Search in sources :

Example 21 with ByteArray

use of com.yubico.webauthn.data.ByteArray 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)

Example 22 with ByteArray

use of com.yubico.webauthn.data.ByteArray in project java-webauthn-server by Yubico.

the class U2fVerifier method verify.

public static boolean verify(AppId appId, RegistrationRequest request, U2fRegistrationResponse response) throws CertificateException, IOException, Base64UrlException {
    final ByteArray appIdHash = Crypto.sha256(appId.getId());
    final ByteArray clientDataHash = Crypto.sha256(response.getCredential().getU2fResponse().getClientDataJSON());
    final JsonNode clientData = JacksonCodecs.json().readTree(response.getCredential().getU2fResponse().getClientDataJSON().getBytes());
    final String challengeBase64 = clientData.get("challenge").textValue();
    ExceptionUtil.assure(request.getPublicKeyCredentialCreationOptions().getChallenge().equals(ByteArray.fromBase64Url(challengeBase64)), "Wrong challenge.");
    InputStream attestationCertAndSignatureStream = new ByteArrayInputStream(response.getCredential().getU2fResponse().getAttestationCertAndSignature().getBytes());
    final X509Certificate attestationCert = CertificateParser.parseDer(attestationCertAndSignatureStream);
    byte[] signatureBytes = new byte[attestationCertAndSignatureStream.available()];
    attestationCertAndSignatureStream.read(signatureBytes);
    final ByteArray signature = new ByteArray(signatureBytes);
    return new U2fRawRegisterResponse(response.getCredential().getU2fResponse().getPublicKey(), response.getCredential().getU2fResponse().getKeyHandle(), attestationCert, signature).verifySignature(appIdHash, clientDataHash);
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ByteArray(com.yubico.webauthn.data.ByteArray) JsonNode(com.fasterxml.jackson.databind.JsonNode) X509Certificate(java.security.cert.X509Certificate)

Example 23 with ByteArray

use of com.yubico.webauthn.data.ByteArray in project java-webauthn-server by Yubico.

the class WebAuthnCodecs method importCoseEd25519PublicKey.

private static PublicKey importCoseEd25519PublicKey(CBORObject cose) throws InvalidKeySpecException, NoSuchAlgorithmException {
    final ByteArray rawKey = new ByteArray(cose.get(CBORObject.FromObject(-2)).GetByteString());
    final ByteArray x509Key = new ByteArray(new byte[] { 0x30, (byte) (ED25519_CURVE_OID.size() + 3 + rawKey.size()) }).concat(ED25519_CURVE_OID).concat(new ByteArray(new byte[] { 0x03, (byte) (rawKey.size() + 1), 0 })).concat(rawKey);
    KeyFactory kFact = KeyFactory.getInstance("EdDSA");
    return kFact.generatePublic(new X509EncodedKeySpec(x509Key.getBytes()));
}
Also used : ByteArray(com.yubico.webauthn.data.ByteArray) X509EncodedKeySpec(java.security.spec.X509EncodedKeySpec) KeyFactory(java.security.KeyFactory)

Aggregations

ByteArray (com.yubico.webauthn.data.ByteArray)23 IOException (java.io.IOException)10 JsonNode (com.fasterxml.jackson.databind.JsonNode)7 X509Certificate (java.security.cert.X509Certificate)7 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)6 CertificateException (java.security.cert.CertificateException)6 List (java.util.List)5 Optional (java.util.Optional)5 CertificateParser (com.yubico.internal.util.CertificateParser)4 Base64UrlException (com.yubico.webauthn.data.exception.Base64UrlException)4 Collection (java.util.Collection)4 Collections (java.util.Collections)4 AllArgsConstructor (lombok.AllArgsConstructor)4 NonNull (lombok.NonNull)4 ASN1Primitive (org.bouncycastle.asn1.ASN1Primitive)4 DEROctetString (org.bouncycastle.asn1.DEROctetString)4 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)3 DigestException (java.security.DigestException)3 Slf4j (lombok.extern.slf4j.Slf4j)3 CoseException (COSE.CoseException)2