Search in sources :

Example 11 with AttestationObject

use of com.webauthn4j.data.attestation.AttestationObject in project webauthn4j by webauthn4j.

the class PackedAttestationStatementValidatorTest method validate_with_ECx5c_test.

@Test
void validate_with_ECx5c_test() {
    byte[] clientData = TestDataUtil.createClientDataJSON(ClientDataType.WEBAUTHN_CREATE);
    byte[] clientDataHash = MessageDigestUtil.createSHA256().digest(clientData);
    AttestationObject attestationObject = TestDataUtil.createAttestationObjectWithBasicPackedECAttestationStatement(clientDataHash);
    validate(clientData, attestationObject);
}
Also used : AttestationObject(com.webauthn4j.data.attestation.AttestationObject) Test(org.junit.jupiter.api.Test)

Example 12 with AttestationObject

use of com.webauthn4j.data.attestation.AttestationObject in project webauthn4j by webauthn4j.

the class PackedAttestationStatementValidatorTest method validate_with_yubikey_fido2_data_test.

@Test
void validate_with_yubikey_fido2_data_test() {
    byte[] attestationObjectBytes = Base64UrlUtil.decode("o2NmbXRmcGFja2VkaGF1dGhEYXRhWJRJlg3liA6MaHQ0Fw9kdmBbj-SuuaKGMseZXPO6gx2XY0UAAAADbUS6m_bsLkm5MAyP6SDLcwAQpt-LSNKw2Ni2n3k1ltLMrqUBAgMmIAEhWCA6CWZ7k4UFMb5kynCGxmRhRVTvppyLpwBKmZ1m96qSjiJYID1KElygcTfTMT5RRoU0oAbBoZEfjHUZytXNemDDkuZpZ2F0dFN0bXSjY2FsZyZjc2lnWEYwRAIgTqgNTx1zMoc4L1Eb_dOgyqtouZBVfrQscgsGrgE4lRICICLuRuy1T05B1kv86XzP0dnN0-DzRcU1t9tS0FTktASBY3g1Y4FZAsEwggK9MIIBpaADAgECAgQq52JjMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBuMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMScwJQYDVQQDDB5ZdWJpY28gVTJGIEVFIFNlcmlhbCA3MTk4MDcwNzUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQqA4ZeYEPZnhH_EKolVFeEvwmvjmseOzIXKSFvVRIajNkQ05ndx2i9_kp7x-PavGLm0kaf9Wdbj_qJDMp0hp4_o2wwajAiBgkrBgEEAYLECgIEFTEuMy42LjEuNC4xLjQxNDgyLjEuMTATBgsrBgEEAYLlHAIBAQQEAwIEMDAhBgsrBgEEAYLlHAEBBAQSBBBtRLqb9uwuSbkwDI_pIMtzMAwGA1UdEwEB_wQCMAAwDQYJKoZIhvcNAQELBQADggEBAHJX0Dzcw-EVaYSQ1vgO-VtTByNz2eZHMmMrEdzcd4rsa9WSbQfhe5xUMHiN4y9OR7RYdv-MVSICm-k4eHlXIzHnJ3AWgopxGznHT9bBJYvR5NnlZtVweQNH2lI1wD8P_kCxQo4FxukXmeR1VHFpAe64i7BXiTWIrYiq0w1xTy8vrDbVTbrXEJxbAnqwyrjPNU7xAIoJCGyghpavDPzbwYOY_N8CMWwmIsle5iK90cAKR4nkocy3SaNUul8nYEIwvv-uBua_AvvAFbzRUd811wqYqOQtykSI_PBxBCGI3-odX3S36niLKvnFFKm6uU_nOJzaGVGQsrEwfb-RGOGpKfg=");
    byte[] clientDataBytes = Base64UrlUtil.decode("ew0KCSJ0eXBlIiA6ICJ3ZWJhdXRobi5jcmVhdGUiLA0KCSJjaGFsbGVuZ2UiIDogIno5LWxDWmFQUlBtMGFReDlLMnE4a3ciLA0KCSJvcmlnaW4iIDogImh0dHA6Ly9sb2NhbGhvc3Q6ODA4MCIsDQoJInRva2VuQmluZGluZyIgOiANCgl7DQoJCSJzdGF0dXMiIDogInN1cHBvcnRlZCINCgl9DQp9");
    AttestationObject attestationObject = new AttestationObjectConverter(objectConverter).convert(attestationObjectBytes);
    validate(clientDataBytes, attestationObject);
}
Also used : AttestationObjectConverter(com.webauthn4j.converter.AttestationObjectConverter) AttestationObject(com.webauthn4j.data.attestation.AttestationObject) Test(org.junit.jupiter.api.Test)

Example 13 with AttestationObject

use of com.webauthn4j.data.attestation.AttestationObject in project webauthn4j by webauthn4j.

the class PackedAttestationStatementValidatorTest method validate_with_invalid_AttestationStatement_test.

@Test
void validate_with_invalid_AttestationStatement_test() {
    byte[] clientData = TestDataUtil.createClientDataJSON(ClientDataType.WEBAUTHN_CREATE);
    AttestationObject attestationObject = TestDataUtil.createAttestationObjectWithFIDOU2FAttestationStatement();
    assertThrows(IllegalArgumentException.class, () -> validate(clientData, attestationObject));
}
Also used : AttestationObject(com.webauthn4j.data.attestation.AttestationObject) Test(org.junit.jupiter.api.Test)

Example 14 with AttestationObject

use of com.webauthn4j.data.attestation.AttestationObject in project webauthn4j by webauthn4j.

the class PackedAttestationStatementValidatorTest method validate_with_RSASelfAttestation_test.

@Test
void validate_with_RSASelfAttestation_test() {
    byte[] clientData = TestDataUtil.createClientDataJSON(ClientDataType.WEBAUTHN_CREATE);
    byte[] clientDataHash = MessageDigestUtil.createSHA256().digest(clientData);
    AttestationObject attestationObject = TestDataUtil.createAttestationObjectWithSelfPackedRSAAttestationStatement(clientDataHash);
    validate(clientData, attestationObject);
}
Also used : AttestationObject(com.webauthn4j.data.attestation.AttestationObject) Test(org.junit.jupiter.api.Test)

Example 15 with AttestationObject

use of com.webauthn4j.data.attestation.AttestationObject in project webauthn4j by webauthn4j.

the class WebAuthnModelAuthenticator method makeCredential.

public MakeCredentialResponse makeCredential(MakeCredentialRequest makeCredentialRequest, RegistrationEmulationOption registrationEmulationOption) {
    PublicKeyCredentialRpEntity rpEntity = makeCredentialRequest.getRpEntity();
    // Check if all the supplied parameters are syntactically well-formed and of the correct length.
    // If not, return an error code equivalent to "UnknownError" and terminate the operation.
    // TODO
    // Check if at least one of the specified combinations of PublicKeyCredentialType and cryptographic parameters
    // in credTypesAndPubKeyAlgs is supported. If not, return an error code equivalent to "NotSupportedError"
    // and terminate the operation.
    Optional<PublicKeyCredentialParameters> optionalPublicKeyCredentialParameters = makeCredentialRequest.getCredTypesAndPublicKeyAlgs().stream().filter(this::isCapableOfHandling).findFirst();
    PublicKeyCredentialParameters publicKeyCredentialParameters;
    if (optionalPublicKeyCredentialParameters.isPresent()) {
        publicKeyCredentialParameters = optionalPublicKeyCredentialParameters.get();
    } else {
        throw new NotSupportedException("Specified PublicKeyCredentialParameters are not supported");
    }
    // For each descriptor of excludeCredentialDescriptorList:
    List<PublicKeyCredentialDescriptor> descriptors = makeCredentialRequest.getExcludeCredentialDescriptorList();
    if (descriptors == null) {
        descriptors = Collections.emptyList();
    }
    for (PublicKeyCredentialDescriptor descriptor : descriptors) {
        PublicKeyCredentialSource publicKeyCredentialSource = lookup(descriptor.getId());
        // The method of obtaining user consent MUST include a test of user presence.
        if (publicKeyCredentialSource != null) {
            if (publicKeyCredentialSource.getRpId().equals(rpEntity.getId()) && publicKeyCredentialSource.getType().equals(descriptor.getType())) {
                boolean userConsent = true;
                // confirms consent to create a new credential
                if (userConsent) {
                    throw new InvalidStateException("");
                } else // does not consent to create a new credential
                {
                    throw new NotAllowedException("User consent is required");
                }
            }
        }
    }
    // return an error code equivalent to "ConstraintError" and terminate the operation.
    if (makeCredentialRequest.isRequireResidentKey() && !isCapableOfStoringClientSideResidentCredential()) {
        throw new ConstraintException("Authenticator isn't capable of storing client-side resident credential");
    }
    // return an error code equivalent to "ConstraintError" and terminate the operation.
    if (makeCredentialRequest.isRequireUserVerification() && !isCapableOfUserVerification()) {
        throw new ConstraintException("Authenticator isn't capable of user verification");
    }
    // Obtain user consent for creating a new credential.
    // The prompt for obtaining this consent is shown by the authenticator if it has its own output capability,
    // or by the user agent otherwise. The prompt SHOULD display rpEntity.id, rpEntity.name, userEntity.name
    // and userEntity.displayName, if possible.
    boolean userVerification = true;
    boolean userConsent = true;
    // "NotAllowedError" and terminate the operation.
    if (makeCredentialRequest.isRequireUserVerification() && !userVerification) {
        throw new NotAllowedException("User is not verified.");
    }
    if (makeCredentialRequest.isRequireUserPresence() && !userConsent) {
        throw new NotAllowedException("User doesn't resolve consent.");
    }
    // Once user consent has been obtained, generate a new credential object:
    byte[] credentialId;
    // Let (publicKey, privateKey) be a new pair of cryptographic keys using the combination of
    // PublicKeyCredentialType and cryptographic parameters represented by the first item in
    // credTypesAndPubKeyAlgs that is supported by this authenticator.
    KeyPair credentialKeyPair;
    COSEKey cosePublicKey;
    COSEKey cosePrivateKey;
    try {
        credentialKeyPair = ECUtil.createKeyPair();
        ECPublicKey publicKey = (ECPublicKey) credentialKeyPair.getPublic();
        ECPrivateKey privateKey = (ECPrivateKey) credentialKeyPair.getPrivate();
        cosePublicKey = TestDataUtil.createEC2COSEPublicKey(publicKey);
        cosePrivateKey = TestDataUtil.createEC2COSEPrivateKey(publicKey, privateKey);
        // Let userHandle be userEntity.id.
        byte[] userHandle = makeCredentialRequest.getUserEntity().getId();
        // Let credentialSource be a new public key credential source with the fields:
        PublicKeyCredentialSource credentialSource = new PublicKeyCredentialSource();
        credentialSource.setType(PublicKeyCredentialType.PUBLIC_KEY);
        credentialSource.setPrivateKey(cosePrivateKey);
        credentialSource.setRpId(rpEntity.getId());
        credentialSource.setUserHandle(userHandle);
        credentialSource.setOtherUI(null);
        // Credential Private Key:
        if (makeCredentialRequest.isRequireResidentKey()) {
            // Let credentialId be a new credential id.
            credentialId = new byte[32];
            secureRandom.nextBytes(credentialId);
            // Set credentialSource.id to credentialId.
            credentialSource.setId(credentialId);
            // Let credentials be this authenticator’s credentials map.
            // noinspection UnnecessaryLocalVariable
            Map<CredentialMapKey, PublicKeyCredentialSource> credentials = credentialMap;
            credentials.put(new CredentialMapKey(rpEntity.getId(), userHandle), credentialSource);
        } else // Otherwise:
        {
            // Let credentialId be the result of serializing and encrypting credentialSource
            // so that only this authenticator can decrypt it.
            byte[] data = cborConverter.writeValueAsBytes(credentialSource);
            credentialId = CipherUtil.encrypt(data, credentialEncryptionKey);
        }
    }// return an error code equivalent to "UnknownError" and terminate the operation.
     catch (RuntimeException e) {
        throw new WebAuthnModelException(e);
    }
    // Let processedExtensions be the result of authenticator extension processing for each
    // supported extension identifier -> authenticator extension input in extensions.
    AuthenticationExtensionsAuthenticatorOutputs<RegistrationExtensionAuthenticatorOutput> registrationExtensionAuthenticatorOutputs = processRegistrationExtensions(makeCredentialRequest);
    // If the authenticator supports:
    // a per-RP ID signature counter
    // allocate the counter, associate it with the RP ID, and initialize the counter value as zero.
    // a global signature counter
    // Use the global signature counter's actual value when generating authenticator data.
    // a per credential signature counter
    // allocate the counter, associate it with the new credential, and initialize the counter value as zero.
    // TODO: counter mode
    countUp();
    // Let attestedCredentialData be the attested credential data byte array including the credentialId and publicKey.
    byte[] rpIdHash = MessageDigestUtil.createSHA256().digest(rpEntity.getId().getBytes(StandardCharsets.UTF_8));
    byte flag = BIT_AT;
    if (userConsent)
        flag |= BIT_UP;
    if (userVerification)
        flag |= BIT_UV;
    if (!registrationExtensionAuthenticatorOutputs.getKeys().isEmpty())
        flag |= BIT_ED;
    AttestedCredentialData attestedCredentialData = new AttestedCredentialData(aaguid, credentialId, cosePublicKey);
    // Let authenticatorData be the byte array specified in §6.1 Authenticator data,
    // including attestedCredentialData as the attestedCredentialData and processedExtensions, if any, as the extensions.
    AuthenticatorData<RegistrationExtensionAuthenticatorOutput> authenticatorData = new AuthenticatorData<>(rpIdHash, flag, counter, attestedCredentialData, registrationExtensionAuthenticatorOutputs);
    byte[] authenticatorDataBytes = authenticatorDataConverter.convert(authenticatorData);
    byte[] signedData = getSignedData(authenticatorDataBytes, makeCredentialRequest.getHash());
    byte[] clientDataHash = makeCredentialRequest.getHash();
    AttestationStatementRequest attestationStatementRequest = new AttestationStatementRequest(signedData, credentialKeyPair, clientDataHash);
    AttestationStatement attestationStatement = createAttestationStatement(attestationStatementRequest, registrationEmulationOption);
    // Return the attestation object for the new credential created by the procedure specified in
    // §6.3.4 Generating an Attestation Object using an authenticator-chosen attestation statement format,
    // authenticatorData, and hash. For more details on attestation, see §6.3 Attestation.
    AttestationObject attestationObject = new AttestationObject(authenticatorData, attestationStatement);
    // On successful completion of this operation, the authenticator returns the attestation object to the client.
    MakeCredentialResponse makeCredentialResponse = new MakeCredentialResponse();
    makeCredentialResponse.setAttestationObject(attestationObject);
    return makeCredentialResponse;
}
Also used : COSEKey(com.webauthn4j.data.attestation.authenticator.COSEKey) RegistrationExtensionAuthenticatorOutput(com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput) AttestedCredentialData(com.webauthn4j.data.attestation.authenticator.AttestedCredentialData) AuthenticatorData(com.webauthn4j.data.attestation.authenticator.AuthenticatorData) AttestationStatement(com.webauthn4j.data.attestation.statement.AttestationStatement) ECPrivateKey(java.security.interfaces.ECPrivateKey) KeyPair(java.security.KeyPair) PublicKeyCredentialRpEntity(com.webauthn4j.data.PublicKeyCredentialRpEntity) PublicKeyCredentialDescriptor(com.webauthn4j.data.PublicKeyCredentialDescriptor) ECPublicKey(java.security.interfaces.ECPublicKey) PublicKeyCredentialParameters(com.webauthn4j.data.PublicKeyCredentialParameters) AttestationObject(com.webauthn4j.data.attestation.AttestationObject)

Aggregations

AttestationObject (com.webauthn4j.data.attestation.AttestationObject)73 Test (org.junit.jupiter.api.Test)48 ServerProperty (com.webauthn4j.server.ServerProperty)26 DefaultChallenge (com.webauthn4j.data.client.challenge.DefaultChallenge)24 CollectedClientData (com.webauthn4j.data.client.CollectedClientData)23 Challenge (com.webauthn4j.data.client.challenge.Challenge)20 RegistrationExtensionClientOutput (com.webauthn4j.data.extension.client.RegistrationExtensionClientOutput)20 Authenticator (com.webauthn4j.authenticator.Authenticator)19 AuthenticationExtensionClientOutput (com.webauthn4j.data.extension.client.AuthenticationExtensionClientOutput)19 AuthenticationExtensionsClientOutputs (com.webauthn4j.data.extension.client.AuthenticationExtensionsClientOutputs)14 FIDOU2FAuthenticator (com.webauthn4j.test.authenticator.u2f.FIDOU2FAuthenticator)9 DCRegistrationObject (com.webauthn4j.appattest.validator.DCRegistrationObject)8 CoreRegistrationObject (com.webauthn4j.validator.CoreRegistrationObject)8 RegistrationObject (com.webauthn4j.validator.RegistrationObject)8 AuthenticatorTransport (com.webauthn4j.data.AuthenticatorTransport)7 RegistrationExtensionAuthenticatorOutput (com.webauthn4j.data.extension.authenticator.RegistrationExtensionAuthenticatorOutput)7 Instant (java.time.Instant)7 Test (org.junit.Test)5 DCServerProperty (com.webauthn4j.appattest.server.DCServerProperty)4 AttestationObjectConverter (com.webauthn4j.converter.AttestationObjectConverter)4