resolve merge conflicts of 2ff6320d77 to oc-dr1-dev

Change-Id: I3711119a6cbba1b697ad379a8520b73023c27edb
This commit is contained in:
Rubin Xu
2017-12-04 11:32:48 +00:00
2 changed files with 38 additions and 10 deletions

View File

@@ -112,7 +112,7 @@ public class SyntheticPasswordCrypto {
} }
} }
public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) { public static byte[] decryptBlobV1(String keyAlias, byte[] blob, byte[] applicationId) {
try { try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null); keyStore.load(null);
@@ -120,6 +120,20 @@ public class SyntheticPasswordCrypto {
SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null); SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob); byte[] intermediate = decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, blob);
return decrypt(decryptionKey, intermediate); return decrypt(decryptionKey, intermediate);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to decrypt blob", e);
}
}
public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey decryptionKey = (SecretKey) keyStore.getKey(keyAlias, null);
byte[] intermediate = decrypt(decryptionKey, blob);
return decrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate);
} catch (CertificateException | IOException | BadPaddingException } catch (CertificateException | IOException | BadPaddingException
| IllegalBlockSizeException | IllegalBlockSizeException
| KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException
@@ -150,9 +164,8 @@ public class SyntheticPasswordCrypto {
keyStore.setEntry(keyAlias, keyStore.setEntry(keyAlias,
new KeyStore.SecretKeyEntry(secretKey), new KeyStore.SecretKeyEntry(secretKey),
builder.build()); builder.build());
byte[] intermediate = encrypt(secretKey, data); byte[] intermediate = encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, data);
return encrypt(applicationId, APPLICATION_ID_PERSONALIZATION, intermediate); return encrypt(secretKey, intermediate);
} catch (CertificateException | IOException | BadPaddingException } catch (CertificateException | IOException | BadPaddingException
| IllegalBlockSizeException | IllegalBlockSizeException
| KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException | KeyStoreException | NoSuchPaddingException | NoSuchAlgorithmException

View File

@@ -99,7 +99,8 @@ public class SyntheticPasswordManager {
private static final byte WEAVER_VERSION = 1; private static final byte WEAVER_VERSION = 1;
private static final int INVALID_WEAVER_SLOT = -1; private static final int INVALID_WEAVER_SLOT = -1;
private static final byte SYNTHETIC_PASSWORD_VERSION = 1; private static final byte SYNTHETIC_PASSWORD_VERSION_V1 = 1;
private static final byte SYNTHETIC_PASSWORD_VERSION = 2;
private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0; private static final byte SYNTHETIC_PASSWORD_PASSWORD_BASED = 0;
private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1; private static final byte SYNTHETIC_PASSWORD_TOKEN_BASED = 1;
@@ -765,6 +766,7 @@ public class SyntheticPasswordManager {
byte[] pwdToken = computePasswordToken(credential, pwd); byte[] pwdToken = computePasswordToken(credential, pwd);
final byte[] applicationId; final byte[] applicationId;
final long sid;
int weaverSlot = loadWeaverSlot(handle, userId); int weaverSlot = loadWeaverSlot(handle, userId);
if (weaverSlot != INVALID_WEAVER_SLOT) { if (weaverSlot != INVALID_WEAVER_SLOT) {
// Weaver based user password // Weaver based user password
@@ -777,6 +779,7 @@ public class SyntheticPasswordManager {
if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { if (result.gkResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
return result; return result;
} }
sid = GateKeeper.INVALID_SECURE_USER_ID;
applicationId = transformUnderWeaverSecret(pwdToken, result.gkResponse.getPayload()); applicationId = transformUnderWeaverSecret(pwdToken, result.gkResponse.getPayload());
} else { } else {
byte[] gkPwdToken = passwordTokenToGkInput(pwdToken); byte[] gkPwdToken = passwordTokenToGkInput(pwdToken);
@@ -809,12 +812,13 @@ public class SyntheticPasswordManager {
result.gkResponse = VerifyCredentialResponse.ERROR; result.gkResponse = VerifyCredentialResponse.ERROR;
return result; return result;
} }
sid = sidFromPasswordHandle(pwd.passwordHandle);
applicationId = transformUnderSecdiscardable(pwdToken, applicationId = transformUnderSecdiscardable(pwdToken,
loadSecdiscardable(handle, userId)); loadSecdiscardable(handle, userId));
} }
result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED, result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_PASSWORD_BASED,
applicationId, userId); applicationId, sid, userId);
// Perform verifyChallenge to refresh auth tokens for GK if user password exists. // Perform verifyChallenge to refresh auth tokens for GK if user password exists.
result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId); result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
@@ -850,7 +854,7 @@ public class SyntheticPasswordManager {
} }
byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable); byte[] applicationId = transformUnderSecdiscardable(token, secdiscardable);
result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED, result.authToken = unwrapSyntheticPasswordBlob(handle, SYNTHETIC_PASSWORD_TOKEN_BASED,
applicationId, userId); applicationId, 0L, userId);
if (result.authToken != null) { if (result.authToken != null) {
result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId); result.gkResponse = verifyChallenge(gatekeeper, result.authToken, 0L, userId);
if (result.gkResponse == null) { if (result.gkResponse == null) {
@@ -865,19 +869,26 @@ public class SyntheticPasswordManager {
} }
private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type, private AuthenticationToken unwrapSyntheticPasswordBlob(long handle, byte type,
byte[] applicationId, int userId) { byte[] applicationId, long sid, int userId) {
byte[] blob = loadState(SP_BLOB_NAME, handle, userId); byte[] blob = loadState(SP_BLOB_NAME, handle, userId);
if (blob == null) { if (blob == null) {
return null; return null;
} }
if (blob[0] != SYNTHETIC_PASSWORD_VERSION) { final byte version = blob[0];
if (version != SYNTHETIC_PASSWORD_VERSION && version != SYNTHETIC_PASSWORD_VERSION_V1) {
throw new RuntimeException("Unknown blob version"); throw new RuntimeException("Unknown blob version");
} }
if (blob[1] != type) { if (blob[1] != type) {
throw new RuntimeException("Invalid blob type"); throw new RuntimeException("Invalid blob type");
} }
byte[] secret = decryptSPBlob(getHandleName(handle), final byte[] secret;
if (version == SYNTHETIC_PASSWORD_VERSION_V1) {
secret = SyntheticPasswordCrypto.decryptBlobV1(getHandleName(handle),
Arrays.copyOfRange(blob, 2, blob.length), applicationId); Arrays.copyOfRange(blob, 2, blob.length), applicationId);
} else {
secret = decryptSPBlob(getHandleName(handle),
Arrays.copyOfRange(blob, 2, blob.length), applicationId);
}
if (secret == null) { if (secret == null) {
Log.e(TAG, "Fail to decrypt SP for user " + userId); Log.e(TAG, "Fail to decrypt SP for user " + userId);
return null; return null;
@@ -892,6 +903,10 @@ public class SyntheticPasswordManager {
} else { } else {
result.syntheticPassword = new String(secret); result.syntheticPassword = new String(secret);
} }
if (version == SYNTHETIC_PASSWORD_VERSION_V1) {
Log.i(TAG, "Upgrade v1 SP blob for user " + userId + ", type = " + type);
createSyntheticPasswordBlob(handle, type, result, applicationId, sid, userId);
}
return result; return result;
} }