use of io.jans.fido2.exception.Fido2RuntimeException in project jans by JanssenProject.
the class AssertionService method options.
/*
* Requires mandatory parameters: username Support non mandatory parameters:
* userVerification, documentDomain, extensions, timeout
*/
public JsonNode options(JsonNode params) {
log.debug("Assertion options {}", params);
// Verify request parameters
commonVerifiers.verifyAssertionOptions(params);
// Get username
String username = commonVerifiers.verifyThatFieldString(params, "username");
// Create result object
ObjectNode optionsResponseNode = dataMapperService.createObjectNode();
// Put userVerification
UserVerification userVerification = commonVerifiers.prepareUserVerification(params);
optionsResponseNode.put("userVerification", userVerification.name());
// Generate and put challenge
String challenge = challengeGenerator.getChallenge();
optionsResponseNode.put("challenge", challenge);
log.debug("Put challenge {}", challenge);
// Put RP
String documentDomain = commonVerifiers.verifyRpDomain(params);
log.debug("Put rpId {}", documentDomain);
optionsResponseNode.put("rpId", documentDomain);
// TODO: Verify documentDomain
// Put allowCredentials
Pair<ArrayNode, String> allowedCredentialsPair = prepareAllowedCredentials(documentDomain, username);
ArrayNode allowedCredentials = allowedCredentialsPair.getLeft();
if (allowedCredentials.isEmpty()) {
throw new Fido2RuntimeException("Can't find associated key(s). Username: " + username);
}
optionsResponseNode.set("allowCredentials", allowedCredentials);
log.debug("Put allowedCredentials {}", allowedCredentials);
// Copy extensions
if (params.hasNonNull("extensions")) {
JsonNode extensions = params.get("extensions");
optionsResponseNode.set("extensions", extensions);
log.debug("Put extensions {}", extensions);
}
String fidoApplicationId = allowedCredentialsPair.getRight();
if (fidoApplicationId != null) {
if (optionsResponseNode.hasNonNull("extensions")) {
ObjectNode extensions = (ObjectNode) optionsResponseNode.get("extensions");
extensions.put("appid", fidoApplicationId);
} else {
ObjectNode extensions = dataMapperService.createObjectNode();
extensions.put("appid", fidoApplicationId);
optionsResponseNode.set("extensions", extensions);
}
}
// optionsResponseNode.put("status", "ok");
// optionsResponseNode.put("errorMessage", "");
Fido2AuthenticationData entity = new Fido2AuthenticationData();
entity.setUsername(username);
entity.setChallenge(challenge);
entity.setDomain(documentDomain);
entity.setUserVerificationOption(userVerification);
entity.setStatus(Fido2AuthenticationStatus.pending);
// Store original request
entity.setAssertionRequest(params.toString());
authenticationPersistenceService.save(entity);
return optionsResponseNode;
}
use of io.jans.fido2.exception.Fido2RuntimeException in project jans by JanssenProject.
the class AuthenticationPersistenceService method save.
public void save(Fido2AuthenticationData authenticationData) {
String userName = authenticationData.getUsername();
User user = userService.getUser(userName, "inum");
if (user == null) {
if (appConfiguration.getFido2Configuration().isUserAutoEnrollment()) {
user = userService.addDefaultUser(userName);
} else {
throw new Fido2RuntimeException("Auto user enrollment was disabled. User not exists!");
}
}
String userInum = userService.getUserInum(user);
prepareBranch(userInum);
Date now = new GregorianCalendar(TimeZone.getTimeZone("UTC")).getTime();
final String id = UUID.randomUUID().toString();
String dn = getDnForAuthenticationEntry(userInum, id);
Fido2AuthenticationEntry authenticationEntity = new Fido2AuthenticationEntry(dn, authenticationData.getId(), now, userInum, authenticationData);
authenticationEntity.setAuthenticationStatus(authenticationData.getStatus());
authenticationData.setCreatedDate(now);
authenticationData.setCreatedBy(userName);
persistenceEntryManager.persist(authenticationEntity);
}
use of io.jans.fido2.exception.Fido2RuntimeException in project jans by JanssenProject.
the class AppleAssertionFormatProcessor method process.
@Override
public void process(String base64AuthenticatorData, String signature, String clientDataJson, Fido2RegistrationData registration, Fido2AuthenticationData authenticationEntity) {
AuthData authData = authenticatorDataParser.parseAssertionData(base64AuthenticatorData);
commonVerifiers.verifyRpIdHash(authData, registration.getDomain());
log.info("User verification option {}", authenticationEntity.getUserVerificationOption());
userVerificationVerifier.verifyUserVerificationOption(authenticationEntity.getUserVerificationOption(), authData);
byte[] clientDataHash = DigestUtils.getSha256Digest().digest(base64Service.urlDecode(clientDataJson));
try {
int counter = authenticatorDataParser.parseCounter(authData.getCounters());
commonVerifiers.verifyCounter(registration.getCounter(), counter);
registration.setCounter(counter);
JsonNode uncompressedECPointNode = dataMapperService.cborReadTree(base64Service.urlDecode(registration.getUncompressedECPoint()));
PublicKey publicKey = coseService.createUncompressedPointFromCOSEPublicKey(uncompressedECPointNode);
log.info("Uncompressed ECpoint node {}", uncompressedECPointNode.toString());
log.info("EC Public key hex {}", Hex.encodeHexString(publicKey.getEncoded()));
log.info("Signature algorithm: " + registration.getSignatureAlgorithm());
// Note : The signature counter is not implemented and therefore it is always
// zero. Secure Enclave is used to prevent the credential private key from
// leaking instead of a software safeguard.
log.info("Key type / Algorithm : " + authData.getKeyType());
// authData.getKeyType());
authenticatorDataVerifier.verifyAssertionSignature(authData, clientDataHash, signature, publicKey, -7);
} catch (Fido2CompromisedDevice ex) {
throw ex;
} catch (Exception ex) {
throw new Fido2RuntimeException("Failed to check packet assertion", ex);
}
}
use of io.jans.fido2.exception.Fido2RuntimeException in project jans by JanssenProject.
the class PackedAssertionFormatProcessor method process.
@Override
public void process(String base64AuthenticatorData, String signature, String clientDataJson, Fido2RegistrationData registration, Fido2AuthenticationData authenticationEntity) {
AuthData authData = authenticatorDataParser.parseAssertionData(base64AuthenticatorData);
commonVerifiers.verifyRpIdHash(authData, registration.getDomain());
log.debug("User verification option {}", authenticationEntity.getUserVerificationOption());
userVerificationVerifier.verifyUserVerificationOption(authenticationEntity.getUserVerificationOption(), authData);
byte[] clientDataHash = DigestUtils.getSha256Digest().digest(base64Service.urlDecode(clientDataJson));
try {
int counter = authenticatorDataParser.parseCounter(authData.getCounters());
commonVerifiers.verifyCounter(registration.getCounter(), counter);
registration.setCounter(counter);
JsonNode uncompressedECPointNode = dataMapperService.cborReadTree(base64Service.urlDecode(registration.getUncompressedECPoint()));
PublicKey publicKey = coseService.createUncompressedPointFromCOSEPublicKey(uncompressedECPointNode);
log.debug("Uncompressed ECpoint node {}", uncompressedECPointNode.toString());
log.debug("EC Public key hex {}", Hex.encodeHexString(publicKey.getEncoded()));
// apple algorithm = -7
// windows hello algorithm is -257
log.debug("registration.getSignatureAlgorithm(): " + registration.getSignatureAlgorithm());
log.debug("Platform authenticator: " + String.valueOf(registration.getAttenstationRequest().contains(AuthenticatorAttachment.PLATFORM.getAttachment()) ? -7 : registration.getSignatureAlgorithm()));
authenticatorDataVerifier.verifyAssertionSignature(authData, clientDataHash, signature, publicKey, registration.getAttenstationRequest().contains(AuthenticatorAttachment.PLATFORM.getAttachment()) ? -7 : registration.getSignatureAlgorithm());
} catch (Fido2CompromisedDevice ex) {
throw ex;
} catch (Exception ex) {
throw new Fido2RuntimeException("Failed to check packet assertion", ex);
}
}
use of io.jans.fido2.exception.Fido2RuntimeException in project jans by JanssenProject.
the class AssertionVerifier method verifyAuthenticatorAssertionResponse.
public void verifyAuthenticatorAssertionResponse(JsonNode response, Fido2RegistrationData registration, Fido2AuthenticationData authenticationEntity) {
if (!(response.hasNonNull("authenticatorData") && response.hasNonNull("clientDataJSON") && response.hasNonNull("signature"))) {
throw new Fido2RuntimeException("Authenticator data is invalid");
}
String base64AuthenticatorData = response.get("authenticatorData").asText();
String clientDataJson = response.get("clientDataJSON").asText();
String signature = response.get("signature").asText();
log.debug("Authenticator data {}", base64AuthenticatorData);
AssertionFormatProcessor assertionProcessor = assertionProcessorFactory.getCommandProcessor(registration.getAttestationType());
assertionProcessor.process(base64AuthenticatorData, signature, clientDataJson, registration, authenticationEntity);
}
Aggregations