@bravemobile/react-native-code-push 12.3.1 → 12.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CodePush.podspec +0 -2
- package/README.md +4 -2
- package/android/app/build.gradle +0 -1
- package/android/app/proguard-rules.pro +5 -0
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +0 -35
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushConstants.java +0 -1
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushNativeModule.java +33 -9
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateManager.java +1 -28
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushUpdateUtils.java +1 -104
- package/cli/commands/bundleCommand/bundleCodePush.ts +29 -0
- package/cli/commands/bundleCommand/index.ts +3 -0
- package/cli/commands/releaseCommand/index.ts +3 -0
- package/cli/commands/releaseCommand/release.ts +2 -1
- package/cli/dist/commands/bundleCommand/bundleCodePush.js +14 -1
- package/cli/dist/commands/bundleCommand/index.js +2 -1
- package/cli/dist/commands/releaseCommand/index.js +2 -1
- package/cli/dist/commands/releaseCommand/release.js +2 -2
- package/cli/dist/utils/hash-utils.js +1 -4
- package/cli/utils/hash-utils.ts +1 -4
- package/expo/plugin/withCodePushAndroid.js +15 -16
- package/ios/CodePush/CodePush.h +0 -16
- package/ios/CodePush/CodePush.m +0 -12
- package/ios/CodePush/CodePushConfig.m +0 -10
- package/ios/CodePush/CodePushPackage.m +0 -39
- package/ios/CodePush/CodePushUpdateUtils.m +1 -91
- package/ios/CodePush.xcodeproj/project.pbxproj +0 -324
- package/package.json +11 -28
- package/android/app/src/main/java/com/microsoft/codepush/react/CodePushInvalidPublicKeyException.java +0 -12
- package/ios/CodePush/Base64/Base64/MF_Base64Additions.h +0 -34
- package/ios/CodePush/Base64/Base64/MF_Base64Additions.m +0 -252
- package/ios/CodePush/Base64/README.md +0 -47
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithm.h +0 -69
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.h +0 -16
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmFactory.m +0 -51
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.h +0 -15
- package/ios/CodePush/JWT/Core/Algorithms/Base/JWTAlgorithmNone.m +0 -55
- package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.h +0 -24
- package/ios/CodePush/JWT/Core/Algorithms/ESFamily/JWTAlgorithmESBase.m +0 -41
- package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.h +0 -28
- package/ios/CodePush/JWT/Core/Algorithms/HSFamily/JWTAlgorithmHSBase.m +0 -205
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.h +0 -103
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolder.m +0 -322
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.h +0 -37
- package/ios/CodePush/JWT/Core/Algorithms/Holders/JWTAlgorithmDataHolderChain.m +0 -145
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.h +0 -35
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTAlgorithmRSBase.m +0 -551
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/JWTRSAlgorithm.h +0 -23
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.h +0 -43
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKey.m +0 -230
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.h +0 -31
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoKeyExtractor.m +0 -113
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.h +0 -38
- package/ios/CodePush/JWT/Core/Algorithms/RSFamily/RSKeys/JWTCryptoSecurity.m +0 -500
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.h +0 -18
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaim.m +0 -214
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.h +0 -23
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSet.m +0 -29
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.h +0 -19
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetSerializer.m +0 -68
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.h +0 -18
- package/ios/CodePush/JWT/Core/ClaimSet/JWTClaimsSetVerifier.m +0 -72
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.h +0 -67
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+ResultTypes.m +0 -111
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.h +0 -119
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionOne.m +0 -307
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.h +0 -94
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionThree.m +0 -619
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.h +0 -164
- package/ios/CodePush/JWT/Core/Coding/JWTCoding+VersionTwo.m +0 -514
- package/ios/CodePush/JWT/Core/Coding/JWTCoding.h +0 -24
- package/ios/CodePush/JWT/Core/Coding/JWTCoding.m +0 -11
- package/ios/CodePush/JWT/Core/FrameworkSupplement/JWT.h +0 -52
- package/ios/CodePush/JWT/Core/FrameworkSupplement/Map.modulemap +0 -5
- package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.h +0 -28
- package/ios/CodePush/JWT/Core/Supplement/JWTBase64Coder.m +0 -70
- package/ios/CodePush/JWT/Core/Supplement/JWTDeprecations.h +0 -22
- package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.h +0 -34
- package/ios/CodePush/JWT/Core/Supplement/JWTErrorDescription.m +0 -73
- package/ios/CodePush/JWT/LICENSE +0 -19
- package/ios/CodePush/JWT/README.md +0 -489
|
@@ -28,11 +28,9 @@ function androidMainApplicationApplyImplementation(mainApplication, find, add, r
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function addJsBundleFilePathArgument(mainApplication) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const packageListArgumentPattern = /(packageList\s*=\s*\n\s*PackageList\(this\)[\s\S]+?\},?\s*\n)/;
|
|
31
|
+
// Capture packageList block plus optional existing jsBundleFilePath line.
|
|
32
|
+
// This allows us to normalize comma placement before injecting the new argument.
|
|
33
|
+
const packageListArgumentPattern = /(packageList\s*=\s*\n\s*PackageList\(this\)[\s\S]+?\},?\s*\n)(\s*jsBundleFilePath\s*=\s*CodePush\.getJSBundleFile\(\),\s*\n)?/;
|
|
36
34
|
|
|
37
35
|
if (!packageListArgumentPattern.test(mainApplication)) {
|
|
38
36
|
WarningAggregator.addWarningAndroid(
|
|
@@ -47,12 +45,15 @@ function addJsBundleFilePathArgument(mainApplication) {
|
|
|
47
45
|
return mainApplication;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
return mainApplication.replace(packageListArgumentPattern, (match) => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
return mainApplication.replace(packageListArgumentPattern, (match, packageListArgument, existingJsBundleArgument) => {
|
|
49
|
+
const trimmedMatch = packageListArgument.replace(/\s+$/, '');
|
|
50
|
+
// Kotlin call args need a trailing comma before the next named argument.
|
|
51
|
+
const hasTrailingComma = /,\s*$/.test(trimmedMatch);
|
|
52
|
+
const packageListArgumentWithComma = hasTrailingComma ? trimmedMatch : `${trimmedMatch},`;
|
|
53
|
+
const jsBundleArgument = existingJsBundleArgument
|
|
54
|
+
? existingJsBundleArgument.replace(/\s+$/, '')
|
|
55
|
+
: ` ${JS_BUNDLE_FILE_PATH_ARGUMENT},`;
|
|
56
|
+
return `${packageListArgumentWithComma}\n${jsBundleArgument}\n`;
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
59
|
|
|
@@ -64,10 +65,9 @@ const withAndroidMainApplicationDependency = (config) => {
|
|
|
64
65
|
IMPORT_CODE_PUSH,
|
|
65
66
|
);
|
|
66
67
|
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
} else {
|
|
68
|
+
if (action.modResults.contents.includes(RN_082_MARKER)) {
|
|
69
|
+
action.modResults.contents = addJsBundleFilePathArgument(action.modResults.contents);
|
|
70
|
+
} else if (!action.modResults.contents.includes('CodePush.getJSBundleFile()')) {
|
|
71
71
|
// https://github.com/Soomgo-Mobile/react-native-code-push/issues/97
|
|
72
72
|
const isExpoSDK54 = config.sdkVersion?.startsWith('54.') ?? false;
|
|
73
73
|
const addingCode = isExpoSDK54
|
|
@@ -81,7 +81,6 @@ const withAndroidMainApplicationDependency = (config) => {
|
|
|
81
81
|
'object : DefaultReactNativeHost(this) {',
|
|
82
82
|
addingCode,
|
|
83
83
|
);
|
|
84
|
-
}
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
return action;
|
package/ios/CodePush/CodePush.h
CHANGED
|
@@ -102,7 +102,6 @@
|
|
|
102
102
|
@property (readonly) NSDictionary *configuration;
|
|
103
103
|
@property (copy) NSString *deploymentKey;
|
|
104
104
|
@property (copy) NSString *serverURL;
|
|
105
|
-
@property (copy) NSString *publicKey;
|
|
106
105
|
|
|
107
106
|
+ (instancetype)current;
|
|
108
107
|
|
|
@@ -140,7 +139,6 @@ failCallback:(void (^)(NSError *err))failCallback;
|
|
|
140
139
|
|
|
141
140
|
+ (void)downloadPackage:(NSDictionary *)updatePackage
|
|
142
141
|
expectedBundleFileName:(NSString *)expectedBundleFileName
|
|
143
|
-
publicKey:(NSString *)publicKey
|
|
144
142
|
operationQueue:(dispatch_queue_t)operationQueue
|
|
145
143
|
progressCallback:(void (^)(long long, long long))progressCallback
|
|
146
144
|
doneCallback:(void (^)())doneCallback
|
|
@@ -203,20 +201,6 @@ failCallback:(void (^)(NSError *err))failCallback;
|
|
|
203
201
|
expectedHash:(NSString *)expectedHash
|
|
204
202
|
error:(NSError **)error;
|
|
205
203
|
|
|
206
|
-
// remove BEGIN / END tags and line breaks from public key string
|
|
207
|
-
+ (NSString *)getKeyValueFromPublicKeyString:(NSString *)publicKeyString;
|
|
208
|
-
|
|
209
|
-
+ (NSString *)getSignatureFilePath:(NSString *)updateFolderPath;
|
|
210
|
-
|
|
211
|
-
+ (NSDictionary *) verifyAndDecodeJWT:(NSString *) jwt
|
|
212
|
-
withPublicKey:(NSString *)publicKey
|
|
213
|
-
error:(NSError **)error;
|
|
214
|
-
|
|
215
|
-
+ (BOOL)verifyUpdateSignatureFor:(NSString *)updateFolderPath
|
|
216
|
-
expectedHash:(NSString *)newUpdateHash
|
|
217
|
-
withPublicKey:(NSString *)publicKeyString
|
|
218
|
-
error:(NSError **)error;
|
|
219
|
-
|
|
220
204
|
@end
|
|
221
205
|
|
|
222
206
|
void CPLog(NSString *formatString, ...);
|
package/ios/CodePush/CodePush.m
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#if __has_include(<React/RCTAssert.h>)
|
|
2
1
|
#import <React/RCTAssert.h>
|
|
3
2
|
#import <React/RCTBridgeModule.h>
|
|
4
3
|
#import <React/RCTConvert.h>
|
|
@@ -6,14 +5,6 @@
|
|
|
6
5
|
#import <React/RCTRootView.h>
|
|
7
6
|
#import <React/RCTUtils.h>
|
|
8
7
|
#import <React/RCTReloadCommand.h>
|
|
9
|
-
#else // back compatibility for RN version < 0.40
|
|
10
|
-
#import "RCTAssert.h"
|
|
11
|
-
#import "RCTBridgeModule.h"
|
|
12
|
-
#import "RCTConvert.h"
|
|
13
|
-
#import "RCTEventDispatcher.h"
|
|
14
|
-
#import "RCTRootView.h"
|
|
15
|
-
#import "RCTUtils.h"
|
|
16
|
-
#endif
|
|
17
8
|
|
|
18
9
|
#import "CodePush.h"
|
|
19
10
|
|
|
@@ -740,12 +731,9 @@ RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary*)updatePackage
|
|
|
740
731
|
_lastProgressEventTime = 0;
|
|
741
732
|
}
|
|
742
733
|
|
|
743
|
-
NSString * publicKey = [[CodePushConfig current] publicKey];
|
|
744
|
-
|
|
745
734
|
[CodePushPackage
|
|
746
735
|
downloadPackage:mutableUpdatePackage
|
|
747
736
|
expectedBundleFileName:[bundleResourceName stringByAppendingPathExtension:bundleResourceExtension]
|
|
748
|
-
publicKey:publicKey
|
|
749
737
|
operationQueue:_methodQueue
|
|
750
738
|
// The download is progressing forward
|
|
751
739
|
progressCallback:^(long long expectedContentLength, long long receivedContentLength) {
|
|
@@ -12,7 +12,6 @@ static NSString * const BuildVersionConfigKey = @"buildVersion";
|
|
|
12
12
|
static NSString * const ClientUniqueIDConfigKey = @"clientUniqueId";
|
|
13
13
|
static NSString * const DeploymentKeyConfigKey = @"deploymentKey";
|
|
14
14
|
static NSString * const ServerURLConfigKey = @"serverUrl";
|
|
15
|
-
static NSString * const PublicKeyKey = @"publicKey";
|
|
16
15
|
|
|
17
16
|
+ (instancetype)current
|
|
18
17
|
{
|
|
@@ -35,7 +34,6 @@ static NSString * const PublicKeyKey = @"publicKey";
|
|
|
35
34
|
NSString *buildVersion = [infoDictionary objectForKey:(NSString *)kCFBundleVersionKey];
|
|
36
35
|
NSString *deploymentKey = [infoDictionary objectForKey:@"CodePushDeploymentKey"];
|
|
37
36
|
NSString *serverURL = [infoDictionary objectForKey:@"CodePushServerURL"];
|
|
38
|
-
NSString *publicKey = [infoDictionary objectForKey:@"CodePushPublicKey"];
|
|
39
37
|
|
|
40
38
|
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
|
|
41
39
|
NSString *clientUniqueId = [userDefaults stringForKey:ClientUniqueIDConfigKey];
|
|
@@ -56,7 +54,6 @@ static NSString * const PublicKeyKey = @"publicKey";
|
|
|
56
54
|
if (serverURL) [_configDictionary setObject:serverURL forKey:ServerURLConfigKey];
|
|
57
55
|
if (clientUniqueId) [_configDictionary setObject:clientUniqueId forKey:ClientUniqueIDConfigKey];
|
|
58
56
|
if (deploymentKey) [_configDictionary setObject:deploymentKey forKey:DeploymentKeyConfigKey];
|
|
59
|
-
if (publicKey) [_configDictionary setObject:publicKey forKey:PublicKeyKey];
|
|
60
57
|
|
|
61
58
|
return self;
|
|
62
59
|
}
|
|
@@ -91,11 +88,6 @@ static NSString * const PublicKeyKey = @"publicKey";
|
|
|
91
88
|
return [_configDictionary objectForKey:ClientUniqueIDConfigKey];
|
|
92
89
|
}
|
|
93
90
|
|
|
94
|
-
- (NSString *)publicKey
|
|
95
|
-
{
|
|
96
|
-
return [_configDictionary objectForKey:PublicKeyKey];
|
|
97
|
-
}
|
|
98
|
-
|
|
99
91
|
- (void)setAppVersion:(NSString *)appVersion
|
|
100
92
|
{
|
|
101
93
|
[_configDictionary setValue:appVersion forKey:AppVersionConfigKey];
|
|
@@ -111,6 +103,4 @@ static NSString * const PublicKeyKey = @"publicKey";
|
|
|
111
103
|
[_configDictionary setValue:serverURL forKey:ServerURLConfigKey];
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
//no setter for PublicKey, because it's need to be hard coded within Info.plist for safety
|
|
115
|
-
|
|
116
106
|
@end
|
|
@@ -45,7 +45,6 @@ static NSString *const UnzippedFolderName = @"unzipped";
|
|
|
45
45
|
|
|
46
46
|
+ (void)downloadPackage:(NSDictionary *)updatePackage
|
|
47
47
|
expectedBundleFileName:(NSString *)expectedBundleFileName
|
|
48
|
-
publicKey:(NSString *)publicKey
|
|
49
48
|
operationQueue:(dispatch_queue_t)operationQueue
|
|
50
49
|
progressCallback:(void (^)(long long, long long))progressCallback
|
|
51
50
|
doneCallback:(void (^)())doneCallback
|
|
@@ -252,44 +251,6 @@ static NSString *const UnzippedFolderName = @"unzipped";
|
|
|
252
251
|
CPLog(@"The update contents succeeded the data integrity check.");
|
|
253
252
|
}
|
|
254
253
|
|
|
255
|
-
BOOL isSignatureVerificationEnabled = (publicKey != nil);
|
|
256
|
-
|
|
257
|
-
NSString *signatureFilePath = [CodePushUpdateUtils getSignatureFilePath:newUpdateFolderPath];
|
|
258
|
-
BOOL isSignatureAppearedInBundle = [[NSFileManager defaultManager] fileExistsAtPath:signatureFilePath];
|
|
259
|
-
|
|
260
|
-
if (isSignatureVerificationEnabled) {
|
|
261
|
-
if (isSignatureAppearedInBundle) {
|
|
262
|
-
BOOL isSignatureValid = [CodePushUpdateUtils verifyUpdateSignatureFor:newUpdateFolderPath
|
|
263
|
-
expectedHash:newUpdateHash
|
|
264
|
-
withPublicKey:publicKey
|
|
265
|
-
error:&error];
|
|
266
|
-
if (!isSignatureValid) {
|
|
267
|
-
CPLog(@"The update contents failed code signing check.");
|
|
268
|
-
if (!error) {
|
|
269
|
-
error = [CodePushErrorUtils errorWithMessage:@"The update contents failed code signing check."];
|
|
270
|
-
}
|
|
271
|
-
failCallback(error);
|
|
272
|
-
return;
|
|
273
|
-
} else {
|
|
274
|
-
CPLog(@"The update contents succeeded the code signing check.");
|
|
275
|
-
}
|
|
276
|
-
} else {
|
|
277
|
-
error = [CodePushErrorUtils errorWithMessage:
|
|
278
|
-
@"Error! Public key was provided but there is no JWT signature within app bundle to verify " \
|
|
279
|
-
"Possible reasons, why that might happen: \n" \
|
|
280
|
-
"1. You've been released CodePush bundle update using version of CodePush CLI that is not support code signing.\n" \
|
|
281
|
-
"2. You've been released CodePush bundle update without providing --privateKeyPath option."];
|
|
282
|
-
failCallback(error);
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
} else {
|
|
287
|
-
if (isSignatureAppearedInBundle) {
|
|
288
|
-
CPLog(@"Warning! JWT signature exists in codepush update but code integrity check couldn't be performed" \
|
|
289
|
-
" because there is no public key configured. " \
|
|
290
|
-
"Please ensure that public key is properly configured within your application.");
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
254
|
} else {
|
|
294
255
|
[[NSFileManager defaultManager] createDirectoryAtPath:newUpdateFolderPath
|
|
295
256
|
withIntermediateDirectories:YES
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
#import "CodePush.h"
|
|
2
2
|
#include <CommonCrypto/CommonDigest.h>
|
|
3
|
-
#import "JWT.h"
|
|
4
3
|
|
|
5
4
|
@implementation CodePushUpdateUtils
|
|
6
5
|
|
|
7
6
|
NSString * const AssetsFolderName = @"assets";
|
|
8
7
|
NSString * const BinaryHashKey = @"CodePushBinaryHash";
|
|
9
8
|
NSString * const ManifestFolderPrefix = @"CodePush";
|
|
10
|
-
NSString * const BundleJWTFile = @".codepushrelease";
|
|
11
9
|
|
|
12
10
|
/*
|
|
13
11
|
Ignore list for hashing
|
|
14
12
|
*/
|
|
15
13
|
NSString * const IgnoreMacOSX= @"__MACOSX/";
|
|
16
14
|
NSString * const IgnoreDSStore = @".DS_Store";
|
|
17
|
-
NSString * const IgnoreCodePushMetadata = @".codepushrelease";
|
|
18
15
|
|
|
19
16
|
+ (BOOL)isHashIgnoredFor:(NSString *) relativePath
|
|
20
17
|
{
|
|
21
18
|
return [relativePath hasPrefix:IgnoreMacOSX]
|
|
22
19
|
|| [relativePath isEqualToString:IgnoreDSStore]
|
|
23
|
-
|| [relativePath hasSuffix:[NSString stringWithFormat:@"/%@", IgnoreDSStore]]
|
|
24
|
-
|| [relativePath isEqualToString:IgnoreCodePushMetadata]
|
|
25
|
-
|| [relativePath hasSuffix:[NSString stringWithFormat:@"/%@", IgnoreCodePushMetadata]];
|
|
20
|
+
|| [relativePath hasSuffix:[NSString stringWithFormat:@"/%@", IgnoreDSStore]];
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
+ (BOOL)addContentsOfFolderToManifest:(NSString *)folderPath
|
|
@@ -288,89 +283,4 @@ NSString * const IgnoreCodePushMetadata = @".codepushrelease";
|
|
|
288
283
|
return [updateContentsManifestHash isEqualToString:expectedHash];
|
|
289
284
|
}
|
|
290
285
|
|
|
291
|
-
// remove BEGIN / END tags and line breaks from public key string
|
|
292
|
-
+ (NSString *)getKeyValueFromPublicKeyString:(NSString *)publicKeyString
|
|
293
|
-
{
|
|
294
|
-
publicKeyString = [publicKeyString stringByReplacingOccurrencesOfString:@"-----BEGIN PUBLIC KEY-----\n"
|
|
295
|
-
withString:@""];
|
|
296
|
-
publicKeyString = [publicKeyString stringByReplacingOccurrencesOfString:@"-----END PUBLIC KEY-----"
|
|
297
|
-
withString:@""];
|
|
298
|
-
publicKeyString = [publicKeyString stringByReplacingOccurrencesOfString:@"\n"
|
|
299
|
-
withString:@""];
|
|
300
|
-
|
|
301
|
-
return publicKeyString;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
+ (NSString *)getSignatureFilePath:(NSString *)updateFolderPath
|
|
305
|
-
{
|
|
306
|
-
return [NSString stringWithFormat:@"%@/%@/%@", updateFolderPath, ManifestFolderPrefix, BundleJWTFile];
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
+ (NSString *)getSignatureFor:(NSString *)folderPath
|
|
310
|
-
error:(NSError **)error
|
|
311
|
-
{
|
|
312
|
-
NSString *signatureFilePath = [self getSignatureFilePath:folderPath];
|
|
313
|
-
if ([[NSFileManager defaultManager] fileExistsAtPath:signatureFilePath]) {
|
|
314
|
-
return [NSString stringWithContentsOfFile:signatureFilePath encoding:NSUTF8StringEncoding error:error];
|
|
315
|
-
} else {
|
|
316
|
-
*error = [CodePushErrorUtils errorWithMessage:[NSString stringWithFormat: @"Cannot find signature at %@", signatureFilePath]];
|
|
317
|
-
return nil;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
+ (NSDictionary *) verifyAndDecodeJWT:(NSString *)jwt
|
|
322
|
-
withPublicKey:(NSString *)publicKey
|
|
323
|
-
error:(NSError **)error
|
|
324
|
-
{
|
|
325
|
-
id <JWTAlgorithmDataHolderProtocol> verifyDataHolder = [JWTAlgorithmRSFamilyDataHolder new].keyExtractorType([JWTCryptoKeyExtractor publicKeyWithPEMBase64].type).algorithmName(@"RS256").secret(publicKey);
|
|
326
|
-
|
|
327
|
-
JWTCodingBuilder *verifyBuilder = [JWTDecodingBuilder decodeMessage:jwt].addHolder(verifyDataHolder);
|
|
328
|
-
JWTCodingResultType *verifyResult = verifyBuilder.result;
|
|
329
|
-
if (verifyResult.successResult) {
|
|
330
|
-
return verifyResult.successResult.payload;
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
*error = verifyResult.errorResult.error;
|
|
334
|
-
return nil;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
+ (BOOL)verifyUpdateSignatureFor:(NSString *)folderPath
|
|
339
|
-
expectedHash:(NSString *)newUpdateHash
|
|
340
|
-
withPublicKey:(NSString *)publicKeyString
|
|
341
|
-
error:(NSError **)error
|
|
342
|
-
{
|
|
343
|
-
NSLog(@"Verifying signature for folder path: %@", folderPath);
|
|
344
|
-
|
|
345
|
-
NSString *publicKey = [self getKeyValueFromPublicKeyString: publicKeyString];
|
|
346
|
-
|
|
347
|
-
NSError *signatureVerificationError;
|
|
348
|
-
NSString *signature = [self getSignatureFor: folderPath
|
|
349
|
-
error: &signatureVerificationError];
|
|
350
|
-
if (signatureVerificationError) {
|
|
351
|
-
CPLog(@"The update could not be verified because no signature was found. %@", signatureVerificationError);
|
|
352
|
-
*error = signatureVerificationError;
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
NSError *payloadDecodingError;
|
|
357
|
-
NSDictionary *envelopedPayload = [self verifyAndDecodeJWT:signature withPublicKey:publicKey error:&payloadDecodingError];
|
|
358
|
-
if(payloadDecodingError){
|
|
359
|
-
CPLog(@"The update could not be verified because it was not signed by a trusted party. %@", payloadDecodingError);
|
|
360
|
-
*error = payloadDecodingError;
|
|
361
|
-
return false;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
CPLog(@"JWT signature verification succeeded, payload content: %@", envelopedPayload);
|
|
365
|
-
|
|
366
|
-
if(![envelopedPayload objectForKey:@"contentHash"]){
|
|
367
|
-
CPLog(@"The update could not be verified because the signature did not specify a content hash.");
|
|
368
|
-
return false;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
NSString *contentHash = envelopedPayload[@"contentHash"];
|
|
372
|
-
|
|
373
|
-
return [contentHash isEqualToString:newUpdateHash];
|
|
374
|
-
}
|
|
375
|
-
|
|
376
286
|
@end
|