Skip to content

Commit

Permalink
reuse a single SecureRandom instance
Browse files Browse the repository at this point in the history
  • Loading branch information
thestinger committed Sep 27, 2024
1 parent 2fb7171 commit 7ee59af
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions app/src/main/java/app/attestation/auditor/AttestationProtocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class AttestationProtocol {
private static final String KEY_VERIFIED_TIME_FIRST = "verified_time_first";
private static final String KEY_VERIFIED_TIME_LAST = "verified_time_last";

private static final int CHALLENGE_LENGTH = 32;
private static final int RANDOM_TOKEN_LENGTH = 32;
static final String EC_CURVE = "secp256r1";
private static final String SIGNATURE_ALGORITHM = "SHA256WithECDSA";
static final String KEY_DIGEST = DIGEST_SHA256;
Expand All @@ -119,8 +119,8 @@ class AttestationProtocol {
// Challenge message:
//
// byte maxVersion = PROTOCOL_VERSION
// byte[] challenge index (length: CHALLENGE_LENGTH)
// byte[] challenge (length: CHALLENGE_LENGTH)
// byte[] challenge index (length: RANDOM_TOKEN_LENGTH)
// byte[] challenge (length: RANDOM_TOKEN_LENGTH)
//
// The challenge index is randomly generated by Auditor and used for all future challenge
// messages from that Auditor. It's used on the Auditee as an index to choose the correct
Expand Down Expand Up @@ -193,7 +193,7 @@ class AttestationProtocol {
private static final byte PROTOCOL_VERSION = 5;
private static final byte PROTOCOL_VERSION_MINIMUM = 5;
// can become longer in the future, but this is the minimum length
static final byte CHALLENGE_MESSAGE_LENGTH = 1 + CHALLENGE_LENGTH * 2;
static final byte CHALLENGE_MESSAGE_LENGTH = 1 + RANDOM_TOKEN_LENGTH * 2;
private static final int MAX_ENCODED_CHAIN_LENGTH = 5000;
private static final int MAX_MESSAGE_SIZE = 2953;

Expand Down Expand Up @@ -511,23 +511,24 @@ private static byte[] getChallengeIndex(final Context context) {
if (challengeIndexSerialized != null) {
return BaseEncoding.base64().decode(challengeIndexSerialized);
} else {
final byte[] challengeIndex = getChallenge();
final byte[] challengeIndex = getRandomToken();
global.edit()
.putString(KEY_CHALLENGE_INDEX, BaseEncoding.base64().encode(challengeIndex))
.apply();
return challengeIndex;
}
}

private static byte[] getChallenge() {
final SecureRandom random = new SecureRandom();
final byte[] challenge = new byte[CHALLENGE_LENGTH];
private static final SecureRandom random = new SecureRandom();

private static byte[] getRandomToken() {
final byte[] challenge = new byte[RANDOM_TOKEN_LENGTH];
random.nextBytes(challenge);
return challenge;
}

static byte[] getChallengeMessage(final Context context) {
return Bytes.concat(new byte[]{PROTOCOL_VERSION}, getChallengeIndex(context), getChallenge());
return Bytes.concat(new byte[]{PROTOCOL_VERSION}, getChallengeIndex(context), getRandomToken());
}

private static byte[] getFingerprint(final Certificate certificate)
Expand Down Expand Up @@ -1233,7 +1234,7 @@ static VerificationResult verifySerialized(final Context context, final byte[] a
deserializer.rewind();
deserializer.limit(deserializer.capacity() - signature.length);

final byte[] challenge = Arrays.copyOfRange(challengeMessage, 1 + CHALLENGE_LENGTH, 1 + CHALLENGE_LENGTH * 2);
final byte[] challenge = Arrays.copyOfRange(challengeMessage, 1 + RANDOM_TOKEN_LENGTH, 1 + RANDOM_TOKEN_LENGTH * 2);
return verify(context, fingerprint, challenge, deserializer.asReadOnlyBuffer(), signature,
certificates, userProfileSecure, accessibility, deviceAdmin, deviceAdminNonSystem,
adbEnabled, addUsersWhenLocked, enrolledBiometrics, denyNewUsb, oemUnlockAllowed,
Expand Down Expand Up @@ -1314,8 +1315,8 @@ static AttestationResult generateSerialized(final Context context, final byte[]
throw new GeneralSecurityException("Auditor protocol version too old: " + maxVersion);
}
final byte version = (byte) Math.min(PROTOCOL_VERSION, maxVersion);
final byte[] challengeIndex = Arrays.copyOfRange(challengeMessage, 1, 1 + CHALLENGE_LENGTH);
final byte[] challenge = Arrays.copyOfRange(challengeMessage, 1 + CHALLENGE_LENGTH, 1 + CHALLENGE_LENGTH * 2);
final byte[] challengeIndex = Arrays.copyOfRange(challengeMessage, 1, 1 + RANDOM_TOKEN_LENGTH);
final byte[] challenge = Arrays.copyOfRange(challengeMessage, 1 + RANDOM_TOKEN_LENGTH, 1 + RANDOM_TOKEN_LENGTH * 2);

final KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
Expand Down

0 comments on commit 7ee59af

Please sign in to comment.