Search in sources :

Example 1 with Response

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

the class AndroidSafetyNetAttestationStatementValidatorTest method validateNull_with_timestampMs_null_test.

@Test
void validateNull_with_timestampMs_null_test() {
    String nonce = "nonce";
    String apkPackageName = "com.android.keystore.androidkeystoredemo";
    String[] apkCertificateDigestSha256 = new String[] { "bsb4/WQdaaOWYCd/j9OJiQpg7b0iwFgAc/zzA1tCfwE=" };
    String apkDigestSha256 = "dM/LUHSI9SkQhZHHpQWRnzJ3MvvB2ANSauqYAAbS2Jg=";
    boolean ctsProfileMatch = true;
    boolean basicIntegrity = true;
    String advice = null;
    Response response = new Response(nonce, null, apkPackageName, apkCertificateDigestSha256, apkDigestSha256, ctsProfileMatch, basicIntegrity, advice);
    assertThatThrownBy(() -> target.validateResponseNotNull(response)).isInstanceOf(BadAttestationStatementException.class);
}
Also used : Response(com.webauthn4j.data.attestation.statement.Response) Test(org.junit.jupiter.api.Test)

Example 2 with Response

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

the class AndroidSafetyNetAttestationStatementValidatorTest method validateNull_with_apkPackageName_null_test.

@Test
void validateNull_with_apkPackageName_null_test() {
    String nonce = "nonce";
    long timestampMs = Instant.now().toEpochMilli();
    String[] apkCertificateDigestSha256 = new String[] { "bsb4/WQdaaOWYCd/j9OJiQpg7b0iwFgAc/zzA1tCfwE=" };
    String apkDigestSha256 = "dM/LUHSI9SkQhZHHpQWRnzJ3MvvB2ANSauqYAAbS2Jg=";
    boolean ctsProfileMatch = true;
    boolean basicIntegrity = true;
    String advice = null;
    Response response = new Response(nonce, timestampMs, null, apkCertificateDigestSha256, apkDigestSha256, ctsProfileMatch, basicIntegrity, advice);
    assertThatThrownBy(() -> target.validateResponseNotNull(response)).isInstanceOf(BadAttestationStatementException.class);
}
Also used : Response(com.webauthn4j.data.attestation.statement.Response) Test(org.junit.jupiter.api.Test)

Example 3 with Response

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

the class AndroidSafetyNetAttestationStatementValidatorTest method validateNull_with_apkDigestSha256_null_test.

@Test
void validateNull_with_apkDigestSha256_null_test() {
    String nonce = "nonce";
    long timestampMs = Instant.now().toEpochMilli();
    String apkPackageName = "com.android.keystore.androidkeystoredemo";
    String[] apkCertificateDigestSha256 = new String[] { "bsb4/WQdaaOWYCd/j9OJiQpg7b0iwFgAc/zzA1tCfwE=" };
    boolean ctsProfileMatch = true;
    boolean basicIntegrity = true;
    String advice = null;
    Response response = new Response(nonce, timestampMs, apkPackageName, apkCertificateDigestSha256, null, ctsProfileMatch, basicIntegrity, advice);
    assertThatThrownBy(() -> target.validateResponseNotNull(response)).isInstanceOf(BadAttestationStatementException.class);
}
Also used : Response(com.webauthn4j.data.attestation.statement.Response) Test(org.junit.jupiter.api.Test)

Example 4 with Response

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

the class AndroidSafetyNetAttestationStatementValidatorTest method validateNull_with_advice_null_test.

@Test
void validateNull_with_advice_null_test() {
    String nonce = "nonce";
    long timestampMs = Instant.now().toEpochMilli();
    String apkPackageName = "com.android.keystore.androidkeystoredemo";
    String[] apkCertificateDigestSha256 = new String[] { "bsb4/WQdaaOWYCd/j9OJiQpg7b0iwFgAc/zzA1tCfwE=" };
    String apkDigestSha256 = "dM/LUHSI9SkQhZHHpQWRnzJ3MvvB2ANSauqYAAbS2Jg=";
    boolean ctsProfileMatch = true;
    boolean basicIntegrity = true;
    Response response = new Response(nonce, timestampMs, apkPackageName, apkCertificateDigestSha256, apkDigestSha256, ctsProfileMatch, basicIntegrity, null);
    assertThatCode(() -> target.validateResponseNotNull(response)).doesNotThrowAnyException();
}
Also used : Response(com.webauthn4j.data.attestation.statement.Response) Test(org.junit.jupiter.api.Test)

Example 5 with Response

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

the class AndroidSafetyNetAttestationStatementValidator method validate.

@SuppressWarnings("ConstantConditions")
@Override
@NonNull
public AttestationType validate(@NonNull CoreRegistrationObject registrationObject) {
    AssertUtil.notNull(registrationObject, "registrationObject must not be null");
    if (!supports(registrationObject)) {
        throw new IllegalArgumentException("Specified format is not supported by " + this.getClass().getName());
    }
    AndroidSafetyNetAttestationStatement attestationStatement = (AndroidSafetyNetAttestationStatement) registrationObject.getAttestationObject().getAttestationStatement();
    validateAttestationStatementNotNull(attestationStatement);
    if (attestationStatement.getX5c().isEmpty()) {
        throw new BadAttestationStatementException("No attestation certificate is found in android safetynet attestation statement.");
    }
    // / Given the verification procedure inputs attStmt, authenticatorData and clientDataHash,
    // the verification procedure is as follows:
    // / 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 response is a valid SafetyNet response of version ver.
    versionValidator.validate(attestationStatement.getVer());
    // / Verify that the nonce in the response is identical to the Base64url encoding of the SHA-256 hash of the concatenation of authenticatorData and clientDataHash.
    Response response = attestationStatement.getResponse().getPayload();
    String nonce = response.getNonce();
    byte[] authenticatorData = registrationObject.getAuthenticatorDataBytes();
    validateNonce(nonce, authenticatorData, registrationObject.getClientDataHash());
    // / Let attestationCert be the attestation certificate.
    // / Verify that attestationCert is issued to the hostname "attest.android.com" (see SafetyNet online documentation).
    AttestationCertificate attestationCertificate = attestationStatement.getX5c().getEndEntityAttestationCertificate();
    if (!Objects.equals(attestationCertificate.getSubjectCommonName(), "attest.android.com")) {
        throw new BadAttestationStatementException("The attestation certificate is not issued to 'attest.android.com'.");
    }
    // / Verify that the ctsProfileMatch attribute in the payload of response is true.
    if (!Objects.equals(response.getCtsProfileMatch(), true)) {
        throw new BadAttestationStatementException("The profile of the device doesn't match the profile of a device that has passed Android Compatibility Test Suite.");
    }
    if (response.getTimestampMs() == null) {
        throw new BadAttestationStatementException("timestampMs is null.");
    }
    // Verify the timestampMs doesn't violate backwardThreshold
    if (Instant.ofEpochMilli(response.getTimestampMs()).isBefore(registrationObject.getTimestamp().minus(Duration.ofSeconds(backwardThreshold)))) {
        throw new BadAttestationStatementException("timestampMs violates backwardThreshold.");
    }
    // Verify the timestampMs doesn't violate forwardThreshold
    if (Instant.ofEpochMilli(response.getTimestampMs()).isAfter(registrationObject.getTimestamp().plus(Duration.ofSeconds(forwardThreshold)))) {
        throw new BadAttestationStatementException("timestampMs violates forwardThreshold.");
    }
    if (!attestationStatement.getResponse().isValidSignature()) {
        throw new BadAttestationStatementException("Android safetynet response in the attestation statement doesn't have a valid signature.");
    }
    // / If successful, return implementation-specific values representing attestation type Basic and attestation trust path attestationCert.
    return AttestationType.BASIC;
}
Also used : Response(com.webauthn4j.data.attestation.statement.Response) AndroidSafetyNetAttestationStatement(com.webauthn4j.data.attestation.statement.AndroidSafetyNetAttestationStatement) BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException) AttestationCertificate(com.webauthn4j.data.attestation.statement.AttestationCertificate) NonNull(org.checkerframework.checker.nullness.qual.NonNull)

Aggregations

Response (com.webauthn4j.data.attestation.statement.Response)11 Test (org.junit.jupiter.api.Test)9 AndroidSafetyNetAttestationStatement (com.webauthn4j.data.attestation.statement.AndroidSafetyNetAttestationStatement)3 JWSHeader (com.webauthn4j.data.jws.JWSHeader)2 AttestationCertificate (com.webauthn4j.data.attestation.statement.AttestationCertificate)1 JWSFactory (com.webauthn4j.data.jws.JWSFactory)1 BadAttestationStatementException (com.webauthn4j.validator.exception.BadAttestationStatementException)1 CertPath (java.security.cert.CertPath)1 X509Certificate (java.security.cert.X509Certificate)1 ArrayList (java.util.ArrayList)1 NonNull (org.checkerframework.checker.nullness.qual.NonNull)1