Skip to content

Commit 64f8111

Browse files
committed
Add InputStream parser APIs
1 parent 089d667 commit 64f8111

File tree

5 files changed

+138
-28
lines changed

5 files changed

+138
-28
lines changed

webauthn4j-core/src/main/java/com/webauthn4j/WebAuthnAuthenticationManager.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.slf4j.Logger;
3737
import org.slf4j.LoggerFactory;
3838

39+
import java.io.InputStream;
3940
import java.util.Collections;
4041
import java.util.List;
4142

@@ -79,10 +80,18 @@ public WebAuthnAuthenticationManager() {
7980
}
8081

8182

82-
@SuppressWarnings("java:S2583")
83-
public AuthenticationData parse(String authenticationResponseJSON) {
83+
public @NotNull AuthenticationData parse(@NotNull String authenticationResponseJSON) {
84+
PublicKeyCredential<AuthenticatorAssertionResponse, AuthenticationExtensionClientOutput> publicKeyCredential = objectConverter.getJsonConverter().readValue(authenticationResponseJSON, new TypeReference<>() {});
85+
return toAuthenticationData(publicKeyCredential);
86+
}
87+
88+
public @NotNull AuthenticationData parse(@NotNull InputStream authenticationResponseJSON) {
8489
PublicKeyCredential<AuthenticatorAssertionResponse, AuthenticationExtensionClientOutput> publicKeyCredential = objectConverter.getJsonConverter().readValue(authenticationResponseJSON, new TypeReference<>() {});
90+
return toAuthenticationData(publicKeyCredential);
91+
}
8592

93+
@SuppressWarnings("java:S2583")
94+
private @NotNull AuthenticationData toAuthenticationData(@NotNull PublicKeyCredential<AuthenticatorAssertionResponse, AuthenticationExtensionClientOutput> publicKeyCredential){
8695
byte[] credentialId = publicKeyCredential.getRawId();
8796
byte[] userHandle = publicKeyCredential.getResponse().getUserHandle();
8897

@@ -146,6 +155,13 @@ public AuthenticationData parse(String authenticationResponseJSON) {
146155
return verify(authenticationData, authenticationParameters);
147156
}
148157

158+
public @NotNull AuthenticationData verify(
159+
@NotNull InputStream authenticationResponseJSON,
160+
@NotNull AuthenticationParameters authenticationParameters) throws DataConversionException, VerificationException {
161+
AuthenticationData authenticationData = parse(authenticationResponseJSON);
162+
return verify(authenticationData, authenticationParameters);
163+
}
164+
149165
@SuppressWarnings("squid:S1130")
150166
public @NotNull AuthenticationData verify(
151167
@NotNull AuthenticationRequest authenticationRequest,

webauthn4j-core/src/main/java/com/webauthn4j/WebAuthnManager.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.webauthn4j.verifier.exception.VerificationException;
3939
import org.jetbrains.annotations.NotNull;
4040

41+
import java.io.InputStream;
4142
import java.util.ArrayList;
4243
import java.util.Arrays;
4344
import java.util.List;
@@ -150,6 +151,10 @@ public WebAuthnManager(@NotNull List<AttestationStatementVerifier> attestationSt
150151
return this.webAuthnRegistrationManager.parse(registrationResponseJSON);
151152
}
152153

154+
public @NotNull RegistrationData parseRegistrationResponseJSON(@NotNull InputStream registrationResponseJSON){
155+
return this.webAuthnRegistrationManager.parse(registrationResponseJSON);
156+
}
157+
153158
@SuppressWarnings("squid:S1130")
154159
public @NotNull RegistrationData parse(@NotNull RegistrationRequest registrationRequest) throws DataConversionException {
155160
return this.webAuthnRegistrationManager.parse(registrationRequest);
@@ -159,6 +164,10 @@ public WebAuthnManager(@NotNull List<AttestationStatementVerifier> attestationSt
159164
return this.webAuthnRegistrationManager.verify(registrationResponseJSON, registrationParameters);
160165
}
161166

167+
public @NotNull RegistrationData verifyRegistrationResponseJSON(@NotNull InputStream registrationResponseJSON, @NotNull RegistrationParameters registrationParameters) throws DataConversionException, VerificationException {
168+
return this.webAuthnRegistrationManager.verify(registrationResponseJSON, registrationParameters);
169+
}
170+
162171
@SuppressWarnings("squid:S1130")
163172
public @NotNull RegistrationData verify(@NotNull RegistrationRequest registrationRequest, @NotNull RegistrationParameters registrationParameters) throws DataConversionException, VerificationException {
164173
return this.webAuthnRegistrationManager.verify(registrationRequest, registrationParameters);
@@ -189,6 +198,10 @@ public WebAuthnManager(@NotNull List<AttestationStatementVerifier> attestationSt
189198
return this.webAuthnAuthenticationManager.parse(authenticationResponseJSON);
190199
}
191200

201+
public @NotNull AuthenticationData parseAuthenticationResponseJSON(@NotNull InputStream authenticationResponseJSON) throws DataConversionException {
202+
return this.webAuthnAuthenticationManager.parse(authenticationResponseJSON);
203+
}
204+
192205
@SuppressWarnings("squid:S1130")
193206
public @NotNull AuthenticationData parse(@NotNull AuthenticationRequest authenticationRequest) throws DataConversionException {
194207
return this.webAuthnAuthenticationManager.parse(authenticationRequest);
@@ -198,6 +211,10 @@ public WebAuthnManager(@NotNull List<AttestationStatementVerifier> attestationSt
198211
return this.webAuthnAuthenticationManager.verify(authenticationResponseJSON, authenticationParameters);
199212
}
200213

214+
public @NotNull AuthenticationData verifyAuthenticationResponseJSON(@NotNull InputStream authenticationResponseJSON, @NotNull AuthenticationParameters authenticationParameters) throws DataConversionException, VerificationException {
215+
return this.webAuthnAuthenticationManager.verify(authenticationResponseJSON, authenticationParameters);
216+
}
217+
201218
@SuppressWarnings("squid:S1130")
202219
public @NotNull AuthenticationData verify(@NotNull AuthenticationRequest authenticationRequest, @NotNull AuthenticationParameters authenticationParameters) throws DataConversionException, VerificationException {
203220
return this.webAuthnAuthenticationManager.verify(authenticationRequest, authenticationParameters);

webauthn4j-core/src/main/java/com/webauthn4j/WebAuthnRegistrationManager.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.slf4j.Logger;
4949
import org.slf4j.LoggerFactory;
5050

51+
import java.io.InputStream;
5152
import java.util.Arrays;
5253
import java.util.Collections;
5354
import java.util.List;
@@ -170,10 +171,18 @@ public WebAuthnRegistrationManager(@NotNull List<AttestationStatementVerifier> a
170171
);
171172
}
172173

173-
@SuppressWarnings("java:S2583")
174-
public RegistrationData parse(String registrationResponseJSON) {
174+
public @NotNull RegistrationData parse(@NotNull String registrationResponseJSON) {
175175
PublicKeyCredential<AuthenticatorAttestationResponse, RegistrationExtensionClientOutput> publicKeyCredential = objectConverter.getJsonConverter().readValue(registrationResponseJSON, new TypeReference<>() {});
176+
return toRegistrationData(publicKeyCredential);
177+
}
178+
179+
public @NotNull RegistrationData parse(@NotNull InputStream registrationResponseJSON) {
180+
PublicKeyCredential<AuthenticatorAttestationResponse, RegistrationExtensionClientOutput> publicKeyCredential = objectConverter.getJsonConverter().readValue(registrationResponseJSON, new TypeReference<>() {});
181+
return toRegistrationData(publicKeyCredential);
182+
}
176183

184+
@SuppressWarnings("java:S2583")
185+
private @NotNull RegistrationData toRegistrationData(@NotNull PublicKeyCredential<AuthenticatorAttestationResponse, RegistrationExtensionClientOutput> publicKeyCredential){
177186
byte[] attestationObjectBytes = publicKeyCredential.getResponse().getAttestationObject();
178187
AttestationObject attestationObject = attestationObjectBytes == null ? null : attestationObjectConverter.convert(attestationObjectBytes);
179188
byte[] clientDataBytes = publicKeyCredential.getResponse().getClientDataJSON();
@@ -218,7 +227,12 @@ public RegistrationData parse(String registrationResponseJSON) {
218227

219228
}
220229

221-
public RegistrationData verify(String registrationResponseJSON, @NotNull RegistrationParameters registrationParameters) {
230+
public @NotNull RegistrationData verify(@NotNull String registrationResponseJSON, @NotNull RegistrationParameters registrationParameters) {
231+
RegistrationData registrationData = parse(registrationResponseJSON);
232+
return verify(registrationData, registrationParameters);
233+
}
234+
235+
public @NotNull RegistrationData verify(@NotNull InputStream registrationResponseJSON, @NotNull RegistrationParameters registrationParameters) {
222236
RegistrationData registrationData = parse(registrationResponseJSON);
223237
return verify(registrationData, registrationParameters);
224238
}

webauthn4j-core/src/test/java/integration/scenario/webauthn/AuthenticationResponseJSONVerificationTest.java

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.webauthn4j.test.client.ClientPlatform;
3636
import org.junit.jupiter.api.Test;
3737

38+
import java.io.ByteArrayInputStream;
3839
import java.util.Collections;
3940
import java.util.List;
4041

@@ -45,14 +46,14 @@ class AuthenticationResponseJSONVerificationTest {
4546

4647
private final ObjectConverter objectConverter = new ObjectConverter();
4748

49+
private final String rpId = "example.com";
4850
private final Origin origin = new Origin("http://example.com");
4951
private final ClientPlatform clientPlatform = EmulatorUtil.createClientPlatform(EmulatorUtil.PACKED_AUTHENTICATOR);
5052
private final WebAuthnManager target = WebAuthnManager.createNonStrictWebAuthnManager(objectConverter);
5153

5254

5355
@Test
54-
void test() {
55-
String rpId = "example.com";
56+
void test_with_authenticationResponseJSON_as_string() {
5657
long timeout = 0;
5758
Challenge challenge = new DefaultChallenge();
5859

@@ -86,8 +87,45 @@ void test() {
8687
);
8788

8889
assertThatCode(()->target.parseAuthenticationResponseJSON(authenticationResponseJSON)).doesNotThrowAnyException();
89-
AuthenticationData authenticationData = target.parseAuthenticationResponseJSON(authenticationResponseJSON);
90-
assertThatCode(()->target.verify(authenticationData, authenticationParameters)).doesNotThrowAnyException();
90+
assertThatCode(()->target.verifyAuthenticationResponseJSON(authenticationResponseJSON, authenticationParameters)).doesNotThrowAnyException();
91+
}
92+
93+
@Test
94+
void test_with_authenticationResponseJSON_as_InputStream() {
95+
long timeout = 0;
96+
Challenge challenge = new DefaultChallenge();
97+
98+
// create
99+
AttestationObject attestationObject = createAttestationObject(rpId, challenge);
100+
101+
// get
102+
PublicKeyCredentialRequestOptions credentialRequestOptions = new PublicKeyCredentialRequestOptions(
103+
challenge,
104+
timeout,
105+
rpId,
106+
null,
107+
UserVerificationRequirement.REQUIRED,
108+
null
109+
);
110+
111+
PublicKeyCredential<AuthenticatorAssertionResponse, AuthenticationExtensionClientOutput> credential = clientPlatform.get(credentialRequestOptions);
112+
byte[] authenticationResponseJSON = objectConverter.getJsonConverter().writeValueAsBytes(credential);
113+
114+
115+
ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, null);
116+
Authenticator authenticator = TestDataUtil.createAuthenticator(attestationObject);
117+
118+
List<byte[]> allowCredentials = null;
119+
AuthenticationParameters authenticationParameters =
120+
new AuthenticationParameters(
121+
serverProperty,
122+
authenticator,
123+
allowCredentials,
124+
true
125+
);
126+
127+
assertThatCode(()->target.parseAuthenticationResponseJSON(new ByteArrayInputStream(authenticationResponseJSON))).doesNotThrowAnyException();
128+
assertThatCode(()->target.verifyAuthenticationResponseJSON(new ByteArrayInputStream(authenticationResponseJSON), authenticationParameters)).doesNotThrowAnyException();
91129
}
92130

93131
private AttestationObject createAttestationObject(String rpId, Challenge challenge) {

webauthn4j-core/src/test/java/integration/scenario/webauthn/RegistrationResponseJSONVerificationTest.java

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.webauthn4j.verifier.attestation.trustworthiness.self.DefaultSelfAttestationTrustworthinessVerifier;
4141
import org.junit.jupiter.api.Test;
4242

43+
import java.io.ByteArrayInputStream;
4344
import java.util.Arrays;
4445
import java.util.Collections;
4546
import java.util.List;
@@ -51,7 +52,9 @@ class RegistrationResponseJSONVerificationTest {
5152

5253
private final ObjectConverter objectConverter = new ObjectConverter();
5354

55+
private final String rpId = "example.com";
5456
private final Origin origin = new Origin("http://localhost");
57+
private final Challenge challenge = new DefaultChallenge();
5558
private final WebAuthnAuthenticatorAdaptor webAuthnAuthenticatorAdaptor = new WebAuthnAuthenticatorAdaptor(EmulatorUtil.PACKED_AUTHENTICATOR);
5659
private final ClientPlatform clientPlatform = new ClientPlatform(origin, webAuthnAuthenticatorAdaptor);
5760
private final NoneAttestationStatementVerifier noneAttestationStatementValidator = new NoneAttestationStatementVerifier();
@@ -71,9 +74,46 @@ class RegistrationResponseJSONVerificationTest {
7174
);
7275

7376
@Test
74-
void test() {
75-
String rpId = "example.com";
76-
Challenge challenge = new DefaultChallenge();
77+
void test_with_registrationResponseJSON_as_string() {
78+
PublicKeyCredential<AuthenticatorAttestationResponse, RegistrationExtensionClientOutput> credential = createCredential();
79+
String registrationResponseJSON = objectConverter.getJsonConverter().writeValueAsString(credential);
80+
ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, null);
81+
List<PublicKeyCredentialParameters> pubKeyCredParams = null;
82+
RegistrationParameters registrationParameters = new RegistrationParameters(
83+
serverProperty,
84+
pubKeyCredParams,
85+
false
86+
);
87+
88+
assertThatCode(()->target.parseRegistrationResponseJSON(registrationResponseJSON)).doesNotThrowAnyException();
89+
90+
RegistrationData registrationData = target.parseRegistrationResponseJSON(registrationResponseJSON);
91+
assertThatCode(()->target.verify(registrationData, registrationParameters)).doesNotThrowAnyException();
92+
93+
assertThatCode(()->target.verifyRegistrationResponseJSON(registrationResponseJSON, registrationParameters)).doesNotThrowAnyException();
94+
}
95+
96+
@Test
97+
void test_with_registrationResponseJSON_as_InputStream() {
98+
PublicKeyCredential<AuthenticatorAttestationResponse, RegistrationExtensionClientOutput> credential = createCredential();
99+
byte[] registrationResponseJSON = objectConverter.getJsonConverter().writeValueAsBytes(credential);
100+
ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, null);
101+
List<PublicKeyCredentialParameters> pubKeyCredParams = null;
102+
RegistrationParameters registrationParameters = new RegistrationParameters(
103+
serverProperty,
104+
pubKeyCredParams,
105+
false
106+
);
107+
108+
assertThatCode(()->target.parseRegistrationResponseJSON(new ByteArrayInputStream(registrationResponseJSON))).doesNotThrowAnyException();
109+
110+
RegistrationData registrationData = target.parseRegistrationResponseJSON(new ByteArrayInputStream(registrationResponseJSON));
111+
assertThatCode(()->target.verify(registrationData, registrationParameters)).doesNotThrowAnyException();
112+
113+
assertThatCode(()->target.verifyRegistrationResponseJSON(new ByteArrayInputStream(registrationResponseJSON), registrationParameters)).doesNotThrowAnyException();
114+
}
115+
116+
private PublicKeyCredential<AuthenticatorAttestationResponse, RegistrationExtensionClientOutput> createCredential(){
77117
AuthenticatorSelectionCriteria authenticatorSelectionCriteria =
78118
new AuthenticatorSelectionCriteria(
79119
AuthenticatorAttachment.CROSS_PLATFORM,
@@ -97,21 +137,6 @@ void test() {
97137
AttestationConveyancePreference.NONE,
98138
extensions
99139
);
100-
PublicKeyCredential<AuthenticatorAttestationResponse, RegistrationExtensionClientOutput> credential = clientPlatform.create(credentialCreationOptions);
101-
String registrationResponseJSON = objectConverter.getJsonConverter().writeValueAsString(credential);
102-
ServerProperty serverProperty = new ServerProperty(origin, rpId, challenge, null);
103-
List<PublicKeyCredentialParameters> pubKeyCredParams = null;
104-
RegistrationParameters registrationParameters = new RegistrationParameters(
105-
serverProperty,
106-
pubKeyCredParams,
107-
false
108-
);
109-
110-
assertThatCode(()->target.parseRegistrationResponseJSON(registrationResponseJSON)).doesNotThrowAnyException();
111-
112-
RegistrationData registrationData = target.parseRegistrationResponseJSON(registrationResponseJSON);
113-
assertThatCode(()->target.verify(registrationData, registrationParameters)).doesNotThrowAnyException();
114-
115-
assertThatCode(()->target.verifyRegistrationResponseJSON(registrationResponseJSON, registrationParameters)).doesNotThrowAnyException();
140+
return clientPlatform.create(credentialCreationOptions);
116141
}
117142
}

0 commit comments

Comments
 (0)