use of org.xdi.oxauth.model.fido.u2f.exception.BadInputException in project oxAuth by GluuFederation.
the class RegistrationService method finishRegistration.
public DeviceRegistrationResult finishRegistration(RegisterRequestMessage requestMessage, RegisterResponse response, String userInum, Set<String> facets) throws BadInputException {
RegisterRequest request = requestMessage.getRegisterRequest();
String appId = request.getAppId();
ClientData clientData = response.getClientData();
clientDataValidationService.checkContent(clientData, RawRegistrationService.SUPPORTED_REGISTER_TYPES, request.getChallenge(), facets);
RawRegisterResponse rawRegisterResponse = rawRegistrationService.parseRawRegisterResponse(response.getRegistrationData());
rawRegistrationService.checkSignature(appId, clientData, rawRegisterResponse);
Date now = new GregorianCalendar(TimeZone.getTimeZone("UTC")).getTime();
DeviceRegistration deviceRegistration = rawRegistrationService.createDevice(rawRegisterResponse);
deviceRegistration.setStatus(DeviceRegistrationStatus.ACTIVE);
deviceRegistration.setApplication(appId);
deviceRegistration.setCreationDate(now);
int keyHandleHashCode = deviceRegistrationService.getKeyHandleHashCode(rawRegisterResponse.getKeyHandle());
deviceRegistration.setKeyHandleHashCode(keyHandleHashCode);
final String deviceRegistrationId = String.valueOf(System.currentTimeMillis());
deviceRegistration.setId(deviceRegistrationId);
String responseDeviceData = response.getDeviceData();
if (StringHelper.isNotEmpty(responseDeviceData)) {
try {
String responseDeviceDataDecoded = new String(Base64Util.base64urldecode(responseDeviceData));
DeviceData deviceData = ServerUtil.jsonMapperWithWrapRoot().readValue(responseDeviceDataDecoded, DeviceData.class);
deviceRegistration.setDeviceData(deviceData);
} catch (Exception ex) {
throw new BadInputException(String.format("Device data is invalid: %s", responseDeviceData), ex);
}
}
boolean approved = StringHelper.equals(RawRegistrationService.REGISTER_FINISH_TYPE, response.getClientData().getTyp());
if (!approved) {
log.debug("Registratio request with keyHandle '{}' was canceled", rawRegisterResponse.getKeyHandle());
return new DeviceRegistrationResult(deviceRegistration, DeviceRegistrationResult.Status.CANCELED);
}
boolean twoStep = StringHelper.isNotEmpty(userInum);
if (twoStep) {
deviceRegistration.setDn(deviceRegistrationService.getDnForU2fDevice(userInum, deviceRegistrationId));
// Check if there is device registration with keyHandle in LDAP already
List<DeviceRegistration> foundDeviceRegistrations = deviceRegistrationService.findDeviceRegistrationsByKeyHandle(appId, deviceRegistration.getKeyHandle(), "oxId");
if (foundDeviceRegistrations.size() != 0) {
throw new BadInputException(String.format("KeyHandle %s was compromised", deviceRegistration.getKeyHandle()));
}
deviceRegistrationService.addUserDeviceRegistration(userInum, deviceRegistration);
} else {
deviceRegistration.setDn(deviceRegistrationService.getDnForOneStepU2fDevice(deviceRegistrationId));
deviceRegistrationService.addOneStepDeviceRegistration(deviceRegistration);
}
return new DeviceRegistrationResult(deviceRegistration, DeviceRegistrationResult.Status.APPROVED);
}
use of org.xdi.oxauth.model.fido.u2f.exception.BadInputException in project oxAuth by GluuFederation.
the class RawAuthenticationService method checkSignature.
public void checkSignature(String appId, ClientData clientData, RawAuthenticateResponse rawAuthenticateResponse, byte[] publicKey) throws BadInputException {
String rawClientData = clientData.getRawClientData();
byte[] signedBytes = packBytesToSign(signatureVerification.hash(appId), rawAuthenticateResponse.getUserPresence(), rawAuthenticateResponse.getCounter(), signatureVerification.hash(rawClientData));
try {
signatureVerification.checkSignature(signatureVerification.decodePublicKey(publicKey), signedBytes, rawAuthenticateResponse.getSignature());
} catch (SignatureException ex) {
throw new BadInputException("Failed to checkSignature", ex);
}
}
use of org.xdi.oxauth.model.fido.u2f.exception.BadInputException in project oxAuth by GluuFederation.
the class RawRegistrationService method checkSignature.
public void checkSignature(String appId, ClientData clientData, RawRegisterResponse rawRegisterResponse) throws BadInputException {
String rawClientData = clientData.getRawClientData();
byte[] signedBytes = packBytesToSign(signatureVerification.hash(appId), signatureVerification.hash(rawClientData), rawRegisterResponse.getKeyHandle(), rawRegisterResponse.getUserPublicKey());
try {
signatureVerification.checkSignature(rawRegisterResponse.getAttestationCertificate(), signedBytes, rawRegisterResponse.getSignature());
} catch (SignatureException ex) {
throw new BadInputException("Failed to checkSignature", ex);
}
}
use of org.xdi.oxauth.model.fido.u2f.exception.BadInputException in project oxAuth by GluuFederation.
the class ClientDataValidationService method checkContent.
public void checkContent(ClientData clientData, String[] types, String challenge, Set<String> facets) throws BadInputException {
if (!ArrayUtils.contains(types, clientData.getTyp())) {
throw new BadInputException("Bad clientData: wrong typ " + clientData.getTyp());
}
if (!challenge.equals(clientData.getChallenge())) {
throw new BadInputException("Bad clientData: wrong challenge");
}
if (facets != null && !facets.isEmpty()) {
Set<String> allowedFacets = canonicalizeOrigins(facets);
String canonicalOrigin;
try {
canonicalOrigin = canonicalizeOrigin(clientData.getOrigin());
} catch (RuntimeException e) {
throw new BadInputException("Bad clientData: Malformed origin", e);
}
verifyOrigin(canonicalOrigin, allowedFacets);
}
}
use of org.xdi.oxauth.model.fido.u2f.exception.BadInputException in project oxAuth by GluuFederation.
the class U2fAuthenticationWS method startAuthentication.
@GET
@Produces({ "application/json" })
public Response startAuthentication(@QueryParam("username") String userName, @QueryParam("keyhandle") String keyHandle, @QueryParam("application") String appId, @QueryParam("session_state") String sessionState) {
// Parameter username is deprecated. We uses it only to determine is it's one or two step workflow
try {
log.debug("Startig authentication with username '{}', keyhandle '{}' for appId '{}' and session_state '{}'", userName, keyHandle, appId, sessionState);
if (StringHelper.isEmpty(userName) && StringHelper.isEmpty(keyHandle)) {
throw new BadInputException(String.format("The request should contains either username or keyhandle"));
}
String foundUserInum = null;
boolean twoStep = StringHelper.isNotEmpty(userName);
if (twoStep) {
boolean valid = u2fValidationService.isValidSessionState(userName, sessionState);
if (!valid) {
throw new BadInputException(String.format("session_state '%s' is invalid", sessionState));
}
foundUserInum = userService.getUserInum(userName);
} else {
// Convert to non padding URL base64 string
String keyHandleWithoutPading = Base64Util.base64urlencode(Base64Util.base64urldecode(keyHandle));
// In one step we expects empty username and not empty keyhandle
foundUserInum = u2fAuthenticationService.getUserInumByKeyHandle(appId, keyHandleWithoutPading);
}
if (StringHelper.isEmpty(foundUserInum)) {
throw new BadInputException(String.format("Failed to find user by userName '%s' or keyHandle '%s' in LDAP", userName, keyHandle));
}
AuthenticateRequestMessage authenticateRequestMessage = u2fAuthenticationService.buildAuthenticateRequestMessage(appId, foundUserInum);
u2fAuthenticationService.storeAuthenticationRequestMessage(authenticateRequestMessage, foundUserInum, sessionState);
// convert manually to avoid possible conflict between resteasy
// providers, e.g. jettison, jackson
final String entity = ServerUtil.asJson(authenticateRequestMessage);
return Response.status(Response.Status.OK).entity(entity).cacheControl(ServerUtil.cacheControl(true)).build();
} catch (Exception ex) {
log.error("Exception happened", ex);
if (ex instanceof WebApplicationException) {
throw (WebApplicationException) ex;
}
if ((ex instanceof NoEligableDevicesException) || (ex instanceof InvalidKeyHandleDeviceException)) {
throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).entity(errorResponseFactory.getErrorResponse(U2fErrorResponseType.NO_ELIGABLE_DEVICES)).build());
}
throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorResponseFactory.getJsonErrorResponse(U2fErrorResponseType.SERVER_ERROR)).build());
}
}
Aggregations