class MobileId::Cert

Attributes

cert[RW]
subject[RW]

Public Class Methods

build_store(paths) click to toggle source
# File lib/mobile_id/cert.rb, line 36
def build_store(paths)
  store = OpenSSL::X509::Store.new
  paths.each { |path| cert = OpenSSL::X509::Certificate.new(File.read(path)); store.add_cert(cert) }
  store
end
live_store() click to toggle source
# File lib/mobile_id/cert.rb, line 10
def live_store
  @live_store ||= 
    build_store([
      File.join(root_path, 'EE_Certification_Centre_Root_CA.pem.crt'),
      File.join(root_path, 'EE-GovCA2018.pem.crt'),
      File.join(root_path, 'EID-SK_2011.pem.crt'),
      File.join(root_path, 'EID-SK_2016.pem.crt'),
      File.join(root_path, 'esteid2018.pem.crt'),
      File.join(root_path, 'ESTEID-SK_2011.pem.crt'),
      File.join(root_path, 'ESTEID-SK_2015.pem.crt'),
      File.join(root_path, 'KLASS3-SK_2010_EECCRCA.pem.crt'),
      File.join(root_path, 'KLASS3-SK_2010_EECCRCA_SHA384.pem.crt'),
      File.join(root_path, 'KLASS3-SK_2016_EECCRCA_SHA384.pem.crt'),
      File.join(root_path, 'KLASS3-SK.pem.crt'),
      File.join(root_path, 'NQ-SK_2016.pem.crt')
    ])
end
new(base64_cert, live:) click to toggle source
# File lib/mobile_id/cert.rb, line 45
def initialize(base64_cert, live:)
  self.cert = OpenSSL::X509::Certificate.new(Base64.decode64(base64_cert))
  verify!(self.cert, live: live)
  build_cert_subject
end
root_path() click to toggle source
# File lib/mobile_id/cert.rb, line 6
def root_path
  @root_path ||= File.expand_path('certs', __dir__)
end
test_store() click to toggle source
# File lib/mobile_id/cert.rb, line 28
def test_store
  @test_store ||= 
    build_store([
      File.join(root_path, 'TEST_of_EE_Certification_Centre_Root_CA.pem.crt'),
      File.join(root_path, 'TEST_of_ESTEID-SK_2015.pem.crt')
    ])
end

Public Instance Methods

common_name() click to toggle source
# File lib/mobile_id/cert.rb, line 101
def common_name
  subject["CN"]
end
country() click to toggle source
# File lib/mobile_id/cert.rb, line 97
def country
  subject["C"].tr(",", " ")
end
cvc_to_der(cvc) click to toggle source
# File lib/mobile_id/cert.rb, line 79
def cvc_to_der(cvc)
  sign_hex = cvc.unpack('H*').first
  half = sign_hex.size / 2
  i = [OpenSSL::ASN1::Integer.new(sign_hex[0...half].to_i(16)), OpenSSL::ASN1::Integer.new(sign_hex[half..sign_hex.size].to_i(16))]
  seq = OpenSSL::ASN1::Sequence.new(i)
  seq.to_der
end
first_name()
Alias for: given_name
given_name() click to toggle source
# File lib/mobile_id/cert.rb, line 87
def given_name
  subject["GN"].tr(",", " ")
end
Also aliased as: first_name
last_name()
Alias for: surname
organizational_unit() click to toggle source
# File lib/mobile_id/cert.rb, line 105
def organizational_unit
  subject["OU"]
end
personal_code()
Alias for: serial_number
serial_number() click to toggle source
# File lib/mobile_id/cert.rb, line 109
def serial_number
  subject["serialNumber"]
end
Also aliased as: personal_code
surname() click to toggle source
# File lib/mobile_id/cert.rb, line 92
def surname
  subject["SN"].tr(",", " ")
end
Also aliased as: last_name
verify!(cert, live:) click to toggle source
# File lib/mobile_id/cert.rb, line 51
def verify!(cert, live:)
  if live == true
    raise Error, 'User certificate is not valid' unless self.class.live_store.verify(cert)
  else
    raise Error, 'User certificate is not valid' unless self.class.test_store.verify(cert) || self.class.live_store.verify(cert)
  end

  raise Error, 'User certificate is not valid [check_key]' unless cert.public_key.check_key
  raise Error, 'User certificate is expired' unless (cert.not_before..cert.not_after) === Time.now

  true
end
verify_signature!(signature_base64, doc) click to toggle source
# File lib/mobile_id/cert.rb, line 64
def verify_signature!(signature_base64, doc)
  signature = Base64.decode64(signature_base64)
  digest = OpenSSL::Digest::SHA256.new(doc)

  valid =
    begin
      cert.public_key.verify(digest, signature, doc)
    rescue OpenSSL::PKey::PKeyError
      der_signature = cvc_to_der(signature) # Probably signature is CVC encoded
      cert.public_key.verify(digest, der_signature, doc)
    end

  raise Error, 'We could not verify user signature' unless valid
end

Private Instance Methods

build_cert_subject() click to toggle source
# File lib/mobile_id/cert.rb, line 116
def build_cert_subject
  self.subject = cert.subject.to_utf8.split(/(?<!\\)\,+/).each_with_object({}) do |c, result|
    next unless c.include?("=")

    key, val = c.split("=")
    result[key] = val
  end
end