diff --git a/iReSign/iReSign/iReSignAppDelegate.h b/iReSign/iReSign/iReSignAppDelegate.h index 6bd917b..8fc85dd 100755 --- a/iReSign/iReSign/iReSignAppDelegate.h +++ b/iReSign/iReSign/iReSignAppDelegate.h @@ -19,6 +19,7 @@ NSTask *unzipTask; NSTask *copyTask; NSTask *provisioningTask; + NSTask *grabCertPubKeyTask; NSTask *codesignTask; NSTask *generateEntitlementsTask; NSTask *verifyTask; @@ -30,6 +31,7 @@ NSString *workingPath; NSString *appName; NSString *fileName; + NSString *certPubKey; NSString *entitlementsResult; NSString *codesigningResult; diff --git a/iReSign/iReSign/iReSignAppDelegate.m b/iReSign/iReSign/iReSignAppDelegate.m index e03a820..03d5307 100755 --- a/iReSign/iReSign/iReSignAppDelegate.m +++ b/iReSign/iReSign/iReSignAppDelegate.m @@ -347,7 +347,7 @@ - (void)checkProvisioning:(NSTimer *)timer { if (identifierOK) { NSLog(@"Provisioning completed."); [statusLabel setStringValue:@"Provisioning completed"]; - [self doEntitlementsFixing]; + [self checkProvisioningSignature]; } else { [self showAlertOfKind:NSCriticalAlertStyle WithTitle:@"Error" AndMessage:@"Product identifiers don't match"]; [self enableControls]; @@ -364,6 +364,94 @@ - (void)checkProvisioning:(NSTimer *)timer { } } +-(void)checkProvisioningSignature { + grabCertPubKeyTask = [[NSTask alloc] init]; + [grabCertPubKeyTask setLaunchPath:@"/usr/bin/security"]; + [grabCertPubKeyTask setArguments:[NSArray arrayWithObjects:@"find-certificate", @"-a", @"-c", [certComboBox objectValue], @"-p", nil]]; + + [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(verifyProvisioningSignature:) userInfo:nil repeats:TRUE]; + + NSPipe *pipe=[NSPipe pipe]; + [grabCertPubKeyTask setStandardOutput:pipe]; + [grabCertPubKeyTask setStandardError:pipe]; + NSFileHandle *handle = [pipe fileHandleForReading]; + + [grabCertPubKeyTask launch]; + + [NSThread detachNewThreadSelector:@selector(watchCheckProvisioningSignature:) + toTarget:self withObject:handle]; +} + +- (void)watchCheckProvisioningSignature:(NSFileHandle*)streamHandle { + @autoreleasepool { + certPubKey = [[NSString alloc] initWithData:[streamHandle readDataToEndOfFile] encoding:NSASCIIStringEncoding]; + } +} + +- (void)verifyProvisioningSignature:(NSTimer *)timer { + if ([provisioningTask isRunning] == 0) { + [timer invalidate]; + grabCertPubKeyTask = nil; + appPath = nil; + + NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[workingPath stringByAppendingPathComponent:kPayloadDirName] error:nil]; + + for (NSString *file in dirContents) { + if ([[[file pathExtension] lowercaseString] isEqualToString:@"app"]) { + appPath = [[workingPath stringByAppendingPathComponent:kPayloadDirName] stringByAppendingPathComponent:file]; + if ([[NSFileManager defaultManager] fileExistsAtPath:[appPath stringByAppendingPathComponent:@"embedded.mobileprovision"]]) { + + BOOL provisioningSignatureOK = FALSE; + + NSString *embeddedProvisioning = [NSString stringWithContentsOfFile:[appPath stringByAppendingPathComponent:@"embedded.mobileprovision"] encoding:NSASCIIStringEncoding error:nil]; + NSArray* embeddedProvisioningLines = [embeddedProvisioning componentsSeparatedByCharactersInSet: + [NSCharacterSet newlineCharacterSet]]; + + for (int i = 0; i < [embeddedProvisioningLines count]; i++) { + if ([[embeddedProvisioningLines objectAtIndex:i] rangeOfString:@"DeveloperCertificates"].location != NSNotFound) { + + i+=2; + while ([[embeddedProvisioningLines objectAtIndex:i] rangeOfString:@"data"].location != NSNotFound) { + + NSInteger fromPosition = [[embeddedProvisioningLines objectAtIndex:i] rangeOfString:@""].location + 6; + NSInteger toPosition = [[embeddedProvisioningLines objectAtIndex:i] rangeOfString:@""].location; + NSRange range; + range.location = fromPosition; + range.length = toPosition-fromPosition; + + NSString *mpPubKey = [[embeddedProvisioningLines objectAtIndex:i] substringWithRange:range]; + mpPubKey = [NSString stringWithFormat:@"-----BEGIN CERTIFICATE-----%@-----END CERTIFICATE-----", mpPubKey]; + mpPubKey = [mpPubKey stringByReplacingOccurrencesOfString:@"\n" withString:@""]; + mpPubKey = [mpPubKey stringByReplacingOccurrencesOfString:@"\t" withString:@""]; + + certPubKey = [certPubKey stringByReplacingOccurrencesOfString:@"\n" withString:@""]; + certPubKey = [certPubKey stringByReplacingOccurrencesOfString:@"\t" withString:@""]; + + if ([mpPubKey isEqualToString:certPubKey]) { + provisioningSignatureOK = true; + break; + } + i++; + } + break; + } + } + + if (provisioningSignatureOK) { + NSLog(@"Provisioning signature validation completed."); + [statusLabel setStringValue:@"Provisioning signature validation completed"]; + [self doEntitlementsFixing]; + } else { + [self showAlertOfKind:NSCriticalAlertStyle WithTitle:@"Error" AndMessage:@"Provisioning signature validation failed"]; + [self enableControls]; + [statusLabel setStringValue:@"Ready"]; + } + } + } + } + } +} + - (void)doEntitlementsFixing { if (![entitlementField.stringValue isEqualToString:@""] || [provisioningPathField.stringValue isEqualToString:@""]) {