class WebAuthn::FakeAuthenticator::AuthenticatorData
def attested_credential_data
def attested_credential_data @attested_credential_data ||= if credential @aaguid + [credential[:id].length].pack("n*") + credential[:id] + cose_credential_public_key else "" end end
def attested_credential_data_included_bit
def attested_credential_data_included_bit if attested_credential_data.empty? "0" else "1" end end
def bit(flag)
def bit(flag) if context[flag] "1" else "0" end end
def context
def context { user_present: user_present, user_verified: user_verified, backup_eligibility: backup_eligibility, backup_state: backup_state } end
def cose_credential_public_key
def cose_credential_public_key case credential[:public_key] when OpenSSL::PKey::RSA key = COSE::Key::RSA.from_pkey(credential[:public_key]) key.alg = -257 when OpenSSL::PKey::EC::Point alg = { COSE::Key::Curve.by_name("P-256").id => -7, COSE::Key::Curve.by_name("P-384").id => -35, COSE::Key::Curve.by_name("P-521").id => -36 } key = COSE::Key::EC2.from_pkey(credential[:public_key]) key.alg = alg[key.crv] when OpenSSL::PKey::PKey key = COSE::Key::OKP.from_pkey(credential[:public_key]) key.alg = -8 end key.serialize end
def extension_data
def extension_data if extensions CBOR.encode(extensions) else "" end end
def extension_data_included_bit
def extension_data_included_bit if extension_data.empty? "0" else "1" end end
def flags
def flags [ [ bit(:user_present), reserved_for_future_use_bit, bit(:user_verified), bit(:backup_eligibility), bit(:backup_state), reserved_for_future_use_bit, attested_credential_data_included_bit, extension_data_included_bit ].join ].pack("b*") end
def initialize(
def initialize( rp_id_hash:, credential: { id: SecureRandom.random_bytes(16), public_key: OpenSSL::PKey::EC.generate("prime256v1").public_key }, sign_count: 0, user_present: true, user_verified: !user_present, backup_eligibility: false, backup_state: false, aaguid: AAGUID, extensions: { "fakeExtension" => "fakeExtensionValue" } ) @rp_id_hash = rp_id_hash @credential = credential @sign_count = sign_count @user_present = user_present @user_verified = user_verified @backup_eligibility = backup_eligibility @backup_state = backup_state @aaguid = aaguid @extensions = extensions end
def key_bytes(public_key)
def key_bytes(public_key) public_key.to_bn.to_s(2) end
def reserved_for_future_use_bit
def reserved_for_future_use_bit "0" end
def serialize
def serialize rp_id_hash + flags + serialized_sign_count + attested_credential_data + extension_data end
def serialized_sign_count
def serialized_sign_count [sign_count].pack('L>') end