diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java index 3c2a743..77f879d 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java @@ -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. " + diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java index e45eaed..7b6ffd0 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java @@ -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 verifyAndDecodeJWT(String jwt, PublicKey publicKey) { @@ -184,7 +186,7 @@ public class CodePushUpdateUtils { JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey)publicKey); if (signedJWT.verify(verifier)) { Map 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."); } } \ No newline at end of file diff --git a/ios/CodePush/CodePush.h b/ios/CodePush/CodePush.h index 314b3da..34dc815 100644 --- a/ios/CodePush/CodePush.h +++ b/ios/CodePush/CodePush.h @@ -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 diff --git a/ios/CodePush/CodePushPackage.m b/ios/CodePush/CodePushPackage.m index b32ba13..2671934 100644 --- a/ios/CodePush/CodePushPackage.m +++ b/ios/CodePush/CodePushPackage.m @@ -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: diff --git a/ios/CodePush/CodePushUpdateUtils.m b/ios/CodePush/CodePushUpdateUtils.m index 1c9c588..b88cb64 100644 --- a/ios/CodePush/CodePushUpdateUtils.m +++ b/ios/CodePush/CodePushUpdateUtils.m @@ -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