Search in sources :

Example 1 with AndroidKeyAttestationStatement

use of com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement in project webauthn4j by webauthn4j.

the class AndroidKeyAttestationStatementValidatorTest method validateAttestationStatementNotNull_test.

@Test
void validateAttestationStatementNotNull_test() {
    AndroidKeyAttestationStatement attestationStatement = new AndroidKeyAttestationStatement(COSEAlgorithmIdentifier.ES256, new byte[32], new AttestationCertificatePath());
    target.validateAttestationStatementNotNull(attestationStatement);
}
Also used : AndroidKeyAttestationStatement(com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement) AttestationCertificatePath(com.webauthn4j.data.attestation.statement.AttestationCertificatePath) Test(org.junit.jupiter.api.Test)

Example 2 with AndroidKeyAttestationStatement

use of com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement in project webauthn4j by webauthn4j.

the class AndroidKeyAttestationStatementValidatorTest method validate_empty_x5c_test2.

@Test
void validate_empty_x5c_test2() {
    RegistrationObject registrationObject = mock(RegistrationObject.class, RETURNS_DEEP_STUBS);
    when(registrationObject.getAttestationObject().getAttestationStatement()).thenReturn(new AndroidKeyAttestationStatement(COSEAlgorithmIdentifier.ES256, new byte[32], new AttestationCertificatePath()));
    assertThrows(BadAttestationStatementException.class, () -> target.validate(registrationObject));
}
Also used : AndroidKeyAttestationStatement(com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement) AttestationCertificatePath(com.webauthn4j.data.attestation.statement.AttestationCertificatePath) RegistrationObject(com.webauthn4j.validator.RegistrationObject) Test(org.junit.jupiter.api.Test)

Example 3 with AndroidKeyAttestationStatement

use of com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement in project webauthn4j by webauthn4j.

the class AndroidKeyAttestationStatementValidator method validate.

@Override
@NonNull
public AttestationType validate(@NonNull CoreRegistrationObject registrationObject) {
    AssertUtil.notNull(registrationObject, "registrationObject must not be null");
    if (!supports(registrationObject)) {
        throw new IllegalArgumentException(String.format("Specified format '%s' is not supported by %s.", registrationObject.getAttestationObject().getFormat(), this.getClass().getName()));
    }
    AndroidKeyAttestationStatement attestationStatement = (AndroidKeyAttestationStatement) registrationObject.getAttestationObject().getAttestationStatement();
    validateAttestationStatementNotNull(attestationStatement);
    if (attestationStatement.getX5c().isEmpty()) {
        throw new BadAttestationStatementException("No attestation certificate is found in android key attestation statement.");
    }
    // / Verify that attStmt is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the contained fields.
    // / Verify that sig is a valid signature over the concatenation of authenticatorData and clientDataHash using the public key in the first certificate in x5c with the algorithm specified in alg.
    validateSignature(registrationObject);
    // / Verify that the public key in the first certificate in x5c matches the credentialPublicKey in the attestedCredentialData in authenticatorData.
    PublicKey publicKeyInEndEntityCert = attestationStatement.getX5c().getEndEntityAttestationCertificate().getCertificate().getPublicKey();
    AuthenticatorData<RegistrationExtensionAuthenticatorOutput> authenticatorData = registrationObject.getAttestationObject().getAuthenticatorData();
    // noinspection ConstantConditions as null check is already done in caller
    PublicKey publicKeyInCredentialData = authenticatorData.getAttestedCredentialData().getCOSEKey().getPublicKey();
    if (!publicKeyInEndEntityCert.equals(publicKeyInCredentialData)) {
        throw new PublicKeyMismatchException("The public key in the first certificate in x5c doesn't matches the credentialPublicKey in the attestedCredentialData in authenticatorData.");
    }
    byte[] clientDataHash = registrationObject.getClientDataHash();
    keyDescriptionValidator.validate(attestationStatement.getX5c().getEndEntityAttestationCertificate().getCertificate(), clientDataHash, teeEnforcedOnly);
    return AttestationType.BASIC;
}
Also used : AndroidKeyAttestationStatement(com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement) BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException) PublicKey(java.security.PublicKey) RegistrationExtensionAuthenticatorOutput(com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput) PublicKeyMismatchException(com.webauthn4j.validator.exception.PublicKeyMismatchException) NonNull(org.checkerframework.checker.nullness.qual.NonNull)

Example 4 with AndroidKeyAttestationStatement

use of com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement in project webauthn4j by webauthn4j.

the class AndroidKeyAttestationStatementValidator method validateSignature.

private void validateSignature(@NonNull CoreRegistrationObject registrationObject) {
    AndroidKeyAttestationStatement attestationStatement = (AndroidKeyAttestationStatement) registrationObject.getAttestationObject().getAttestationStatement();
    byte[] signedData = getSignedData(registrationObject);
    byte[] signature = attestationStatement.getSig();
    PublicKey publicKey = getPublicKey(attestationStatement);
    try {
        String jcaName;
        jcaName = getJcaName(attestationStatement.getAlg());
        Signature verifier = SignatureUtil.createSignature(jcaName);
        verifier.initVerify(publicKey);
        verifier.update(signedData);
        if (verifier.verify(signature)) {
            return;
        }
        throw new BadSignatureException("`sig` in attestation statement is not valid signature over the concatenation of authenticatorData and clientDataHash.");
    } catch (SignatureException | InvalidKeyException e) {
        throw new BadSignatureException("`sig` in attestation statement is not valid signature over the concatenation of authenticatorData and clientDataHash.", e);
    }
}
Also used : BadSignatureException(com.webauthn4j.validator.exception.BadSignatureException) AndroidKeyAttestationStatement(com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement) PublicKey(java.security.PublicKey) Signature(java.security.Signature) BadSignatureException(com.webauthn4j.validator.exception.BadSignatureException) SignatureException(java.security.SignatureException) InvalidKeyException(java.security.InvalidKeyException)

Example 5 with AndroidKeyAttestationStatement

use of com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement in project webauthn4j by webauthn4j.

the class AndroidKeyAuthenticator method createAttestationStatement.

@Override
public AttestationStatement createAttestationStatement(AttestationStatementRequest attestationStatementRequest, RegistrationEmulationOption registrationEmulationOption) {
    byte[] signature;
    if (registrationEmulationOption.isSignatureOverrideEnabled()) {
        signature = registrationEmulationOption.getSignature();
    } else {
        signature = TestDataUtil.calculateSignature(attestationStatementRequest.getCredentialKeyPair().getPrivate(), attestationStatementRequest.getSignedData());
    }
    AttestationOption attestationOption = registrationEmulationOption.getAttestationOption() == null ? new AndroidKeyAttestationOption() : registrationEmulationOption.getAttestationOption();
    X509Certificate attestationCertificate = getAttestationCertificate(attestationStatementRequest, attestationOption);
    AttestationCertificatePath attestationCertificates = new AttestationCertificatePath(attestationCertificate, this.getCACertificatePath());
    return new AndroidKeyAttestationStatement(COSEAlgorithmIdentifier.ES256, signature, attestationCertificates);
}
Also used : AndroidKeyAttestationStatement(com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement) AttestationCertificatePath(com.webauthn4j.data.attestation.statement.AttestationCertificatePath) X509Certificate(java.security.cert.X509Certificate)

Aggregations

AndroidKeyAttestationStatement (com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement)5 AttestationCertificatePath (com.webauthn4j.data.attestation.statement.AttestationCertificatePath)3 PublicKey (java.security.PublicKey)2 Test (org.junit.jupiter.api.Test)2 RegistrationExtensionAuthenticatorOutput (com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput)1 RegistrationObject (com.webauthn4j.validator.RegistrationObject)1 BadAttestationStatementException (com.webauthn4j.validator.exception.BadAttestationStatementException)1 BadSignatureException (com.webauthn4j.validator.exception.BadSignatureException)1 PublicKeyMismatchException (com.webauthn4j.validator.exception.PublicKeyMismatchException)1 InvalidKeyException (java.security.InvalidKeyException)1 Signature (java.security.Signature)1 SignatureException (java.security.SignatureException)1 X509Certificate (java.security.cert.X509Certificate)1 NonNull (org.checkerframework.checker.nullness.qual.NonNull)1