Class: IosAppAttest::Validators::CertificateValidator

Inherits:
BaseValidator
  • Object
show all
Defined in:
lib/ios_app_attest/validators/certificate_validator.rb

Overview

Validates certificate chain and related aspects

This validator is responsible for verifying the certificate chain, validating sequence structures, and ensuring the App Attest OID is present in the certificate.

Examples:

validator = IosAppAttest::Validators::CertificateValidator.new(config)
cred_cert = validator.validate(attestation)

Instance Attribute Summary

Attributes inherited from BaseValidator

#config, #logger

Instance Method Summary collapse

Methods inherited from BaseValidator

#initialize

Constructor Details

This class inherits a constructor from IosAppAttest::Validators::BaseValidator

Instance Method Details

#extract_public_key(cred_cert) ⇒ String

Extract the public key from the certificate

This method extracts the public key from the credential certificate in DER (Distinguished Encoding Rules) format for further validation.

Parameters:

  • cred_cert (OpenSSL::X509::Certificate) —

    The credential certificate

Returns:

  • (String) —

    The public key in DER format



64
65
66
# File 'lib/ios_app_attest/validators/certificate_validator.rb', line 64

def extract_public_key(cred_cert)
  cred_cert.public_key.to_der
end

#validate(attestation) ⇒ OpenSSL::X509::Certificate

Validate the certificate chain

This method performs the following validations:

  1. Extracts certificates from the attestation statement
  2. Verifies the certificate chain against the Apple root CA
  3. Validates that the certificate contains the App Attest OID

Parameters:

  • attestation (Hash) —

    The decoded attestation object containing x5c certificates

Returns:

  • (OpenSSL::X509::Certificate) —

    The credential certificate if validation succeeds

Raises:



25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/ios_app_attest/validators/certificate_validator.rb', line 25

def validate(attestation)
  att_stmt = attestation['attStmt']
  certificates = att_stmt['x5c'].map { |c| OpenSSL::X509::Certificate.new(c) }
  cred_cert, *chain = certificates
  
  context = OpenSSL::X509::StoreContext.new(certificates_store, cred_cert, chain)
  unless context.verify
    raise IosAppAttest::CertificateError, 
          "Certificate chain verification failed: #{context.error_string}"
  end
  
  verify_app_attest_oid(cred_cert)
  cred_cert
end

#validate_sequence(cred_cert) ⇒ Object

Validate the sequence structure in the certificate

This method validates that the certificate extension with the App Attest OID contains a properly structured ASN.1 sequence. This is required for the challenge validation process.

Parameters:

  • cred_cert (OpenSSL::X509::Certificate) —

    The credential certificate to validate

Raises:



48
49
50
51
52
53
54
55
# File 'lib/ios_app_attest/validators/certificate_validator.rb', line 48

def validate_sequence(cred_cert)
  extension = cred_cert.extensions.find { |e| e.oid == app_attest_oid }
  sequence = OpenSSL::ASN1.decode(OpenSSL::ASN1.decode(extension.to_der).value[1].value)
  
  unless sequence.tag == OpenSSL::ASN1::SEQUENCE && sequence.value.size == 1
    raise IosAppAttest::CertificateError, 'Failed sequence structure validation'
  end
end