Skip to content

Commit dcaf3dd

Browse files
ynojimavietj
authored andcommitted
Enable attestation verification when Attestation.DIRECT or INDIRECT is specified
1 parent f2d60e0 commit dcaf3dd

File tree

3 files changed

+26
-26
lines changed

3 files changed

+26
-26
lines changed

vertx-auth-webauthn4j/src/main/java/io/vertx/ext/auth/webauthn4j/impl/WebAuthn4JImpl.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public WebAuthn4JImpl(Vertx vertx, WebAuthn4JOptions options) {
141141
throw new IllegalArgumentException("options.relyingParty.name cannot be null!");
142142
}
143143

144-
if(options.getAttestation() == Attestation.ENTERPRISE) {
144+
if(options.getAttestation() != Attestation.NONE) {
145145
TrustAnchorAsyncRepository something;
146146
Set<TrustAnchor> trustAnchors = new HashSet<>();
147147
try {
@@ -163,7 +163,7 @@ public WebAuthn4JImpl(Vertx vertx, WebAuthn4JOptions options) {
163163
FidoMDS3MetadataBLOBAsyncProvider blobAsyncProvider = new FidoMDS3MetadataBLOBAsyncProvider(objectConverter, FidoMDS3MetadataBLOBAsyncProvider.DEFAULT_BLOB_ENDPOINT, httpClient, trustAnchors);
164164
something = new MetadataBLOBBasedTrustAnchorAsyncRepository(blobAsyncProvider);
165165
}
166-
166+
167167
webAuthnManager = new WebAuthnAsyncManager(
168168
Arrays.asList(
169169
new NoneAttestationStatementAsyncVerifier(),
@@ -178,7 +178,7 @@ public WebAuthn4JImpl(Vertx vertx, WebAuthn4JOptions options) {
178178
new DefaultSelfAttestationTrustworthinessAsyncVerifier(),
179179
objectConverter
180180
);
181-
181+
182182
} else {
183183
webAuthnManager = WebAuthnAsyncManager.createNonStrictWebAuthnAsyncManager(objectConverter);
184184
}
@@ -523,7 +523,7 @@ public Future<User> authenticate(Credentials credentials) {
523523
* @param clientDataJSON - Binary session data
524524
*/
525525
private Future<Authenticator> verifyWebAuthNCreate(JsonObject response, WebAuthn4JCredentials authInfo, byte[] clientDataJSON) {
526-
526+
527527
// client properties
528528
byte[] attestationObject = base64UrlDecode(response.getString("attestationObject"));
529529
Set<String> transports = new HashSet<>();
@@ -543,7 +543,7 @@ private Future<Authenticator> verifyWebAuthNCreate(JsonObject response, WebAuthn
543543
String clientExtensionJSON = clientExtensionResults != null ? clientExtensionResults.encode() : null;
544544

545545
RegistrationRequest registrationRequest = new RegistrationRequest(attestationObject, clientDataJSON, clientExtensionJSON, transports);
546-
546+
547547
// server properties
548548
ServerProperty serverProperty = getServerProperty(authInfo);
549549

@@ -656,7 +656,7 @@ private Future<Long> verifyWebAuthNGet(JsonObject response, WebAuthn4JCredential
656656
boolean userVerificationRequired = options.getUserVerification() == UserVerification.REQUIRED;
657657
boolean userPresenceRequired = options.isUserPresenceRequired();
658658
CredentialRecord credentialRecord = loadCredentialRecord(authenticator);
659-
659+
660660
AuthenticationParameters authenticationParameters =
661661
new AuthenticationParameters(
662662
serverProperty,
@@ -666,15 +666,15 @@ private Future<Long> verifyWebAuthNGet(JsonObject response, WebAuthn4JCredential
666666
userPresenceRequired
667667
);
668668

669-
669+
670670
return Future.fromCompletionStage(webAuthnManager.verify(authenticationRequest, authenticationParameters))
671671
.map(parsedAuthenticatorData -> parsedAuthenticatorData.getAuthenticatorData().getSignCount());
672672
}
673673

674674
private CredentialRecord loadCredentialRecord(Authenticator authenticator) {
675675
// AFAICT, we could reconstruct that from the fmt and certificates, but it doesn't look like it is used
676676
// apparently only coseKey and counter are used for verification, not the attestation statement.
677-
677+
678678
// important
679679
long counter = authenticator.getCounter();
680680
COSEKey coseKey = objectConverter.getCborConverter().readValue(base64UrlDecode(authenticator.getPublicKey()), COSEKey.class);
@@ -691,8 +691,8 @@ private CredentialRecord loadCredentialRecord(Authenticator authenticator) {
691691
CollectedClientData clientData = null;
692692
AuthenticationExtensionsClientOutputs<RegistrationExtensionClientOutput> clientExtensions = null;
693693
Set<com.webauthn4j.data.AuthenticatorTransport> transports = null;
694-
695-
return new CredentialRecordImpl(attestationStatement, uvInitialized, backupEligible, backupState, counter, attestedCredentialData,
694+
695+
return new CredentialRecordImpl(attestationStatement, uvInitialized, backupEligible, backupState, counter, attestedCredentialData,
696696
authenticatorExtensions, clientData, clientExtensions, transports);
697697
}
698-
}
698+
}

vertx-auth-webauthn4j/src/test/java/io/vertx/tests/EmulatorTest.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public void resetDatabase() {
9696
database.clear();
9797
}
9898

99-
99+
100100
@Test
101101
public void testMetadata(TestContext should) {
102102
final Async test = should.async();
@@ -111,11 +111,11 @@ public void testMetadata(TestContext should) {
111111
}
112112
FidoMDS3MetadataBLOBAsyncProvider blobAsyncProvider = new FidoMDS3MetadataBLOBAsyncProvider(objectConverter, FidoMDS3MetadataBLOBAsyncProvider.DEFAULT_BLOB_ENDPOINT, httpClient, trustAnchors);
113113
MetadataBLOBBasedTrustAnchorAsyncRepository something = new MetadataBLOBBasedTrustAnchorAsyncRepository(blobAsyncProvider);
114-
blobAsyncProvider.provide()
114+
blobAsyncProvider.provide()
115115
.thenCompose(metadataBLOB -> {
116116
Assert.assertNotEquals(0, metadataBLOB.getPayload().getEntries().size());
117117
for (MetadataBLOBPayloadEntry entry : metadataBLOB.getPayload().getEntries()) {
118-
if(entry.getAaguid() != null
118+
if(entry.getAaguid() != null
119119
// the following are things that are in the implementation of webauthn4j that will filter what find() returns, so make sure
120120
// they pass
121121
&& !entry.getMetadataStatement().getAttestationRootCertificates().isEmpty()
@@ -137,7 +137,7 @@ public void testMetadata(TestContext should) {
137137
return null;
138138
});
139139
}
140-
140+
141141
@Test
142142
public void testDefaults(TestContext should) throws DataConversionException, InterruptedException, ExecutionException {
143143
final Async test = should.async();
@@ -149,48 +149,48 @@ public void testDefaults(TestContext should) throws DataConversionException, Int
149149

150150
WebAuthnAuthenticatorAdaptor webAuthnAuthenticatorAdaptor = new WebAuthnAuthenticatorAdaptor(EmulatorUtil.PACKED_AUTHENTICATOR);
151151
ClientPlatform clientPlatform = new ClientPlatform(origin, webAuthnAuthenticatorAdaptor);
152-
152+
153153
testRegistration(webAuthN, clientPlatform, should)
154154
.flatMap(v -> testAuthentication(webAuthN, clientPlatform, should))
155155
.onFailure(should::fail)
156156
.onSuccess(v -> test.complete());
157157
}
158158

159159
@Test
160-
public void testEnterprise(TestContext should) throws DataConversionException, InterruptedException, ExecutionException {
160+
public void testDirect(TestContext should) throws DataConversionException, InterruptedException, ExecutionException {
161161
final Async test = should.async();
162162

163163
X509Certificate rootCA = TestAttestationUtil.load3tierTestRootCACertificate();
164-
164+
165165
WebAuthn4J webAuthN = WebAuthn4J.create(
166166
rule.vertx(),
167167
new WebAuthn4JOptions().setRelyingParty(new RelyingParty().setName(rpName))
168-
.setAttestation(Attestation.ENTERPRISE)
168+
.setAttestation(Attestation.DIRECT)
169169
.addRootCertificate(rootCA))
170170
.credentialStorage(database);
171171

172172
WebAuthnAuthenticatorAdaptor webAuthnAuthenticatorAdaptor = new WebAuthnAuthenticatorAdaptor(EmulatorUtil.PACKED_AUTHENTICATOR);
173173
ClientPlatform clientPlatform = new ClientPlatform(origin, webAuthnAuthenticatorAdaptor);
174-
174+
175175
testRegistration(webAuthN, clientPlatform, should)
176176
.flatMap(v -> testAuthentication(webAuthN, clientPlatform, should))
177177
.onFailure(should::fail)
178178
.onSuccess(v -> test.complete());
179179
}
180180

181181
@Test
182-
public void testEnterpriseWithoutCA(TestContext should) throws DataConversionException, InterruptedException, ExecutionException {
182+
public void testDirectWithoutCA(TestContext should) throws DataConversionException, InterruptedException, ExecutionException {
183183
final Async test = should.async();
184184

185185
WebAuthn4J webAuthN = WebAuthn4J.create(
186186
rule.vertx(),
187187
new WebAuthn4JOptions().setRelyingParty(new RelyingParty().setName(rpName))
188-
.setAttestation(Attestation.ENTERPRISE))
188+
.setAttestation(Attestation.DIRECT))
189189
.credentialStorage(database);
190190

191191
WebAuthnAuthenticatorAdaptor webAuthnAuthenticatorAdaptor = new WebAuthnAuthenticatorAdaptor(EmulatorUtil.PACKED_AUTHENTICATOR);
192192
ClientPlatform clientPlatform = new ClientPlatform(origin, webAuthnAuthenticatorAdaptor);
193-
193+
194194
testRegistration(webAuthN, clientPlatform, should)
195195
.flatMap(v -> testAuthentication(webAuthN, clientPlatform, should))
196196
.onFailure(x -> {
@@ -242,7 +242,7 @@ private Future<?> testRegistration(WebAuthn4J webAuthN, ClientPlatform clientPla
242242
});
243243

244244
}
245-
245+
246246
private RegistrationRequest createRegistrationRequest(ClientPlatform clientPlatform, String rpId, Challenge challenge, String username, String displayName, TestContext should){
247247
AuthenticatorSelectionCriteria authenticatorSelectionCriteria =
248248
new AuthenticatorSelectionCriteria(
@@ -353,5 +353,5 @@ private AuthenticationRequest createAuthenticationRequest(ClientPlatform clientP
353353
);
354354

355355
}
356-
356+
357357
}

vertx-auth-webauthn4j/src/test/java/io/vertx/tests/attestation/AttestationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void testPackedFullAttestation(TestContext should) throws CertificateExce
5858

5959
// we are testing all the certificates, which only happens for ENTERPRISE
6060
WebAuthn4JOptions options = new WebAuthn4JOptions().setRelyingParty(new RelyingParty().setName("FIDO Examples Corporation"))
61-
.setAttestation(Attestation.ENTERPRISE);
61+
.setAttestation(Attestation.DIRECT);
6262
// testing attestation validity only happens if we verify that the root CA is known, so we have to add it
6363
options.getRootCertificates().put("Yubico FIDO Preview CA", JWS.parseX5c(YUBICO_FIDO_PREVIEW_CA_EXPIRED_2018));
6464

0 commit comments

Comments
 (0)