diff --git a/RMStore/Optional/RMAppReceipt.h b/RMStore/Optional/RMAppReceipt.h index 9b45fe33..7c038caf 100644 --- a/RMStore/Optional/RMAppReceipt.h +++ b/RMStore/Optional/RMAppReceipt.h @@ -102,6 +102,12 @@ __attribute__((availability(ios,introduced=7.0))) */ + (void)setAppleRootCertificateURL:(NSURL*)url; +/** + Sets the data of the Apple Root certificate that will be used to verifiy the signature of the bundle receipt. This takes precedence over AppleRootCertificateURL if both are set. If none is provided, AppleRootCertificateURL will be used. If no certificate is available, no signature verification will be performed. + @param data containing the Apple Root certificate. + */ ++ (void)setAppleRootCertificateData:(NSData*)data; + @end /** Represents an in-app purchase in the app receipt. diff --git a/RMStore/Optional/RMAppReceipt.m b/RMStore/Optional/RMAppReceipt.m index 68aa7147..5b72cb6c 100644 --- a/RMStore/Optional/RMAppReceipt.m +++ b/RMStore/Optional/RMAppReceipt.m @@ -103,6 +103,8 @@ static int RMASN1ReadInteger(const uint8_t **pp, long omax) static NSURL *_appleRootCertificateURL = nil; +static NSData *_appleRootCertificateData = nil; + @implementation RMAppReceipt - (instancetype)initWithASN1Data:(NSData*)asn1Data @@ -215,6 +217,11 @@ + (void)setAppleRootCertificateURL:(NSURL*)url _appleRootCertificateURL = url; } ++ (void)setAppleRootCertificateData:(NSData*)data +{ + _appleRootCertificateData = data; +} + #pragma mark - Utils + (NSData*)dataFromPCKS7Path:(NSString*)path @@ -229,8 +236,13 @@ + (NSData*)dataFromPCKS7Path:(NSString*)path if (!p7) return nil; NSData *data; - NSURL *certificateURL = _appleRootCertificateURL ? : [[NSBundle mainBundle] URLForResource:@"AppleIncRootCertificate" withExtension:@"cer"]; - NSData *certificateData = [NSData dataWithContentsOfURL:certificateURL]; + NSData *certificateData = _appleRootCertificateData; + + if( certificateData.length == 0 ) { + NSURL *certificateURL = _appleRootCertificateURL ? : [[NSBundle mainBundle] URLForResource:@"AppleIncRootCertificate" withExtension:@"cer"]; + certificateData = [NSData dataWithContentsOfURL:certificateURL]; + } + if (!certificateData || [self verifyPCKS7:p7 withCertificateData:certificateData]) { struct pkcs7_st *contents = p7->d.sign->contents;