Skip to content

Commit

Permalink
add stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
junepark678 committed Dec 24, 2024
1 parent 10e64aa commit 68c82b3
Showing 1 changed file with 61 additions and 61 deletions.
122 changes: 61 additions & 61 deletions Sources/CAltSign/Signing/ALTSigner.mm
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,23 @@
std::string CertificatesContent(ALTCertificate *altCertificate)
{
NSData *altCertificateP12Data = [altCertificate p12Data];

BIO *inputP12Buffer = BIO_new(BIO_s_mem());
BIO_write(inputP12Buffer, altCertificateP12Data.bytes, (int)altCertificateP12Data.length);

auto inputP12 = d2i_PKCS12_bio(inputP12Buffer, NULL);

// Extract key + certificate from .p12.
EVP_PKEY *key;
X509 *certificate;
PKCS12_parse(inputP12, "", &key, &certificate, NULL);

// Prepare certificate chain of trust.
auto *certificates = sk_X509_new(NULL);

BIO *rootCertificateBuffer = BIO_new_mem_buf(AppleRootCertificateData, (int)strlen(AppleRootCertificateData));
BIO *wwdrCertificateBuffer = nil;

unsigned long issuerHash = X509_issuer_name_hash(certificate);
if (issuerHash == 0x817d2f7a)
{
Expand All @@ -144,41 +144,41 @@
// Use latest WWDR certificate.
wwdrCertificateBuffer = BIO_new_mem_buf(AppleWWDRCertificateData, (int)strlen(AppleWWDRCertificateData));
}

auto rootCertificate = PEM_read_bio_X509(rootCertificateBuffer, NULL, NULL, NULL);
if (rootCertificate != NULL)
{
sk_X509_push(certificates, rootCertificate);
}

auto wwdrCertificate = PEM_read_bio_X509(wwdrCertificateBuffer, NULL, NULL, NULL);
if (wwdrCertificate != NULL)
{
sk_X509_push(certificates, wwdrCertificate);
}

// Create new .p12 in memory with private key and certificate chain.
char emptyString[] = "";
auto outputP12 = PKCS12_create(emptyString, emptyString, key, certificate, certificates, 0, 0, 0, 0, 0);

BIO *outputP12Buffer = BIO_new(BIO_s_mem());
i2d_PKCS12_bio(outputP12Buffer, outputP12);

char *buffer = NULL;
NSUInteger size = BIO_get_mem_data(outputP12Buffer, &buffer);

NSData *p12Data = [NSData dataWithBytes:buffer length:size];

// Free .p12 structures
PKCS12_free(inputP12);
PKCS12_free(outputP12);

BIO_free(wwdrCertificateBuffer);
BIO_free(rootCertificateBuffer);

BIO_free(inputP12Buffer);
BIO_free(outputP12Buffer);

std::string output((const char *)p12Data.bytes, (size_t)p12Data.length);
return output;
}
Expand All @@ -198,17 +198,17 @@ - (instancetype)initWithTeam:(ALTTeam *)team certificate:(ALTCertificate *)certi
_team = team;
_certificate = certificate;
}

return self;
}

- (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTProvisioningProfile *> *)profiles completionHandler:(void (^)(BOOL success, NSError *error))completionHandler
{
{
NSProgress *progress = [NSProgress discreteProgressWithTotalUnitCount:1];

NSURL *ipaURL = nil;
NSURL *appBundleURL = nil;

void (^finish)(BOOL, NSError *) = ^(BOOL success, NSError *error) {
if (ipaURL != nil)
{
Expand All @@ -218,23 +218,23 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
NSLog(@"Failed to clean up after resigning. %@", removeError);
}
}

completionHandler(success, error);
};

__block NSError *error = nil;

if ([appURL.pathExtension.lowercaseString isEqualToString:@"ipa"])
{
ipaURL = appURL;

NSURL *outputDirectoryURL = [[appURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:[[NSUUID UUID] UUIDString] isDirectory:YES];
if (![[NSFileManager defaultManager] createDirectoryAtURL:outputDirectoryURL withIntermediateDirectories:YES attributes:nil error:&error])
{
finish(NO, error);
return progress;
}

appBundleURL = [[NSFileManager defaultManager] unzipAppBundleAtURL:appURL toDirectory:outputDirectoryURL error:&error];
if (appBundleURL == nil)
{
Expand All @@ -246,21 +246,21 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
{
appBundleURL = appURL;
}

NSBundle *appBundle = [NSBundle bundleWithURL:appBundleURL];
if (appBundle == nil)
{
finish(NO, [NSError errorWithDomain:AltSignErrorDomain code:ALTErrorInvalidApp userInfo:nil]);
return progress;
}

ALTApplication *application = [[ALTApplication alloc] initWithFileURL:appBundleURL];
if (application == nil)
{
finish(NO, [NSError errorWithDomain:AltSignErrorDomain code:ALTErrorInvalidApp userInfo:nil]);
return progress;
}

NSDirectoryEnumerator *countEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:appURL
includingPropertiesForKeys:@[NSURLIsDirectoryKey]
options:0
Expand All @@ -269,10 +269,10 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
NSLog(@"[Error] %@ (%@)", error, url);
return NO;
}

return YES;
}];

NSInteger totalCount = 0;
for (NSURL *__unused fileURL in countEnumerator)
{
Expand All @@ -281,22 +281,22 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
{
continue;
}

// Ignore CodeResources files.
if ([[fileURL lastPathComponent] isEqualToString:@"CodeResources"])
{
continue;
}

totalCount++;
}

progress.totalUnitCount = totalCount;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

NSMutableDictionary<NSURL *, NSString *> *entitlementsByFileURL = [NSMutableDictionary dictionary];

ALTProvisioningProfile *(^profileForApp)(ALTApplication *) = ^ALTProvisioningProfile *(ALTApplication *app) {
// Assume for now that apps don't have 100s of app extensions 🤷‍♂️
for (ALTProvisioningProfile *profile in profiles)
Expand All @@ -306,20 +306,20 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
return profile;
}
}

return nil;
};

NSError * (^prepareApp)(ALTApplication *) = ^NSError *(ALTApplication *app) {
ALTProvisioningProfile *profile = profileForApp(app);
if (profile == nil)
{
return [NSError errorWithDomain:AltSignErrorDomain code:ALTErrorMissingProvisioningProfile userInfo:nil];
}

NSURL *profileURL = [app.fileURL URLByAppendingPathComponent:@"embedded.mobileprovision"];
[profile.data writeToURL:profileURL atomically:YES];

NSString *additionalEntitlements = nil;
if (app.hasPrivateEntitlements)
{
Expand All @@ -329,14 +329,14 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
{
// Most likely using private (commented out) entitlements to exploit Psychic Paper https://github.com/Siguza/psychicpaper
// Assume they know what they are doing and extract private entitlements to merge with profile's.

NSRange commentRange = NSMakeRange(commentStartRange.location, (commentEndRange.location + commentEndRange.length) - commentStartRange.location);
NSString *commentedEntitlements = [app.entitlementsString substringWithRange:commentRange];

additionalEntitlements = commentedEntitlements;
}
}

NSMutableDictionary<NSString *, id> *filteredEntitlements = [profile.entitlements mutableCopy];
for (NSString *entitlement in profile.entitlements)
{
Expand Down Expand Up @@ -368,13 +368,13 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
}
else
{
if ([entitlement isEqualToString:ALTEntitlementApplicationIdentifier] || [entitlement isEqualToString:ALTEntitlementTeamIdentifier] || [entitlement isEqualToString:ALTEntitlementGetTaskAllow] || [entitlement isEqualToString:ALTEntitlementIncreasedMemoryLimit])
if ([entitlement isEqualToString:ALTEntitlementApplicationIdentifier] || [entitlement isEqualToString:ALTEntitlementTeamIdentifier] || [entitlement isEqualToString:ALTEntitlementGetTaskAllow] || [entitlement isEqualToString:ALTEntitlementIncreasedMemoryLimit] || [entitlement isEqualToString:ALTEntitlementIncreasedDebuggingMemoryLimit])
{
// Apps signed with development profiles _must_ have these entitlements, so never remove them,
// even if downloaded app doesn't have them originally.
continue;
}

// Original app does not have this entitlement, so don't give it to resigned app.
filteredEntitlements[entitlement] = nil;
}
Expand All @@ -385,28 +385,28 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
{
return error;
}

NSMutableString *entitlements = [[NSMutableString alloc] initWithData:entitlementsData encoding:NSUTF8StringEncoding];
if (additionalEntitlements != nil)
{
// Insert additional entitlements after first occurence of <dict>.
NSRange entitlementsStartRange = [entitlements rangeOfString:@"<dict>"];
[entitlements insertString:additionalEntitlements atIndex:entitlementsStartRange.location + entitlementsStartRange.length];
}

NSURL *resolvedURL = [app.fileURL URLByResolvingSymlinksInPath];
entitlementsByFileURL[resolvedURL] = entitlements;

return nil;
};

NSError *prepareError = prepareApp(application);
if (prepareError != nil)
{
finish(NO, prepareError);
return;
}

for (ALTApplication *appExtension in application.appExtensions)
{
NSError *error = prepareApp(appExtension);
Expand All @@ -416,25 +416,25 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
break;
}
}

if (prepareError != nil)
{
finish(NO, prepareError);
return;
}

try
{
// Sign application
ldid::DiskFolder appBundle(application.fileURL.fileSystemRepresentation);
std::string key = CertificatesContent(self.certificate);

ldid::Sign("", appBundle, key, "",
ldid::fun([&](const std::string &path, const std::string &binaryEntitlements) -> std::string {
NSString *filename = [NSString stringWithCString:path.c_str() encoding:NSUTF8StringEncoding];

NSURL *fileURL = nil;

if (filename.length == 0)
{
fileURL = application.fileURL;
Expand All @@ -443,9 +443,9 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
{
fileURL = [application.fileURL URLByAppendingPathComponent:filename isDirectory:YES];
}

NSURL *resolvedURL = [fileURL URLByResolvingSymlinksInPath];

NSString *entitlements = entitlementsByFileURL[resolvedURL];
return entitlements.UTF8String;
}),
Expand All @@ -454,21 +454,21 @@ - (NSProgress *)signAppAtURL:(NSURL *)appURL provisioningProfiles:(NSArray<ALTPr
}),
ldid::fun([&](const double signingProgress) {
}));


// Dispatch after to allow time to finish signing binary.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (ipaURL != nil)
{
NSURL *resignedIPAURL = [[NSFileManager defaultManager] zipAppBundleAtURL:appBundleURL error:&error];

if (![[NSFileManager defaultManager] replaceItemAtURL:ipaURL withItemAtURL:resignedIPAURL backupItemName:nil options:0 resultingItemURL:nil error:&error])
{
finish(NO, error);
return;
}
}

finish(YES, nil);
});
}
Expand Down

0 comments on commit 68c82b3

Please sign in to comment.