Created
October 24, 2023 21:25
-
-
Save jevinskie/dc04f875eb4dea495efdaa3df2ae83fc to your computer and use it in GitHub Desktop.
MobileStorageMounter DDI verification
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// clang-format off | |
// clang++ -Wall -Wextra -Wno-deprecated-declarations -g -fobjc-arc -std=gnu++2b -framework Foundation -framework CommonCrypto -framework Security -o secstuff secstuff.mm && ./secstuff ./iPhoneCA.pem ./DeveloperDiskImage.dmg ./DeveloperDiskImage.dmg | |
// xcrun --sdk iphoneos clang++ -miphoneos-version-min=14.0 -Wall -Wextra -Wno-deprecated-declarations -g -fobjc-arc -std=gnu++2b -framework Foundation -framework CommonCrypto -framework Security -Wl,-adhoc_codesign -o secstuff-ios secstuff.mm | |
// clang-format on | |
#define SEC_OS_IPHONE 1 | |
#undef NDEBUG | |
#include <CommonCrypto/CommonDigest.h> | |
#import <Foundation/Foundation.h> | |
#import <Security/Security.h> | |
#include <cassert> | |
#include <cstdint> | |
#include <cstdio> | |
#include <cstdlib> | |
@interface NSData (hexString) | |
- (NSString *)hexString; | |
@end | |
@implementation NSData (hexString) | |
- (NSString *)hexString { | |
const auto buf = (const uint8_t *)self.bytes; | |
if (!buf) { | |
return @""; | |
} | |
const auto len = self.length; | |
NSMutableString *hexString = [NSMutableString stringWithCapacity:len * 2]; | |
for (NSUInteger i = 0; i < len; ++i) { | |
[hexString appendString:[NSString stringWithFormat:@"%02hhx", buf[i]]]; | |
} | |
return [NSString stringWithString:hexString]; | |
} | |
@end | |
/* Returns a certificate from a pem blob. | |
Return NULL if the passed-in data is not a valid DER-encoded X.509 | |
certificate. */ | |
extern "C" SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator, | |
CFDataRef pem_certificate); | |
int main(int argc, const char **argv) { | |
if (argc != 5) { | |
fprintf(stderr, | |
"Usage: %s <iPhoneDebug.pem path> <iPhoneCA.pem path> <DDI.dmg path> " | |
"<DDI.dmg.signature path>\n", | |
getprogname()); | |
return 1; | |
} | |
const auto dbg_pem_data = [NSData dataWithContentsOfFile:@(argv[1])]; | |
const SecCertificateRef dbg_cert = | |
SecCertificateCreateWithPEM(nullptr, (__bridge CFDataRef)dbg_pem_data); | |
NSLog(@"dbg_cert: %@", dbg_cert); | |
const auto ca_pem_data = [NSData dataWithContentsOfFile:@(argv[2])]; | |
const SecCertificateRef ca_cert = | |
SecCertificateCreateWithPEM(nullptr, (__bridge CFDataRef)ca_pem_data); | |
NSLog(@"ca_cert: %@", ca_cert); | |
const auto policy = SecPolicyCreateBasicX509(); | |
NSLog(@"policy: %@", policy); | |
const auto certs = @[ (__bridge id)dbg_cert, (__bridge id)ca_cert ]; | |
const auto policies = @[ (__bridge id)policy ]; | |
SecTrustRef trust = nullptr; | |
const auto trust_create_res = SecTrustCreateWithCertificates( | |
(__bridge CFArrayRef)certs, (__bridge CFArrayRef)policies, &trust); | |
assert(errSecSuccess == trust_create_res); | |
assert(trust); | |
NSLog(@"trust: %@", (__bridge id)trust); | |
// 2014-04-10 22:55:30 | |
const auto date = [NSDate dateWithTimeIntervalSince1970:1397170530]; | |
NSLog(@"date: %@", date); | |
const auto trust_set_date_res = SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date); | |
if (errSecSuccess != trust_set_date_res) { | |
NSLog(@"SecTrustSetVerifyDate(%@, %@) failed with %@", (__bridge id)trust, date, | |
(__bridge id)SecCopyErrorMessageString(trust_set_date_res, nullptr)); | |
return 2; | |
} | |
assert(errSecSuccess == trust_set_date_res); | |
NSLog(@"dated trust: %@", (__bridge id)trust); | |
CFErrorRef eval_err = nullptr; | |
const auto eval_res = SecTrustEvaluateWithError(trust, &eval_err); | |
if (!eval_res || eval_err) { | |
NSLog(@"eval_res: %d eval_err: %@", eval_res, (__bridge id)eval_err); | |
return 3; | |
} | |
const auto key = SecTrustCopyKey(trust); | |
assert(key); | |
NSLog(@"returned key: %@", (__bridge id)key); | |
const auto dmg_data = [NSData dataWithContentsOfFile:@(argv[3])]; | |
assert(dmg_data); | |
NSLog(@"dmg_data: %@", dmg_data); | |
uint8_t sha1[CC_SHA1_DIGEST_LENGTH] = {}; | |
const auto sha1_res = CC_SHA1(dmg_data.bytes, dmg_data.length, sha1); | |
assert(sha1_res); | |
const auto sha1_data = [NSData dataWithBytes:sha1 length:sizeof(sha1)]; | |
assert(sha1_data); | |
NSLog(@"DMG sha1: %@", sha1_data.hexString); | |
const auto dmg_sig_data = [NSData dataWithContentsOfFile:@(argv[4])]; | |
assert(dmg_sig_data); | |
NSLog(@"dmg_sig_data: %@", dmg_sig_data); | |
NSLog(@"sig: %@", dmg_sig_data.hexString); | |
const auto verify_res = | |
SecKeyRawVerify(key, kSecPaddingPKCS1SHA1, (const uint8_t *)sha1_data.bytes, | |
sha1_data.length, (const uint8_t *)dmg_sig_data.bytes, dmg_sig_data.length); | |
NSLog(@"verify_res: %d aka %@", verify_res, | |
(__bridge id)SecCopyErrorMessageString(verify_res, nullptr)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment