Search in sources :

Example 1 with CoseException

use of COSE.CoseException in project java-webauthn-server by Yubico.

the class PackedAttestationStatementVerifier method verifySelfAttestationSignature.

private boolean verifySelfAttestationSignature(AttestationObject attestationObject, ByteArray clientDataJsonHash) {
    final PublicKey pubkey;
    try {
        pubkey = WebAuthnCodecs.importCosePublicKey(attestationObject.getAuthenticatorData().getAttestedCredentialData().get().getCredentialPublicKey());
    } catch (IOException | CoseException | InvalidKeySpecException e) {
        throw ExceptionUtil.wrapAndLog(log, String.format("Failed to parse public key from attestation data %s", attestationObject.getAuthenticatorData().getAttestedCredentialData()), e);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
    final Long keyAlgId = CBORObject.DecodeFromBytes(attestationObject.getAuthenticatorData().getAttestedCredentialData().get().getCredentialPublicKey().getBytes()).get(CBORObject.FromObject(3)).AsInt64();
    final COSEAlgorithmIdentifier keyAlg = COSEAlgorithmIdentifier.fromId(keyAlgId).orElseThrow(() -> new IllegalArgumentException("Unsupported COSE algorithm identifier: " + keyAlgId));
    final Long sigAlgId = attestationObject.getAttestationStatement().get("alg").asLong();
    final COSEAlgorithmIdentifier sigAlg = COSEAlgorithmIdentifier.fromId(sigAlgId).orElseThrow(() -> new IllegalArgumentException("Unsupported COSE algorithm identifier: " + sigAlgId));
    if (!Objects.equals(keyAlg, sigAlg)) {
        throw new IllegalArgumentException(String.format("Key algorithm and signature algorithm must be equal, was: Key: %s, Sig: %s", keyAlg, sigAlg));
    }
    ByteArray signedData = attestationObject.getAuthenticatorData().getBytes().concat(clientDataJsonHash);
    ByteArray signature;
    try {
        signature = new ByteArray(attestationObject.getAttestationStatement().get("sig").binaryValue());
    } catch (IOException e) {
        throw ExceptionUtil.wrapAndLog(log, ".binaryValue() of \"sig\" failed", e);
    }
    return Crypto.verifySignature(pubkey, signedData, signature, keyAlg);
}
Also used : PublicKey(java.security.PublicKey) COSEAlgorithmIdentifier(com.yubico.webauthn.data.COSEAlgorithmIdentifier) CoseException(COSE.CoseException) ByteArray(com.yubico.webauthn.data.ByteArray) IOException(java.io.IOException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException)

Example 2 with CoseException

use of COSE.CoseException in project java-webauthn-server by Yubico.

the class FidoU2fAttestationStatementVerifier method verifyAttestationSignature.

@Override
public boolean verifyAttestationSignature(AttestationObject attestationObject, ByteArray clientDataJsonHash) {
    final X509Certificate attestationCertificate;
    try {
        attestationCertificate = getAttestationCertificate(attestationObject);
    } catch (CertificateException e) {
        throw new IllegalArgumentException(String.format("Failed to parse X.509 certificate from attestation object: %s", attestationObject));
    }
    if (!("EC".equals(attestationCertificate.getPublicKey().getAlgorithm()) && isP256(((ECPublicKey) attestationCertificate.getPublicKey()).getParams()))) {
        throw new IllegalArgumentException("Attestation certificate for fido-u2f must have an ECDSA P-256 public key.");
    }
    final Optional<AttestedCredentialData> attData = attestationObject.getAuthenticatorData().getAttestedCredentialData();
    return attData.map(attestedCredentialData -> {
        JsonNode signature = attestationObject.getAttestationStatement().get("sig");
        if (signature == null) {
            throw new IllegalArgumentException("fido-u2f attestation statement must have a \"sig\" property set to a DER encoded signature.");
        }
        if (signature.isBinary()) {
            final ByteArray userPublicKey;
            try {
                userPublicKey = getRawUserPublicKey(attestationObject);
            } catch (IOException | CoseException e) {
                RuntimeException err = new RuntimeException(String.format("Failed to parse public key from attestation data %s", attestedCredentialData), e);
                log.error(err.getMessage(), err);
                throw err;
            }
            ByteArray keyHandle = attestedCredentialData.getCredentialId();
            U2fRawRegisterResponse u2fRegisterResponse;
            try {
                u2fRegisterResponse = new U2fRawRegisterResponse(userPublicKey, keyHandle, attestationCertificate, new ByteArray(signature.binaryValue()));
            } catch (IOException e) {
                RuntimeException err = new RuntimeException("signature.isBinary() was true but signature.binaryValue() failed", e);
                log.error(err.getMessage(), err);
                throw err;
            }
            return u2fRegisterResponse.verifySignature(attestationObject.getAuthenticatorData().getRpIdHash(), clientDataJsonHash);
        } else {
            throw new IllegalArgumentException("\"sig\" property of fido-u2f attestation statement must be a CBOR byte array value.");
        }
    }).orElseThrow(() -> new IllegalArgumentException("Attestation object for credential creation must have attestation data."));
}
Also used : AttestedCredentialData(com.yubico.webauthn.data.AttestedCredentialData) X509Certificate(java.security.cert.X509Certificate) Crypto.isP256(com.yubico.webauthn.Crypto.isP256) AttestationObject(com.yubico.webauthn.data.AttestationObject) AttestedCredentialData(com.yubico.webauthn.data.AttestedCredentialData) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) CoseException(COSE.CoseException) IOException(java.io.IOException) PublicKey(java.security.PublicKey) CertificateException(java.security.cert.CertificateException) Slf4j(lombok.extern.slf4j.Slf4j) ExceptionUtil(com.yubico.internal.util.ExceptionUtil) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Optional(java.util.Optional) JsonNode(com.fasterxml.jackson.databind.JsonNode) ByteArray(com.yubico.webauthn.data.ByteArray) AttestationType(com.yubico.webauthn.data.AttestationType) ECPublicKey(java.security.interfaces.ECPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) ByteArray(com.yubico.webauthn.data.ByteArray) CertificateException(java.security.cert.CertificateException) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate)

Aggregations

CoseException (COSE.CoseException)2 ByteArray (com.yubico.webauthn.data.ByteArray)2 IOException (java.io.IOException)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 PublicKey (java.security.PublicKey)2 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 ExceptionUtil (com.yubico.internal.util.ExceptionUtil)1 Crypto.isP256 (com.yubico.webauthn.Crypto.isP256)1 AttestationObject (com.yubico.webauthn.data.AttestationObject)1 AttestationType (com.yubico.webauthn.data.AttestationType)1 AttestedCredentialData (com.yubico.webauthn.data.AttestedCredentialData)1 COSEAlgorithmIdentifier (com.yubico.webauthn.data.COSEAlgorithmIdentifier)1 CertificateException (java.security.cert.CertificateException)1 X509Certificate (java.security.cert.X509Certificate)1 ECPublicKey (java.security.interfaces.ECPublicKey)1 Optional (java.util.Optional)1 Slf4j (lombok.extern.slf4j.Slf4j)1