Class: AndroidKeyAttestation::Statement

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/android_key_attestation/statement.rb

Constant Summary collapse

EXTENSION_DATA_OID =
"1.3.6.1.4.1.11129.2.1.17"
GOOGLE_ROOT_CERTIFICATES =
begin
  file = File.read(File.join(GEM_ROOT, "android_key_attestation", "google_hardware_attestation_root.pem"))
  [OpenSSL::X509::Certificate.new(file)]
end.freeze

Instance Method Summary collapse

Constructor Details

#initialize(*certificates) ⇒ Statement

Returns a new instance of Statement.



22
23
24
# File 'lib/android_key_attestation/statement.rb', line 22

def initialize(*certificates)
  @certificates = certificates
end

Instance Method Details

#attestation_certificateObject



26
27
28
# File 'lib/android_key_attestation/statement.rb', line 26

def attestation_certificate
  @certificates.first
end

#key_descriptionObject



46
47
48
49
50
51
52
53
54
# File 'lib/android_key_attestation/statement.rb', line 46

def key_description
  @key_description ||= begin
    extension_data = attestation_certificate.extensions.detect { |ext| ext.oid == EXTENSION_DATA_OID }
    raise AndroidKeyAttestation::ExtensionMissingError unless extension_data

    raw_key_description = OpenSSL::ASN1.decode(extension_data).value.last
    KeyDescription.new(OpenSSL::ASN1.decode(raw_key_description.value).value)
  end
end

#verify_certificate_chain(root_certificates: GOOGLE_ROOT_CERTIFICATES, time: Time.now) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/android_key_attestation/statement.rb', line 37

def verify_certificate_chain(root_certificates: GOOGLE_ROOT_CERTIFICATES, time: Time.now)
  store = OpenSSL::X509::Store.new
  root_certificates.each { |cert| store.add_cert(cert) }
  store.time = time

  store.verify(attestation_certificate, @certificates[1..-1]) ||
    raise(CertificateVerificationError, store.error_string)
end

#verify_challenge(challenge) ⇒ Object



30
31
32
33
34
35
# File 'lib/android_key_attestation/statement.rb', line 30

def verify_challenge(challenge)
  attestation_challenge = key_description.attestation_challenge
  attestation_challenge.bytesize == challenge.bytesize &&
    OpenSSL.fixed_length_secure_compare(attestation_challenge, challenge) ||
    raise(ChallengeMismatchError)
end