From dd4a1fb11efb226bf9db8510c76b7b0005a823d4 Mon Sep 17 00:00:00 2001 From: Imran <78725662+imran-ishaq@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:11:54 +0500 Subject: [PATCH] Reflect Authenicator Name with Passkeys (#9716) * feat(jans-fido2): reflect authenticator name with passkeys Signed-off-by: imran-ishaq * fix(jans-fido2): handle test cases for authenticator name Signed-off-by: imran-ishaq --------- Signed-off-by: imran-ishaq Co-authored-by: Mohammad Abudayyeh <47318409+moabu@users.noreply.github.com> --- .../fido2/model/auth/CredAndCounterData.java | 4 +++ .../mds/AttestationCertificateService.java | 28 +++++++++++++++++-- .../service/operation/AttestationService.java | 1 + .../AppleAttestationProcessor.java | 1 + .../PackedAttestationProcessor.java | 1 + .../processor/attestation/TPMProcessor.java | 1 + .../attestation/U2FAttestationProcessor.java | 1 + .../U2FSuperGluuAttestationProcessor.java | 1 + .../PackedAttestationProcessorTest.java | 2 +- .../U2FAttestationProcessorTest.java | 2 +- 10 files changed, 38 insertions(+), 4 deletions(-) diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/model/auth/CredAndCounterData.java b/jans-fido2/server/src/main/java/io/jans/fido2/model/auth/CredAndCounterData.java index db333ab8ce7..8e2261f528d 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/model/auth/CredAndCounterData.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/model/auth/CredAndCounterData.java @@ -30,6 +30,7 @@ public class CredAndCounterData { private boolean extensionDataFlag; private boolean userVerifiedFlag; private boolean userPresentFlag; + private String authenticatorName; public String getCredId() { return credId; @@ -122,4 +123,7 @@ public boolean isUserPresentFlag() { public void setUserPresentFlag(boolean userPresentFlag) { this.userPresentFlag = userPresentFlag; } + + public void setAuthenticatorName(String authenticatorName) {this.authenticatorName = authenticatorName;} + public String getAuthenticatorName() {return authenticatorName;} } diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/AttestationCertificateService.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/AttestationCertificateService.java index 1e6100bff1b..a142f5da9b1 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/AttestationCertificateService.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/mds/AttestationCertificateService.java @@ -112,7 +112,27 @@ public List getAttestationRootCertificates(JsonNode metadataNod return certificateService.getCertificates(x509certificates); } - public List getAttestationRootCertificates(AuthData authData, List attestationCertificates) { + public String getAttestationAuthenticatorName(AuthData authData) { + JsonNode metadataForAuthenticator = getMetadataForAuthenticator(authData); + JsonNode metaDataStatement = null; + if ((metadataForAuthenticator != null)) { + if (metadataForAuthenticator.has("description")) { + metaDataStatement = metadataForAuthenticator; + } else if (metadataForAuthenticator.has("metadataStatement")) { + try { + metaDataStatement = dataMapperService.readTree(metadataForAuthenticator.get("metadataStatement").toPrettyString()); + } catch (IOException e) { + log.error("Error parsing the metadata statement", e); + } + } + } + if (metadataForAuthenticator == null || metaDataStatement == null + || !metaDataStatement.has("description")) { + return null; + } + return metaDataStatement.get("description").asText(); + } + private JsonNode getMetadataForAuthenticator(AuthData authData) { String aaguid = Hex.encodeHexString(authData.getAaguid()); Fido2Configuration fido2Configuration = appConfiguration.getFido2Configuration(); JsonNode metadataForAuthenticator; @@ -126,14 +146,18 @@ public List getAttestationRootCertificates(AuthData authData, L log.info("No Local metadata for authenticator {}. Checking for metadata MDS3 blob", aaguid); JsonNode metadata = mdsService.fetchMetadata(authData.getAaguid()); commonVerifiers.verifyThatMetadataIsValid(metadata); - return getAttestationRootCertificates(metadata, attestationCertificates); + metadataForAuthenticator = metadata; } catch (Fido2RuntimeException ex) { log.warn("Failed to get metadata from Fido2 meta-data server: {}", ex.getMessage(), ex); metadataForAuthenticator = dataMapperService.createObjectNode(); } } + return metadataForAuthenticator; + } + public List getAttestationRootCertificates(AuthData authData, List attestationCertificates) { + JsonNode metadataForAuthenticator = getMetadataForAuthenticator(authData); return getAttestationRootCertificates(metadataForAuthenticator, attestationCertificates); } diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/operation/AttestationService.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/operation/AttestationService.java index b3ebe10d4e8..21fc3d426a5 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/operation/AttestationService.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/operation/AttestationService.java @@ -353,6 +353,7 @@ public AttestationOrAssertionResponse verify(AttestationResult attestationResult attestationResultResponse.setCredentials(credentialDescriptor); attestationResultResponse.setStatus("ok"); attestationResultResponse.setErrorMessage(""); + attestationResultResponse.setAuthenticatorName(attestationData.getAuthenticatorName()); externalFido2InterceptionContext.addToContext(registrationEntry, null); externalFido2InterceptionService.verifyAttestationFinish(CommonUtilService.toJsonNode(attestationResult), externalFido2InterceptionContext); diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/AppleAttestationProcessor.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/AppleAttestationProcessor.java index ba583816f39..9f62b4df8c2 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/AppleAttestationProcessor.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/AppleAttestationProcessor.java @@ -171,6 +171,7 @@ public void process(JsonNode attStmt, AuthData authData, Fido2RegistrationData c // log.info("attStmt.get(\"alg\")"+attStmt.get("alg")); int alg = -7;// commonVerifiers.verifyAlgorithm(attStmt.get("alg"), authData.getKeyType()); credIdAndCounters.setSignatureAlgorithm(alg); + credIdAndCounters.setAuthenticatorName(attestationCertificateService.getAttestationAuthenticatorName(authData)); } } } diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessor.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessor.java index 67200d2e451..2a468c167fd 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessor.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessor.java @@ -120,6 +120,7 @@ public void process(JsonNode attStmt, AuthData authData, Fido2RegistrationData r credIdAndCounters.setCredId(base64Service.urlEncodeToString(authData.getCredId())); credIdAndCounters.setUncompressedEcPoint(base64Service.urlEncodeToString(authData.getCosePublicKey())); credIdAndCounters.setSignatureAlgorithm(alg); + credIdAndCounters.setAuthenticatorName(attestationCertificateService.getAttestationAuthenticatorName(authData)); } private List getAttestationCertificates(JsonNode attStmt) { diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/TPMProcessor.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/TPMProcessor.java index fbc7e971bc7..343f64deb2c 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/TPMProcessor.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/TPMProcessor.java @@ -168,6 +168,7 @@ public void process(JsonNode attStmt, AuthData authData, Fido2RegistrationData c credIdAndCounters.setAttestationType(getAttestationFormat().getFmt()); credIdAndCounters.setCredId(base64Service.urlEncodeToString(authData.getCredId())); credIdAndCounters.setUncompressedEcPoint(base64Service.urlEncodeToString(authData.getCosePublicKey())); + credIdAndCounters.setAuthenticatorName(attestationCertificateService.getAttestationAuthenticatorName(authData)); credIdAndCounters.setSignatureAlgorithm(alg); } else { throw errorResponseFactory.badRequestException(AttestationErrorResponseType.TPM_ERROR, "Problem with TPM attestation. Unsupported"); diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessor.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessor.java index 28bd832287d..f05184efafb 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessor.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessor.java @@ -138,5 +138,6 @@ public void process(JsonNode attStmt, AuthData authData, Fido2RegistrationData r credIdAndCounters.setAttestationType(getAttestationFormat().getFmt()); credIdAndCounters.setCredId(base64Service.urlEncodeToString(authData.getCredId())); credIdAndCounters.setUncompressedEcPoint(base64Service.urlEncodeToString(authData.getCosePublicKey())); + credIdAndCounters.setAuthenticatorName(attestationCertificateService.getAttestationAuthenticatorName(authData)); } } diff --git a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FSuperGluuAttestationProcessor.java b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FSuperGluuAttestationProcessor.java index 7820c743dc1..5234ef17f85 100644 --- a/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FSuperGluuAttestationProcessor.java +++ b/jans-fido2/server/src/main/java/io/jans/fido2/service/processor/attestation/U2FSuperGluuAttestationProcessor.java @@ -127,6 +127,7 @@ public void process(JsonNode attStmt, AuthData authData, Fido2RegistrationData r credIdAndCounters.setAttestationType(getAttestationFormat().getFmt()); credIdAndCounters.setCredId(base64Service.urlEncodeToString(authData.getCredId())); credIdAndCounters.setUncompressedEcPoint(base64Service.urlEncodeToString(authData.getCosePublicKey())); + credIdAndCounters.setAuthenticatorName(attestationCertificateService.getAttestationAuthenticatorName(authData)); } } diff --git a/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessorTest.java b/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessorTest.java index 64538dbce73..cb6f0ffb983 100644 --- a/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessorTest.java +++ b/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/PackedAttestationProcessorTest.java @@ -275,6 +275,6 @@ void process_ifAttStmtIsNotX5cOrEcdaaKey_valid() { verify(commonVerifiers).verifyAlgorithm(any(JsonNode.class), any(Integer.class)); verify(commonVerifiers).verifyBase64String(any(JsonNode.class)); verify(base64Service, times(2)).urlEncodeToString(any()); - verifyNoInteractions(certificateService, attestationCertificateService, appConfiguration, log, certificateVerifier); + verifyNoInteractions(certificateService, appConfiguration, log, certificateVerifier); } } diff --git a/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessorTest.java b/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessorTest.java index 42920a77e6f..ffd7a34c2e5 100644 --- a/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessorTest.java +++ b/jans-fido2/server/src/test/java/io/jans/fido2/service/processor/attestation/U2FAttestationProcessorTest.java @@ -239,6 +239,6 @@ void process_ifAttStmtNotIsX5cOrEcdaaKeyId_success() { verify(commonVerifiers).verifyRpIdHash(authData, "test-domain"); verify(coseService).getPublicKeyFromUncompressedECPoint(any()); verify(authenticatorDataVerifier).verifyPackedSurrogateAttestationSignature(authData.getAuthDataDecoded(), clientDataHash, "test-signature", publicKey, -7); - verifyNoInteractions(log, certificateService, certificateVerifier, appConfiguration, attestationCertificateService); + verifyNoInteractions(log, certificateService, certificateVerifier, appConfiguration); } }