Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add authentication SG flow tests #3877

Merged
merged 1 commit into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public class ChallengeGenerator {
@Inject
private Base64Service base64Service;

public String getAttestationChallenge() {
return getChallenge();
}

public String getAssertionChallenge() {
return getChallenge();
}

public String getChallenge() {
byte buffer[] = new byte[32];
new SecureRandom().nextBytes(buffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public ObjectNode options(JsonNode params) {
optionsResponseNode.put("userVerification", userVerification.name());

// Generate and put challenge
String challenge = challengeGenerator.getChallenge();
String challenge = challengeGenerator.getAssertionChallenge();
optionsResponseNode.put("challenge", challenge);
log.debug("Put challenge {}", challenge);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public ObjectNode options(JsonNode params) {
log.debug("Put authenticatorSelection {}", authenticatorSelectionNode);

// Generate and put challenge
String challenge = challengeGenerator.getChallenge();
String challenge = challengeGenerator.getAttestationChallenge();
optionsResponseNode.put("challenge", challenge);
log.debug("Put challenge {}", challenge);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

package io.jans.fido2.service.persist;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
Expand All @@ -23,13 +22,9 @@
import io.jans.fido2.service.ChallengeGenerator;
import io.jans.fido2.service.shared.UserService;
import io.jans.orm.PersistenceEntryManager;
import io.jans.orm.model.BatchOperation;
import io.jans.orm.model.ProcessBatchOperation;
import io.jans.orm.model.SearchScope;
import io.jans.orm.model.base.SimpleBranch;
import io.jans.orm.model.fido2.Fido2AuthenticationData;
import io.jans.orm.model.fido2.Fido2AuthenticationEntry;
import io.jans.orm.model.fido2.Fido2AuthenticationStatus;
import io.jans.orm.search.filter.Filter;
import io.jans.util.StringHelper;
import jakarta.enterprise.context.ApplicationScoped;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public class RegistrationPersistenceService extends io.jans.as.common.service.co
@Inject
private UserService userService;

// public void setUserService(UserService userService) {
// this.userService = userService;
// }

@Inject
private PersistenceEntryManager persistenceEntryManager;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,7 @@ public class AssertionSuperGluuController {
* "keyHandle":"YJvWD9n40eIurInJvPKUoxpKzrleUMWgu9w3v_NUBu7BiGAclgkH_Zg88_T5y6Rh78imTxTh0djWFYG4jxOixw","version":"U2F_V2"}]}
*/
public JsonNode startAuthentication(String userName, String keyHandle, String appId, String sessionId) {
boolean oneStep = StringHelper.isEmpty(userName);

boolean valid = userSessionIdService.isValidSessionId(sessionId, userName);
if (!valid) {
throw new Fido2RuntimeException(String.format("session_id '%s' is invalid", sessionId));
}

if (StringHelper.isEmpty(userName) && StringHelper.isEmpty(keyHandle)) {
throw new Fido2RuntimeException("The request should contains either username or keyhandle");
}

ObjectNode params = dataMapperService.createObjectNode();
// Add all required parameters from request to allow process U2F request
params.put(CommonVerifiers.SUPER_GLUU_REQUEST, true);
params.put(CommonVerifiers.SUPER_GLUU_APP_ID, appId);
params.put(CommonVerifiers.SUPER_GLUU_KEY_HANDLE, keyHandle);
params.put(CommonVerifiers.SUPER_GLUU_MODE, oneStep ? SuperGluuMode.ONE_STEP.getMode() : SuperGluuMode.TWO_STEP.getMode());

params.put("username", userName);
params.put("session_id", sessionId);

log.debug("Prepared U2F_V2 assertions options request: {}", params.toString());
ObjectNode params = buildFido2AssertionStartResponse(userName, keyHandle, appId, sessionId);

ObjectNode result = assertionService.options(params);

Expand All @@ -135,6 +114,33 @@ public JsonNode startAuthentication(String userName, String keyHandle, String ap
return superGluuResult;
}

public ObjectNode buildFido2AssertionStartResponse(String userName, String keyHandle, String appId,
String sessionId) {
boolean oneStep = StringHelper.isEmpty(userName);

boolean valid = userSessionIdService.isValidSessionId(sessionId, userName);
if (!valid) {
throw new Fido2RuntimeException(String.format("session_id '%s' is invalid", sessionId));
}

if (StringHelper.isEmpty(userName) && StringHelper.isEmpty(keyHandle)) {
throw new Fido2RuntimeException("The request should contains either username or keyhandle");
}

ObjectNode params = dataMapperService.createObjectNode();
// Add all required parameters from request to allow process U2F request
params.put(CommonVerifiers.SUPER_GLUU_REQUEST, true);
params.put(CommonVerifiers.SUPER_GLUU_APP_ID, appId);
params.put(CommonVerifiers.SUPER_GLUU_KEY_HANDLE, keyHandle);
params.put(CommonVerifiers.SUPER_GLUU_MODE, oneStep ? SuperGluuMode.ONE_STEP.getMode() : SuperGluuMode.TWO_STEP.getMode());

params.put("username", userName);
params.put("session_id", sessionId);

log.debug("Prepared U2F_V2 assertions options request: {}", params.toString());
return params;
}

/* Example for one_step:
* - request:
* username: null
Expand All @@ -159,14 +165,20 @@ public JsonNode startAuthentication(String userName, String keyHandle, String ap
*
*/
public JsonNode finishAuthentication(String userName, String authenticateResponseString) {
AuthenticateResponse authenticateResponse;
try {
authenticateResponse = dataMapperService.readValue(authenticateResponseString, AuthenticateResponse.class);
} catch (IOException ex) {
throw new Fido2RpRuntimeException("Failed to parse options assertion request", ex);
}
AuthenticateResponse authenticateResponse = parseAuthenticateResponse(authenticateResponseString);

if (!ArrayUtils.contains(RawAuthenticationService.SUPPORTED_AUTHENTICATE_TYPES, authenticateResponse.getClientData().getTyp())) {
ObjectNode params = buildFido2AuthenticationVerifyResponse(userName, authenticateResponseString, authenticateResponse);

ObjectNode result = assertionService.verify(params);

result.put("status", "success");
result.put("challenge", authenticateResponse.getClientData().getChallenge());

return result;
}

public ObjectNode buildFido2AuthenticationVerifyResponse(String userName, String authenticateResponseString, AuthenticateResponse authenticateResponse) {
if (!ArrayUtils.contains(RawAuthenticationService.SUPPORTED_AUTHENTICATE_TYPES, authenticateResponse.getClientData().getTyp())) {
throw new Fido2RuntimeException("Invalid options attestation request type");
}

Expand Down Expand Up @@ -216,14 +228,18 @@ public JsonNode finishAuthentication(String userName, String authenticateRespons
}

log.debug("Prepared U2F_V2 assertion verify request: {}", params.toString());
return params;
}

ObjectNode result = assertionService.verify(params);

result.put("status", "success");
result.put("challenge", authenticateResponse.getClientData().getChallenge());

return result;
}
public AuthenticateResponse parseAuthenticateResponse(String authenticateResponseString) {
AuthenticateResponse authenticateResponse;
try {
authenticateResponse = dataMapperService.readValue(authenticateResponseString, AuthenticateResponse.class);
} catch (IOException ex) {
throw new Fido2RpRuntimeException("Failed to parse options assertion request", ex);
}
return authenticateResponse;
}

private byte[] generateAuthData(ClientData clientData, RawAuthenticateResponse rawAuthenticateResponse) throws IOException {
byte[] rpIdHash = digestService.hashSha256(clientData.getOrigin());
Expand Down

This file was deleted.

Loading