use of com.google.u2f.key.messages.AuthenticateResponse in project OpenUnison by TremoloSecurity.
the class U2FServerReferenceImpl method processSignResponse.
@Override
public SecurityKeyData processSignResponse(SignResponse signResponse) throws U2FException {
Log.info(">> processSignResponse");
String sessionId = signResponse.getSessionId();
String browserDataBase64 = signResponse.getClientData();
String rawSignDataBase64 = signResponse.getSignatureData();
SignSessionData sessionData = dataStore.getSignSessionData(sessionId);
if (sessionData == null) {
throw new U2FException("Unknown session_id");
}
String appId = sessionData.getAppId();
SecurityKeyData securityKeyData = null;
for (SecurityKeyData temp : dataStore.getSecurityKeyData(sessionData.getAccountName())) {
if (Arrays.equals(sessionData.getPublicKey(), temp.getPublicKey())) {
securityKeyData = temp;
break;
}
}
if (securityKeyData == null) {
throw new U2FException("No security keys registered for this user");
}
String browserData = new String(Base64.decodeBase64(browserDataBase64));
byte[] rawSignData = Base64.decodeBase64(rawSignDataBase64);
Log.info("-- Input --");
Log.info(" sessionId: " + sessionId);
Log.info(" publicKey: " + Hex.encodeHexString(securityKeyData.getPublicKey()));
Log.info(" challenge: " + Hex.encodeHexString(sessionData.getChallenge()));
Log.info(" accountName: " + sessionData.getAccountName());
Log.info(" browserData: " + browserData);
Log.info(" rawSignData: " + Hex.encodeHexString(rawSignData));
verifyBrowserData(new JsonParser().parse(browserData), "navigator.id.getAssertion", sessionData);
AuthenticateResponse authenticateResponse = RawMessageCodec.decodeAuthenticateResponse(rawSignData);
byte userPresence = authenticateResponse.getUserPresence();
int counter = authenticateResponse.getCounter();
byte[] signature = authenticateResponse.getSignature();
Log.info("-- Parsed rawSignData --");
Log.info(" userPresence: " + Integer.toHexString(userPresence & 0xFF));
Log.info(" counter: " + counter);
Log.info(" signature: " + Hex.encodeHexString(signature));
if ((userPresence & UserPresenceVerifier.USER_PRESENT_FLAG) == 0) {
throw new U2FException("User presence invalid during authentication");
}
if (counter <= securityKeyData.getCounter()) {
throw new U2FException("Counter value smaller than expected!");
}
byte[] appIdSha256 = crypto.computeSha256(appId.getBytes());
byte[] browserDataSha256 = crypto.computeSha256(browserData.getBytes());
byte[] signedBytes = RawMessageCodec.encodeAuthenticateSignedBytes(appIdSha256, userPresence, counter, browserDataSha256);
Log.info("Verifying signature of bytes " + Hex.encodeHexString(signedBytes));
if (!crypto.verifySignature(crypto.decodePublicKey(securityKeyData.getPublicKey()), signedBytes, signature)) {
throw new U2FException("Signature is invalid");
}
dataStore.updateSecurityKeyCounter(sessionData.getAccountName(), securityKeyData.getPublicKey(), counter);
Log.info("<< processSignResponse");
return securityKeyData;
}
use of com.google.u2f.key.messages.AuthenticateResponse in project OpenUnison by TremoloSecurity.
the class RawMessageCodec method decodeAuthenticateResponse.
public static AuthenticateResponse decodeAuthenticateResponse(byte[] data) throws U2FException {
try {
DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(data));
byte userPresence = inputStream.readByte();
int counter = inputStream.readInt();
byte[] signature = new byte[inputStream.available()];
inputStream.readFully(signature);
if (inputStream.available() != 0) {
throw new U2FException("Message ends with unexpected data");
}
return new AuthenticateResponse(userPresence, counter, signature);
} catch (IOException e) {
throw new U2FException("Error when parsing raw AuthenticateResponse", e);
}
}
use of com.google.u2f.key.messages.AuthenticateResponse in project OpenUnison by TremoloSecurity.
the class U2FServerUnison method processSignResponse.
@Override
public SecurityKeyData processSignResponse(SignResponse signResponse) throws U2FException {
if (log.isDebugEnabled()) {
log.debug(">> processSignResponse");
}
String sessionId = signResponse.getSessionId();
String browserDataBase64 = signResponse.getClientData();
String rawSignDataBase64 = signResponse.getSignatureData();
SignSessionData sessionData = dataStore.getSignSessionData(sessionId);
if (sessionData == null) {
throw new U2FException("Unknown session_id");
}
String appId = sessionData.getAppId();
SecurityKeyData securityKeyData = null;
for (SecurityKeyData temp : dataStore.getSecurityKeyData(sessionData.getAccountName())) {
if (Arrays.equals(sessionData.getPublicKey(), temp.getPublicKey())) {
securityKeyData = temp;
break;
}
}
if (securityKeyData == null) {
throw new U2FException("No security keys registered for this user");
}
String browserData = new String(Base64.decodeBase64(browserDataBase64));
byte[] rawSignData = Base64.decodeBase64(rawSignDataBase64);
if (log.isDebugEnabled()) {
log.debug("-- Input --");
log.debug(" sessionId: " + sessionId);
log.debug(" publicKey: " + Hex.encodeHexString(securityKeyData.getPublicKey()));
log.debug(" challenge: " + Hex.encodeHexString(sessionData.getChallenge()));
log.debug(" accountName: " + sessionData.getAccountName());
log.debug(" browserData: " + browserData);
log.debug(" rawSignData: " + Hex.encodeHexString(rawSignData));
}
verifyBrowserData(new JsonParser().parse(browserData), "navigator.id.getAssertion", sessionData);
AuthenticateResponse authenticateResponse = RawMessageCodec.decodeAuthenticateResponse(rawSignData);
byte userPresence = authenticateResponse.getUserPresence();
int counter = authenticateResponse.getCounter();
byte[] signature = authenticateResponse.getSignature();
if (log.isDebugEnabled()) {
log.debug("-- Parsed rawSignData --");
log.debug(" userPresence: " + Integer.toHexString(userPresence & 0xFF));
log.debug(" counter: " + counter);
log.debug(" signature: " + Hex.encodeHexString(signature));
}
if ((userPresence & UserPresenceVerifier.USER_PRESENT_FLAG) == 0) {
throw new U2FException("User presence invalid during authentication");
}
if (counter <= securityKeyData.getCounter()) {
throw new U2FException("Counter value smaller than expected!");
}
byte[] appIdSha256 = crypto.computeSha256(appId.getBytes());
byte[] browserDataSha256 = crypto.computeSha256(browserData.getBytes());
byte[] signedBytes = RawMessageCodec.encodeAuthenticateSignedBytes(appIdSha256, userPresence, counter, browserDataSha256);
if (log.isDebugEnabled()) {
log.debug("Verifying signature of bytes " + Hex.encodeHexString(signedBytes));
}
if (!crypto.verifySignature(crypto.decodePublicKey(securityKeyData.getPublicKey()), signedBytes, signature)) {
throw new U2FException("Signature is invalid");
}
dataStore.updateSecurityKeyCounter(sessionData.getAccountName(), securityKeyData.getPublicKey(), counter);
if (log.isDebugEnabled()) {
log.debug("<< processSignResponse");
}
return securityKeyData;
}
use of com.google.u2f.key.messages.AuthenticateResponse in project OpenUnison by TremoloSecurity.
the class U2FKeyReferenceImpl method authenticate.
@Override
public AuthenticateResponse authenticate(AuthenticateRequest authenticateRequest) throws U2FException {
Log.info(">> authenticate");
byte control = authenticateRequest.getControl();
byte[] applicationSha256 = authenticateRequest.getApplicationSha256();
byte[] challengeSha256 = authenticateRequest.getChallengeSha256();
byte[] keyHandle = authenticateRequest.getKeyHandle();
Log.info(" -- Inputs --");
Log.info(" control: " + control);
Log.info(" applicationSha256: " + Hex.encodeHexString(applicationSha256));
Log.info(" challengeSha256: " + Hex.encodeHexString(challengeSha256));
Log.info(" keyHandle: " + Hex.encodeHexString(keyHandle));
KeyPair keyPair = dataStore.getKeyPair(keyHandle);
int counter = dataStore.incrementCounter();
byte userPresence = userPresenceVerifier.verifyUserPresence();
byte[] signedData = RawMessageCodec.encodeAuthenticateSignedBytes(applicationSha256, userPresence, counter, challengeSha256);
Log.info("Signing bytes " + Hex.encodeHexString(signedData));
byte[] signature = crypto.sign(signedData, keyPair.getPrivate());
Log.info(" -- Outputs --");
Log.info(" userPresence: " + userPresence);
Log.info(" counter: " + counter);
Log.info(" signature: " + Hex.encodeHexString(signature));
Log.info("<< authenticate");
return new AuthenticateResponse(userPresence, counter, signature);
}
Aggregations