mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-05-19 11:34:57 +08:00
Add double hash checking support for code signing (#1005)
Add double hash checking support for code signing for both android and ios SDK
This commit is contained in:
@@ -257,7 +257,8 @@ public class CodePushUpdateManager {
|
||||
|
||||
if (isSignatureVerificationEnabled) {
|
||||
if (isSignatureAppearedInBundle) {
|
||||
CodePushUpdateUtils.verifySignature(newUpdateFolderPath, stringPublicKey);
|
||||
CodePushUpdateUtils.verifyFolderHash(newUpdateFolderPath, newUpdateHash);
|
||||
CodePushUpdateUtils.verifyUpdateSignature(newUpdateFolderPath, newUpdateHash, stringPublicKey);
|
||||
} else {
|
||||
throw new CodePushInvalidUpdateException(
|
||||
"Error! Public key was provided but there is no JWT signature within app bundle to verify. " +
|
||||
|
||||
@@ -176,6 +176,8 @@ public class CodePushUpdateUtils {
|
||||
if (!expectedHash.equals(updateContentsManifestHash)) {
|
||||
throw new CodePushInvalidUpdateException("The update contents failed the data integrity check.");
|
||||
}
|
||||
|
||||
CodePushUtils.log("The update contents succeeded the data integrity check.");
|
||||
}
|
||||
|
||||
public static Map<String, Object> verifyAndDecodeJWT(String jwt, PublicKey publicKey) {
|
||||
@@ -184,7 +186,7 @@ public class CodePushUpdateUtils {
|
||||
JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey)publicKey);
|
||||
if (signedJWT.verify(verifier)) {
|
||||
Map<String, Object> claims = signedJWT.getJWTClaimsSet().getClaims();
|
||||
CodePushUtils.log("JWT verification succeeded:\n" + claims.toString());
|
||||
CodePushUtils.log("JWT verification succeeded, payload content: " + claims.toString());
|
||||
return claims;
|
||||
}
|
||||
return null;
|
||||
@@ -233,7 +235,7 @@ public class CodePushUpdateUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void verifySignature(String folderPath, String stringPublicKey) throws CodePushInvalidUpdateException {
|
||||
public static void verifyUpdateSignature(String folderPath, String packageHash, String stringPublicKey) throws CodePushInvalidUpdateException {
|
||||
CodePushUtils.log("Verifying signature for folder path: " + folderPath);
|
||||
|
||||
final PublicKey publicKey = parsePublicKey(stringPublicKey);
|
||||
@@ -256,6 +258,10 @@ public class CodePushUpdateUtils {
|
||||
throw new CodePushInvalidUpdateException("The update could not be verified because the signature did not specify a content hash.");
|
||||
}
|
||||
|
||||
CodePushUpdateUtils.verifyFolderHash(folderPath, contentHash);
|
||||
if (!contentHash.equals(packageHash)) {
|
||||
throw new CodePushInvalidUpdateException("The update contents failed the code signing check.");
|
||||
}
|
||||
|
||||
CodePushUtils.log("The update contents succeeded the code signing check.");
|
||||
}
|
||||
}
|
||||
@@ -193,9 +193,10 @@ failCallback:(void (^)(NSError *err))failCallback;
|
||||
withPublicKey:(NSString *)publicKey
|
||||
error:(NSError **)error;
|
||||
|
||||
+ (BOOL)verifySignatureFor:(NSString *)updateFolderPath
|
||||
withPublicKey:(NSString *)publicKey
|
||||
error:(NSError **)error;
|
||||
+ (BOOL)verifyUpdateSignatureFor:(NSString *)updateFolderPath
|
||||
expectedHash:(NSString *)newUpdateHash
|
||||
withPublicKey:(NSString *)publicKeyString
|
||||
error:(NSError **)error;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -241,18 +241,32 @@ static NSString *const UnzippedFolderName = @"unzipped";
|
||||
|
||||
if (isSignatureVerificationEnabled) {
|
||||
if (isSignatureAppearedInBundle) {
|
||||
BOOL isSignatureValid = [CodePushUpdateUtils verifySignatureFor:newUpdateFolderPath
|
||||
withPublicKey:publicKey
|
||||
error:&error];
|
||||
if (!isSignatureValid) {
|
||||
CPLog(@"Code signing integrity check error.");
|
||||
if (![CodePushUpdateUtils verifyFolderHash:newUpdateFolderPath
|
||||
expectedHash:newUpdateHash
|
||||
error:&error]) {
|
||||
CPLog(@"The update contents failed the data integrity check.");
|
||||
if (!error) {
|
||||
error = [CodePushErrorUtils errorWithMessage:@"Code signing integrity check error."];
|
||||
error = [CodePushErrorUtils errorWithMessage:@"The update contents failed the data integrity check."];
|
||||
}
|
||||
|
||||
failCallback(error);
|
||||
return;
|
||||
} else {
|
||||
CPLog(@"The update contents succeeded the data integrity check.");
|
||||
}
|
||||
BOOL isSignatureValid = [CodePushUpdateUtils verifyUpdateSignatureFor:newUpdateFolderPath
|
||||
expectedHash:newUpdateHash
|
||||
withPublicKey:publicKey
|
||||
error:&error];
|
||||
if (!isSignatureValid) {
|
||||
CPLog(@"The update contents failed code signing check.");
|
||||
if (!error) {
|
||||
error = [CodePushErrorUtils errorWithMessage:@"The update contents failed code signing check."];
|
||||
}
|
||||
failCallback(error);
|
||||
return;
|
||||
} else {
|
||||
CPLog(@"The update contents succeeded the code signing integrity check.");
|
||||
CPLog(@"The update contents succeeded the code signing check.");
|
||||
}
|
||||
} else {
|
||||
error = [CodePushErrorUtils errorWithMessage:
|
||||
|
||||
@@ -335,9 +335,10 @@ NSString * const IgnoreCodePushMetadata = @".codepushrelease";
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)verifySignatureFor:(NSString *)folderPath
|
||||
withPublicKey:(NSString *)publicKeyString
|
||||
error:(NSError **)error
|
||||
+ (BOOL)verifyUpdateSignatureFor:(NSString *)folderPath
|
||||
expectedHash:(NSString *)newUpdateHash
|
||||
withPublicKey:(NSString *)publicKeyString
|
||||
error:(NSError **)error
|
||||
{
|
||||
NSLog(@"Verifying signature for folder path: %@", folderPath);
|
||||
|
||||
@@ -360,6 +361,8 @@ NSString * const IgnoreCodePushMetadata = @".codepushrelease";
|
||||
return false;
|
||||
}
|
||||
|
||||
CPLog(@"JWT signature verification succeeded, payload content: %@", envelopedPayload);
|
||||
|
||||
if(![envelopedPayload objectForKey:@"contentHash"]){
|
||||
CPLog(@"The update could not be verified because the signature did not specify a content hash.");
|
||||
return false;
|
||||
@@ -367,9 +370,7 @@ NSString * const IgnoreCodePushMetadata = @".codepushrelease";
|
||||
|
||||
NSString *contentHash = envelopedPayload[@"contentHash"];
|
||||
|
||||
return [self verifyFolderHash:folderPath
|
||||
expectedHash:contentHash
|
||||
error:error];
|
||||
return [contentHash isEqualToString:newUpdateHash];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user