Search in sources :

Example 1 with BadAttestationStatementException

use of com.webauthn4j.validator.exception.BadAttestationStatementException in project webauthn4j by webauthn4j.

the class FidoMdsMetadataValidator method validate.

@Override
public void validate(RegistrationObject registrationObject) {
    AssertUtil.notNull(registrationObject.getAttestationObject().getAuthenticatorData(), "authenticatorData must not be null");
    AssertUtil.notNull(registrationObject.getAttestationObject().getAuthenticatorData().getAttestedCredentialData(), "attestedCredentialData must not be null");
    AAGUID aaguid = registrationObject.getAttestationObject().getAuthenticatorData().getAttestedCredentialData().getAaguid();
    AttestationStatement attestationStatement = registrationObject.getAttestationObject().getAttestationStatement();
    Set<MetadataItem> metadataItems = metadataItemsResolver.resolve(aaguid);
    List<AuthenticatorAttestationType> authenticatorAttestationTypes = metadataItems.stream().flatMap(item -> item.getMetadataStatement().getAttestationTypes().stream()).collect(Collectors.toList());
    boolean isSurrogate = !authenticatorAttestationTypes.isEmpty() && authenticatorAttestationTypes.stream().allMatch(type -> type.equals(AuthenticatorAttestationType.BASIC_SURROGATE));
    if (isSurrogate && attestationStatement instanceof CertificateBaseAttestationStatement) {
        CertificateBaseAttestationStatement certificateBaseAttestationStatement = (CertificateBaseAttestationStatement) attestationStatement;
        if (certificateBaseAttestationStatement.getX5c() != null) {
            throw new BadAttestationStatementException("Although AAGUID is registered for surrogate attestation in metadata, x5c contains certificates.");
        }
    }
    for (MetadataItem metadataItem : metadataItems) {
        doAdditionalValidationForFidoMdsMetadataItem(metadataItem);
    }
}
Also used : X509Certificate(java.security.cert.X509Certificate) RegistrationObject(com.webauthn4j.validator.RegistrationObject) AttestationStatement(com.webauthn4j.data.attestation.statement.AttestationStatement) BadStatusException(com.webauthn4j.metadata.exception.BadStatusException) AAGUID(com.webauthn4j.data.attestation.authenticator.AAGUID) Set(java.util.Set) CertificateBaseAttestationStatement(com.webauthn4j.data.attestation.statement.CertificateBaseAttestationStatement) Collectors(java.util.stream.Collectors) AuthenticatorAttestationType(com.webauthn4j.data.AuthenticatorAttestationType) List(java.util.List) MetadataItem(com.webauthn4j.metadata.legacy.data.MetadataItem) BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException) ObjectConverter(com.webauthn4j.converter.util.ObjectConverter) CustomRegistrationValidator(com.webauthn4j.validator.CustomRegistrationValidator) AssertUtil(com.webauthn4j.util.AssertUtil) CertificateBaseAttestationStatement(com.webauthn4j.data.attestation.statement.CertificateBaseAttestationStatement) BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException) AAGUID(com.webauthn4j.data.attestation.authenticator.AAGUID) AttestationStatement(com.webauthn4j.data.attestation.statement.AttestationStatement) CertificateBaseAttestationStatement(com.webauthn4j.data.attestation.statement.CertificateBaseAttestationStatement) MetadataItem(com.webauthn4j.metadata.legacy.data.MetadataItem) AuthenticatorAttestationType(com.webauthn4j.data.AuthenticatorAttestationType)

Example 2 with BadAttestationStatementException

use of com.webauthn4j.validator.exception.BadAttestationStatementException in project webauthn4j by webauthn4j.

the class AppleAppAttestAttestationStatementValidator method validatePublicKey.

private void validatePublicKey(CoreRegistrationObject registrationObject) {
    byte[] publicKey = ECUtil.createUncompressedPublicKey((ECPublicKey) getAttestationStatement(registrationObject).getX5c().getEndEntityAttestationCertificate().getCertificate().getPublicKey());
    DCRegistrationObject dcRegistrationObject = (DCRegistrationObject) registrationObject;
    byte[] keyId = dcRegistrationObject.getKeyId();
    // there is no need to prevent timing attack and it is OK to use `Arrays.equals` instead of `MessageDigest.isEqual` here.
    if (!Arrays.equals(MessageDigestUtil.createSHA256().digest(publicKey), keyId)) {
        throw new BadAttestationStatementException("key identifier doesn't match SHA-256 of the publickey");
    }
}
Also used : DCRegistrationObject(com.webauthn4j.appattest.validator.DCRegistrationObject) BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException)

Example 3 with BadAttestationStatementException

use of com.webauthn4j.validator.exception.BadAttestationStatementException in project webauthn4j by webauthn4j.

the class AppleAppAttestAttestationStatementValidator method validateNonce.

private void validateNonce(CoreRegistrationObject registrationObject) {
    AppleAppAttestAttestationStatement attestationStatement = getAttestationStatement(registrationObject);
    X509Certificate attestationCertificate = attestationStatement.getX5c().getEndEntityAttestationCertificate().getCertificate();
    byte[] actualNonce = extractNonce(attestationCertificate);
    byte[] clientDataHash = registrationObject.getClientDataHash();
    byte[] authenticatorData = registrationObject.getAuthenticatorDataBytes();
    byte[] composite = ByteBuffer.allocate(authenticatorData.length + clientDataHash.length).put(authenticatorData).put(clientDataHash).array();
    byte[] expectedNonce = MessageDigestUtil.createSHA256().digest(composite);
    // As nonce is known data to client side(potential attacker), there is no risk of timing attack and it is OK to use `Arrays.equals` instead of `MessageDigest.isEqual`
    if (!Arrays.equals(actualNonce, expectedNonce)) {
        throw new BadAttestationStatementException("App Attest nonce doesn't match.");
    }
}
Also used : BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException) X509Certificate(java.security.cert.X509Certificate) AppleAppAttestAttestationStatement(com.webauthn4j.appattest.data.attestation.statement.AppleAppAttestAttestationStatement)

Example 4 with BadAttestationStatementException

use of com.webauthn4j.validator.exception.BadAttestationStatementException in project webauthn4j by webauthn4j.

the class TPMAttestationStatementValidator method validatePublicKeyEquality.

private void validatePublicKeyEquality(TPMTPublic pubArea, AuthenticatorData<RegistrationExtensionAuthenticatorOutput> authenticatorData) {
    // noinspection ConstantConditions as null check is already done in caller
    PublicKey publicKeyInAuthData = authenticatorData.getAttestedCredentialData().getCOSEKey().getPublicKey();
    TPMUPublicId publicKeyInPubArea = pubArea.getUnique();
    if (pubArea.getType() == TPMIAlgPublic.TPM_ALG_RSA && publicKeyInPubArea instanceof RSAUnique) {
        RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKeyInAuthData;
        TPMSRSAParms parms = (TPMSRSAParms) pubArea.getParameters();
        RSAUnique rsaUnique = (RSAUnique) publicKeyInPubArea;
        long exponent = UnsignedNumberUtil.getUnsignedInt(parms.getExponent());
        if (exponent == 0) {
            // 2^16 + 1
            exponent = 65537;
        }
        // noinspection ConstantConditions as null check is already done in caller
        if (rsaPublicKey.getModulus().equals(new BigInteger(1, rsaUnique.getN())) && rsaPublicKey.getPublicExponent().equals(BigInteger.valueOf(exponent))) {
            return;
        }
    } else if (pubArea.getType() == TPMIAlgPublic.TPM_ALG_ECDSA && publicKeyInPubArea instanceof ECCUnique) {
        ECPublicKey ecPublicKey = (ECPublicKey) publicKeyInAuthData;
        TPMSECCParms parms = (TPMSECCParms) pubArea.getParameters();
        EllipticCurve curveInParms = parms.getCurveId().getEllipticCurve();
        ECCUnique eccUnique = (ECCUnique) publicKeyInPubArea;
        // noinspection ConstantConditions as null check is already done in caller
        if (ecPublicKey.getParams().getCurve().equals(curveInParms) && ecPublicKey.getW().getAffineX().equals(new BigInteger(1, eccUnique.getX())) && ecPublicKey.getW().getAffineY().equals(new BigInteger(1, eccUnique.getY()))) {
            return;
        }
    }
    throw new BadAttestationStatementException("publicKey in authData and publicKey in unique pubArea doesn't match");
}
Also used : RSAPublicKey(java.security.interfaces.RSAPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException) RSAPublicKey(java.security.interfaces.RSAPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) EllipticCurve(java.security.spec.EllipticCurve) BigInteger(java.math.BigInteger)

Example 5 with BadAttestationStatementException

use of com.webauthn4j.validator.exception.BadAttestationStatementException in project webauthn4j by webauthn4j.

the class TPMAttestationStatementValidator method validateSubjectAlternativeName.

private void validateSubjectAlternativeName(X509Certificate certificate) throws CertificateParsingException {
    try {
        for (List<?> entry : certificate.getSubjectAlternativeNames()) {
            if (entry.get(0).equals(4)) {
                TPMDeviceProperty tpmDeviceProperty = parseTPMDeviceProperty((String) entry.get(1));
                tpmDevicePropertyValidator.validate(tpmDeviceProperty);
                return;
            }
        }
    } catch (IOException | RuntimeException e) {
        throw new BadAttestationStatementException("The Subject Alternative Name extension of attestation certificate does not contain a TPM device property", e);
    }
    throw new BadAttestationStatementException("The Subject Alternative Name extension of attestation certificate does not contain a TPM device property");
}
Also used : BadAttestationStatementException(com.webauthn4j.validator.exception.BadAttestationStatementException) IOException(java.io.IOException)

Aggregations

BadAttestationStatementException (com.webauthn4j.validator.exception.BadAttestationStatementException)17 X509Certificate (java.security.cert.X509Certificate)4 NonNull (org.checkerframework.checker.nullness.qual.NonNull)4 AAGUID (com.webauthn4j.data.attestation.authenticator.AAGUID)3 IOException (java.io.IOException)3 RegistrationExtensionAuthenticatorOutput (com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput)2 ECPublicKey (java.security.interfaces.ECPublicKey)2 Asn1Container (org.apache.kerby.asn1.parse.Asn1Container)2 Asn1OctetString (org.apache.kerby.asn1.type.Asn1OctetString)2 Asn1Utf8String (org.apache.kerby.asn1.type.Asn1Utf8String)2 DCAttestationData (com.webauthn4j.appattest.data.DCAttestationData)1 AppleAppAttestAttestationStatement (com.webauthn4j.appattest.data.attestation.statement.AppleAppAttestAttestationStatement)1 DCRegistrationObject (com.webauthn4j.appattest.validator.DCRegistrationObject)1 ObjectConverter (com.webauthn4j.converter.util.ObjectConverter)1 AuthenticatorAttestationType (com.webauthn4j.data.AuthenticatorAttestationType)1 SignatureAlgorithm (com.webauthn4j.data.SignatureAlgorithm)1 AndroidKeyAttestationStatement (com.webauthn4j.data.attestation.statement.AndroidKeyAttestationStatement)1 AndroidSafetyNetAttestationStatement (com.webauthn4j.data.attestation.statement.AndroidSafetyNetAttestationStatement)1 AppleAnonymousAttestationStatement (com.webauthn4j.data.attestation.statement.AppleAnonymousAttestationStatement)1 AttestationCertificate (com.webauthn4j.data.attestation.statement.AttestationCertificate)1