diff --git a/server-spi/src/main/java/org/keycloak/models/credential/WebAuthnCredentialModel.java b/server-spi/src/main/java/org/keycloak/models/credential/WebAuthnCredentialModel.java index 0a878a52c1..e46fcc17b5 100644 --- a/server-spi/src/main/java/org/keycloak/models/credential/WebAuthnCredentialModel.java +++ b/server-spi/src/main/java/org/keycloak/models/credential/WebAuthnCredentialModel.java @@ -48,8 +48,8 @@ public class WebAuthnCredentialModel extends CredentialModel { } public static WebAuthnCredentialModel create(String credentialType, String userLabel, String aaguid, String credentialId, - String attestationStatement, String credentialPublicKey, long counter) { - WebAuthnCredentialData credentialData = new WebAuthnCredentialData(aaguid, credentialId, counter, attestationStatement, credentialPublicKey); + String attestationStatement, String credentialPublicKey, long counter, String attestationStatementFormat) { + WebAuthnCredentialData credentialData = new WebAuthnCredentialData(aaguid, credentialId, counter, attestationStatement, credentialPublicKey, attestationStatementFormat); WebAuthnSecretData secretData = new WebAuthnSecretData(); WebAuthnCredentialModel credentialModel = new WebAuthnCredentialModel(credentialType, credentialData, secretData); diff --git a/server-spi/src/main/java/org/keycloak/models/credential/dto/WebAuthnCredentialData.java b/server-spi/src/main/java/org/keycloak/models/credential/dto/WebAuthnCredentialData.java index 1b7b3a46cd..acbde94c16 100644 --- a/server-spi/src/main/java/org/keycloak/models/credential/dto/WebAuthnCredentialData.java +++ b/server-spi/src/main/java/org/keycloak/models/credential/dto/WebAuthnCredentialData.java @@ -31,18 +31,21 @@ public class WebAuthnCredentialData { private long counter; private String attestationStatement; private String credentialPublicKey; + private String attestationStatementFormat; @JsonCreator public WebAuthnCredentialData(@JsonProperty("aaguid") String aaguid, @JsonProperty("credentialId") String credentialId, @JsonProperty("counter") long counter, @JsonProperty("attestationStatement") String attestationStatement, - @JsonProperty("credentialPublicKey") String credentialPublicKey ) { + @JsonProperty("credentialPublicKey") String credentialPublicKey, + @JsonProperty("attestationStatementFormat") String attestationStatementFormat) { this.aaguid = aaguid; this.credentialId = credentialId; this.counter = counter; this.attestationStatement = attestationStatement; this.credentialPublicKey = credentialPublicKey; + this.attestationStatementFormat = attestationStatementFormat; } public String getAaguid() { @@ -69,6 +72,14 @@ public class WebAuthnCredentialData { this.counter = counter; } + public String getAttestationStatementFormat() { + return attestationStatementFormat; + } + + public void setAttestationStatementFormat(String attestationStatementFormat) { + this.attestationStatementFormat = attestationStatementFormat; + } + @Override public String toString() { return "WebAuthnCredentialData { " + @@ -78,6 +89,7 @@ public class WebAuthnCredentialData { ", credentialPublicKey=" + credentialPublicKey + ", attestationStatement='" + attestationStatement + '\'' + ", credentialPublicKey='" + credentialPublicKey + '\'' + + ", attestationStatementFormat='" + attestationStatementFormat + '\'' + " }"; } } diff --git a/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java b/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java index bbcc9c11e3..1f408b8cab 100644 --- a/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java +++ b/services/src/main/java/org/keycloak/authentication/requiredactions/WebAuthnRegister.java @@ -223,6 +223,7 @@ public class WebAuthnRegister implements RequiredActionProvider, CredentialRegis credential.setAttestedCredentialData(registrationData.getAttestationObject().getAuthenticatorData().getAttestedCredentialData()); credential.setCount(registrationData.getAttestationObject().getAuthenticatorData().getSignCount()); + credential.setAttestationStatementFormat(registrationData.getAttestationObject().getFormat()); // Save new webAuthn credential WebAuthnCredentialProvider webAuthnCredProvider = (WebAuthnCredentialProvider) this.session.getProvider(CredentialProvider.class, getCredentialProviderId()); diff --git a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialModelInput.java b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialModelInput.java index 87f94cbc0b..080e03df2c 100644 --- a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialModelInput.java +++ b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialModelInput.java @@ -33,6 +33,7 @@ public class WebAuthnCredentialModelInput implements CredentialInput { private long count; private String credentialDBId; private final String credentialType; + private String attestationStatementFormat; public WebAuthnCredentialModelInput(String credentialType) { this.credentialType = credentialType; @@ -106,16 +107,29 @@ public class WebAuthnCredentialModelInput implements CredentialInput { return credentialType; } + public String getAttestationStatementFormat() { + return attestationStatementFormat; + } + + public void setAttestationStatementFormat(String attestationStatementFormat) { + this.attestationStatementFormat = attestationStatementFormat; + } + public String toString() { StringBuilder sb = new StringBuilder("Credential Type = " + credentialType + ","); if (credentialDBId != null) sb.append("Credential DB Id = ") .append(credentialDBId) .append(","); - if (attestationStatement != null) + if (attestationStatement != null) { sb.append("Attestation Statement Format = ") .append(attestationStatement.getFormat()) .append(","); + } else if (attestationStatementFormat != null) { + sb.append("Attestation Statement Format = ") + .append(attestationStatementFormat) + .append(","); + } if (attestedCredentialData != null) { sb.append("AAGUID = ") .append(attestedCredentialData.getAaguid().toString()) diff --git a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java index b9b06a8100..ac9a257955 100644 --- a/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java +++ b/services/src/main/java/org/keycloak/credential/WebAuthnCredentialProvider.java @@ -102,8 +102,9 @@ public class WebAuthnCredentialProvider implements CredentialProvider credentials = getCredentials(userId); + credentials.stream().forEach(i -> { + if (WebAuthnCredentialModel.TYPE_TWOFACTOR.equals(i.getType())) { + try { + WebAuthnCredentialData data = JsonSerialization.readValue(i.getCredentialData(), WebAuthnCredentialData.class); + assertEquals(aaguid, data.getAaguid()); + assertEquals(attestationStatementFormat, data.getAttestationStatementFormat()); + } catch (IOException e) { + Assert.fail(); + } + } + }); + } + protected UserRepresentation getUser(String userId) { return testRealm().users().get(userId).toRepresentation(); } + protected List getCredentials(String userId) { + return testRealm().users().get(userId).credentials(); + } + private RealmRepresentation backupWebAuthnRealmSettings() { RealmRepresentation rep = testRealm().toRepresentation(); signatureAlgorithms = rep.getWebAuthnPolicySignatureAlgorithms();