├── iOSRSA ├── en.lproj │ ├── InfoPlist.strings │ └── ViewController.xib ├── .DS_Store ├── Default.png ├── Default@2x.png ├── certificate.cer ├── Default-568h@2x.png ├── ViewController.h ├── AppDelegate.h ├── iOSRSA-Prefix.pch ├── main.m ├── iOSRSA-Info.plist ├── AppDelegate.mm ├── ViewController.mm ├── SecKeyHelper.h └── SecKeyHelper.mm ├── .DS_Store ├── iOSRSA.xcodeproj ├── xcuserdata │ ├── wills.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints.xcbkptlist │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── iOSRSA.xcscheme │ └── william.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ ├── william.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ └── wills.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── iOSRSA.xccheckout └── project.pbxproj └── README.md /iOSRSA/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/.DS_Store -------------------------------------------------------------------------------- /iOSRSA/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/iOSRSA/.DS_Store -------------------------------------------------------------------------------- /iOSRSA/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/iOSRSA/Default.png -------------------------------------------------------------------------------- /iOSRSA/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/iOSRSA/Default@2x.png -------------------------------------------------------------------------------- /iOSRSA/certificate.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/iOSRSA/certificate.cer -------------------------------------------------------------------------------- /iOSRSA/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/iOSRSA/Default-568h@2x.png -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/xcuserdata/wills.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /iOSRSA/ViewController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | // Test the seckey helper fns 5 | void testSecKey() ; 6 | 7 | @interface ViewController : UIViewController 8 | { 9 | 10 | } 11 | @end -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/project.xcworkspace/xcuserdata/william.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/iOSRSA.xcodeproj/project.xcworkspace/xcuserdata/william.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/project.xcworkspace/xcuserdata/wills.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superwills/iOSRSAPublicKeyEncryption/HEAD/iOSRSA.xcodeproj/project.xcworkspace/xcuserdata/wills.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /iOSRSA/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ViewController; 4 | 5 | @interface AppDelegate : UIResponder 6 | 7 | @property (strong, nonatomic) UIWindow *window; 8 | 9 | @property (strong, nonatomic) ViewController *viewController; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iOSRSA/iOSRSA-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'iOSRSA' target in the 'iOSRSA' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /iOSRSA/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iOSRSA 4 | // 5 | // Created by William Sherif on 4/18/13. 6 | // Copyright (c) 2013 William Sherif. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/project.xcworkspace/xcuserdata/wills.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/xcuserdata/william.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | iOSRSA.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/xcuserdata/wills.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | iOSRSA.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9FE4977A172093DD00FFFDD1 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /iOSRSA/iOSRSA-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | w.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations~ipad 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationPortraitUpsideDown 35 | UIInterfaceOrientationLandscapeLeft 36 | UIInterfaceOrientationLandscapeRight 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/project.xcworkspace/xcshareddata/iOSRSA.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 23A5E50C-C5D1-4E5A-A9D4-38B8D9CAB976 9 | IDESourceControlProjectName 10 | iOSRSA 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | DBDBB184-5286-4818-A3C5-1AA0556688B3 14 | ssh://github.com/superwills/iOSRSAPublicKeyEncryption.git 15 | 16 | IDESourceControlProjectPath 17 | iOSRSA.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | DBDBB184-5286-4818-A3C5-1AA0556688B3 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://github.com/superwills/iOSRSAPublicKeyEncryption.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | DBDBB184-5286-4818-A3C5-1AA0556688B3 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | DBDBB184-5286-4818-A3C5-1AA0556688B3 36 | IDESourceControlWCCName 37 | iOSRSAPublicKeyEncryption 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /iOSRSA/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import "ViewController.h" 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 10 | // Override point for customization after application launch. 11 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; 12 | self.window.rootViewController = self.viewController; 13 | [self.window makeKeyAndVisible]; 14 | return YES; 15 | } 16 | 17 | - (void)applicationWillResignActive:(UIApplication *)application 18 | { 19 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 20 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 21 | } 22 | 23 | - (void)applicationDidEnterBackground:(UIApplication *)application 24 | { 25 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 26 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 27 | } 28 | 29 | - (void)applicationWillEnterForeground:(UIApplication *)application 30 | { 31 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 32 | } 33 | 34 | - (void)applicationDidBecomeActive:(UIApplication *)application 35 | { 36 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 37 | } 38 | 39 | - (void)applicationWillTerminate:(UIApplication *)application 40 | { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /iOSRSA/en.lproj/ViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/xcuserdata/wills.xcuserdatad/xcschemes/iOSRSA.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /iOSRSA/ViewController.mm: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | #import "SecKeyHelper.h" 3 | 4 | void testSecKey() 5 | { 6 | // THIS IS A STRING REPRESENTING THE GLOBAL IDENTIFIER FOR MY PUBLIC KEY CERTIFICATE 7 | // ON THE IOS "KEYCHAIN". 8 | const UInt8 keychainIdStr[] = "com.example.widgets.publickey" ; // YOU MUST USE A CHAR ARRAY[], YOU 9 | // MAY NOT USE char* OR UInt8* FOR THE POINTER TYPE. 10 | // Encryption will fail if you do. 11 | // String must be NULL terminated, (the string literal above is implicitly null terminated by the compiler). 12 | 13 | // CREATE MY KEYCHAIN IDENTIFIER. It has to be a CFDataRef. 14 | CFDataRef CFKEYCHAINID = CFDataCreate( 0, keychainIdStr, sizeof(keychainIdStr) ) ; 15 | 16 | // If you want, we can DELETE the item corresponding to the CFKEYCHAINID 17 | // that we created on the last run. 18 | //////SecCertificateDeleteFromKeyChain( CFKEYCHAINID ) ; // DELETE OLD KEY 19 | 20 | SecKeyRef PUBLICKEY = SecKeyFromKeyChain( CFKEYCHAINID ) ; 21 | if( PUBLICKEY ) puts( "<< KEY RETRIEVAL FROM KEYCHAIN OK!! >>" ) ; 22 | else 23 | { 24 | puts( "FAILED TO LOAD SECKEY FROM KEYCHAIN!!!!!" ) ; 25 | puts( "Loading from certificate.cer.." ) ; 26 | 27 | // LOAD THE PUBLIC KEY FROM certificate.cer. 28 | NSString* certPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"]; 29 | PUBLICKEY = SecKeyFromPathAndSaveInKeyChain( certPath, CFKEYCHAINID ) ; 30 | if( !PUBLICKEY ) 31 | { 32 | puts( "DOUBLE FAIL!!!!! MAKE SURE YOU HAVE LOADED certificate.cer INTO THE XCODE PROJECT " 33 | "AND THAT IT IS SET UNDER 'COPY BUNDLE RESOURCES'!!!" ) ; 34 | return ; 35 | } 36 | } 37 | CFRelease( CFKEYCHAINID ) ; // no more use of CFKEYCHAINID needed 38 | 39 | int blockSize = SecKeyGetBlockSize( PUBLICKEY ) ; 40 | printf( "THE MAX LENGTH OF DATA I CAN ENCRYPT IS %d BYTES\n", blockSize ) ; 41 | 42 | uint8_t *binaryData = (uint8_t *)malloc( blockSize ) ; 43 | for( int i = 0 ; i < blockSize ; i++ ) 44 | binaryData[i] = 'A' + (i % 26 ) ; // loop the alphabet 45 | binaryData[ blockSize-1 ] = 0 ; // NULL TERMINATED ;) 46 | printf( "ORIGINAL DATA:\n%s\n", (char*)binaryData ) ; 47 | 48 | uint8_t *encrypted = (uint8_t *)malloc( blockSize ) ; 49 | size_t encryptedLen = blockSize ; // MUST set this to the size of encrypted, otherwise SecKeyEncrypt may fail. 50 | // Docs: "cipherTextLen: On entry, the size of the buffer provided in the cipherText parameter. On return, the amount of data actually placed in the buffer." 51 | SecCheck( SecKeyEncrypt( PUBLICKEY, kSecPaddingNone, binaryData, blockSize, encrypted, &encryptedLen ), 52 | "SecKeyEncrypt" ) ; 53 | free( binaryData ) ; 54 | 55 | printf( "ENCODED %d bytes => %lu bytes\n", blockSize, encryptedLen ) ; 56 | free( encrypted ) ; 57 | } 58 | 59 | @implementation ViewController 60 | 61 | - (void)viewDidLoad 62 | { 63 | [super viewDidLoad]; 64 | // Do any additional setup after loading the view, typically from a nib. 65 | } 66 | 67 | - (void)viewDidUnload 68 | { 69 | [super viewDidUnload]; 70 | // Release any retained subviews of the main view. 71 | // e.g. self.myOutlet = nil; 72 | } 73 | 74 | - (void)viewWillAppear:(BOOL)animated 75 | { 76 | [super viewWillAppear:animated]; 77 | testSecKey() ; 78 | } 79 | 80 | - (void)viewDidAppear:(BOOL)animated 81 | { 82 | [super viewDidAppear:animated]; 83 | } 84 | 85 | - (void)viewWillDisappear:(BOOL)animated 86 | { 87 | [super viewWillDisappear:animated]; 88 | } 89 | 90 | - (void)viewDidDisappear:(BOOL)animated 91 | { 92 | [super viewDidDisappear:animated]; 93 | } 94 | 95 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 96 | { 97 | // Return YES for supported orientations 98 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) 99 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 100 | else return YES; 101 | 102 | } 103 | 104 | - (void)didReceiveMemoryWarning 105 | { 106 | [super didReceiveMemoryWarning]; 107 | // Release any cached data, images, etc that aren't in use. 108 | } 109 | 110 | 111 | 112 | 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | iOSRSAPublicKeyEncryption describes how to encrypt data from a PUBLIC KEY in iOS using RSA. 2 | 3 | The main functions are in [SecKeyHelper.h](https://github.com/superwills/iOSRSAPublicKeyEncryption/blob/master/iOSRSA/SecKeyHelper.h): 4 | 5 | // Loads a certificate located at certPATH (usually in your bundle) 6 | SecKeyRef SecKeyFromPathAndSaveInKeyChain( NSString* certPATH, CFDataRef keyChainId ) 7 | 8 | // Loads a SecKeyRef from Keychain (that you previously loaded from some certPATH) 9 | SecKeyRef SecKeyFromKeyChain( CFDataRef keyChainId ) 10 | 11 | Example of how to use is in the `testSecKey` function in [ViewController.m](https://github.com/superwills/iOSRSAPublicKeyEncryption/blob/master/iOSRSA/ViewController.m) 12 | 13 | >       FACTS       14 | 15 | 1) YOU'RE NOT SUPPOSED TO LOAD PUBLIC KEYS IN IOS FROM 16 | ANYTHING OTHER THAN A "CERTIFICATE". NO BASE64 ENCODED 17 | ----- BEGIN PUBLIC KEY ------ STRINGS ARE SUPPORTED ON IOS BY DEFAULT. 18 | 19 | 2) CERTIFICATES ARE EASY TO CREATE USING OpenSSL OR certutil ON WINDOWS 20 | The basic steps are: 21 | 22 | 23 | HOW TO MAKE A CERTIFICATE 24 | 25 | 26 | ### Make the -----RSA PRIVATE KEY----- file in PEM format 27 | $ openssl genrsa -out privKey.pem 2048 28 | 29 | ### Make the -----CERTIFICATE REQUEST----- 30 | $ openssl req -new -key privKey.pem -out certReq.pem 31 | 32 | ### Make the actual -----CERTIFICATE----- 33 | $ openssl x509 -req -days 2000 -in certReq.pem -signkey privKey.pem -out certificate.pem 34 | 35 | ### Make the DER certificate.crt file from the certificate.pem 36 | $ openssl x509 -outform der -in certificate.pem -out certificate.cer 37 | 38 | SEE ALSO: [stackoverflow](http://stackoverflow.com/questions/9728799/using-an-rsa-public-key-on-/16096064#16096064) 39 | SEE ALSO: [OpenSSL HOWTO](http://www.openssl.org/docs/HOWTO/certificates.txt) 40 | 41 | DO NOT FOLLOW [WINGOFHERMES' METHOD](http://blog.wingsofhermes.org/?p=75) 42 | FOR LOADING PUBLIC KEYS FROM BASE64 CODED STRINGS. 43 | THIS IS NOT SUPPORTED FOR A __REASON__ AND IS NOT THE RECOMMENDED CODE PATH. 44 | 45 | YOU'VE BEEN WARNED. 46 | 47 | RELEVANT DEVFORUMS.APPLE THREADS: 48 | 49 | 1) [USE CERTIFICATES](https://devforums.apple.com/message/135272#135272): 50 | > In general we recommend that you distribute key material to 51 | clients as either a certificate (for public keys) or a PKCS#12 52 | (for private keys or identities). iPhone OS has good support 53 | for importing these types of data. 54 | 55 | 2) [IF YOU HAVE THE DER DATA, YOU CAN CREATE A CERTIFICATE](https://devforums.apple.com/message/135288#135288) 56 | > If you have a blob of data in DER form, you can create a SecCertificateRef 57 | from it using SecCertificateCreateWithData. Once you have a certificate ref, 58 | you can extract the public key using SecTrustCopyPublicKey. 59 | There's one gotcha with this, as explained in the following post. 60 | https://devforums.apple.com/message/114555#114555 61 | 62 | 3) [HOW TO LOAD A CERTIFICATE](https://devforums.apple.com/message/114555#114555) 63 | > This is surprisingly easy. You don't need to add the certificate 64 | to the keychain to handle this case. Rather, just load the 65 | certificate data (that is, the contents of a .cer file) in 66 | your application (you can either get this from your bundle 67 | or off the network) and then create a certificate ref using 68 | SecCertificateCreateWithData. From there you can extract a 69 | public key ref using a SecTrust object (SecTrustCreateWithCertificates, 70 | SecTrustEvaluate -- you can choose to ignore the resulting 71 | SecTrustResultType -- and SecTrustCopyPublicKey). 72 | And from there you can encrypt and verify using the 73 | SecKey APIs (SecKeyEncrypt, SecKeyRawVerify). 74 | 75 | # License 76 | 77 | The code in this package is released under the ZLib license. 78 | 79 | Copyright (C) 2013 William Sherif 80 | 81 | This software is provided 'as-is', without any express or implied 82 | warranty. In no event will the authors be held liable for any damages 83 | arising from the use of this software. 84 | 85 | Permission is granted to anyone to use this software for any purpose, 86 | including commercial applications, and to alter it and redistribute it 87 | freely, subject to the following restrictions: 88 | 89 | 1. The origin of this software must not be misrepresented; you must not 90 | claim that you wrote the original software. If you use this software 91 | in a product, an acknowledgment in the product documentation would be 92 | appreciated but is not required. 93 | 2. Altered source versions must be plainly marked as such, and must not be 94 | misrepresented as being the original software. 95 | 3. This notice may not be removed or altered from any source distribution. 96 | 97 | -------------------------------------------------------------------------------- /iOSRSA/SecKeyHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef SECKEYHELPER_H 2 | #define SECKEYHELPER_H 3 | 4 | /* 5 | 6 | The code in this package is released under the ZLib license. 7 | 8 | https://github.com/superwills/iOSRSAPublicKeyEncryption 9 | SecKeyHelper.h -- iOS public key helper functions 10 | version 1.0.0, April 21, 2013 11:47a 11 | version 1.0.1, Oct 11, 2013 2:10p /+ SecCRUD* operations 12 | 13 | 14 | Copyright (C) 2013 William Sherif 15 | 16 | This software is provided 'as-is', without any express or implied 17 | warranty. In no event will the authors be held liable for any damages 18 | arising from the use of this software. 19 | 20 | Permission is granted to anyone to use this software for any purpose, 21 | including commercial applications, and to alter it and redistribute it 22 | freely, subject to the following restrictions: 23 | 24 | 1. The origin of this software must not be misrepresented; you must not 25 | claim that you wrote the original software. If you use this software 26 | in a product, an acknowledgment in the product documentation would be 27 | appreciated but is not required. 28 | 2. Altered source versions must be plainly marked as such, and must not be 29 | misrepresented as being the original software. 30 | 3. This notice may not be removed or altered from any source distribution. 31 | 32 | William Sherif 33 | 34 | */ 35 | 36 | // 37 | // SecKeyHelper.h 38 | // iOSRSA 39 | // 40 | // Created by William Sherif on 4/20/13. 41 | // Copyright (c) 2013 William Sherif. All rights reserved. 42 | // 43 | 44 | // THIS FILE SHOWS HOW TO ENCRYPT FROM A PUBLIC KEY LOADED FROM A CERTIFICATE FILE. 45 | 46 | // 47 | //       FACTS       48 | // 49 | // 1) YOU'RE NOT SUPPOSED TO LOAD PUBLIC KEYS IN IOS FROM 50 | // ANYTHING OTHER THAN A "CERTIFICATE". NO BASE64 ENCODED 51 | // ----- BEGIN PUBLIC KEY ------ STRINGS ARE SUPPORTED ON IOS BY DEFAULT. 52 | // 2) CERTIFICATES ARE EASY TO CREATE USING OpenSSL OR certutil ON WINDOWS 53 | // The basic steps are: 54 | // 55 | // 56 | // HOW TO MAKE A CERTIFICATE 57 | // 58 | // 59 | // #Make the -----RSA PRIVATE KEY----- file in PEM format 60 | // $ openssl genrsa -out privKey.pem 2048 61 | // 62 | // #Make the -----CERTIFICATE REQUEST----- 63 | // $ openssl req -new -key privKey.pem -out certReq.pem 64 | // 65 | // #Make the actual -----CERTIFICATE----- 66 | // $ openssl x509 -req -days 2000 -in certReq.pem -signkey privKey.pem -out certificate.pem 67 | // 68 | // #Make the DER certificate.crt file from the certificate.pem 69 | // $ openssl x509 -outform der -in certificate.pem -out certificate.cer 70 | // SEE http://stackoverflow.com/questions/9728799/using-an-rsa-public-key-on-ios/16096064#16096064 71 | // SEE ALSO: OpenSSL HOWTO: http://www.openssl.org/docs/HOWTO/certificates.txt 72 | 73 | // DO NOT FOLLOW WINGOFHERMES' METHOD FOR LOADING PUBLIC KEYS FROM BASE64 ENCODED STRINGS. 74 | // THIS IS NOT SUPPORTED FOR A __REASON__ AND IS NOT THE RECOMMENDED CODE PATH. 75 | // 76 | // YOU'VE BEEN WARNED http://blog.wingsofhermes.org/?p=75 77 | 78 | // RELEVANT DEVFORUMS.APPLE THREADS: 79 | 80 | // 1) USE CERTIFICATES: 81 | // https://devforums.apple.com/message/135272#135272 82 | // In general we recommend that you distribute key material to 83 | // clients as either a certificate (for public keys) or a PKCS#12 84 | // (for private keys or identities). iPhone OS has good support 85 | // for importing these types of data. 86 | 87 | // 2) IF YOU HAVE THE DER DATA, YOU CAN CREATE A CERTIFICATE 88 | // https://devforums.apple.com/message/135288#135288 89 | // If you have a blob of data in DER form, you can create a SecCertificateRef 90 | // from it using SecCertificateCreateWithData. Once you have a certificate ref, 91 | // you can extract the public key using SecTrustCopyPublicKey. 92 | // There's one gotcha with this, as explained in the following post. 93 | // https://devforums.apple.com/message/114555#114555 94 | 95 | // 3) HOW TO LOAD A CERTIFICATE 96 | // https://devforums.apple.com/message/114555#114555 97 | // This is surprisingly easy. You don't need to add the certificate 98 | // to the keychain to handle this case. Rather, just load the 99 | // certificate data (that is, the contents of a .cer file) in 100 | // your application (you can either get this from your bundle 101 | // or off the network) and then create a certificate ref using 102 | // SecCertificateCreateWithData. From there you can extract a 103 | // public key ref using a SecTrust object (SecTrustCreateWithCertificates, 104 | // SecTrustEvaluate -- you can choose to ignore the resulting 105 | // SecTrustResultType -- and SecTrustCopyPublicKey). 106 | // And from there you can encrypt and verify using the 107 | // SecKey APIs (SecKeyEncrypt, SecKeyRawVerify). 108 | 109 | //  The base ctor is too large. 110 | CFMutableDictionaryRef CFMutableDictionaryCreateEmpty(); 111 | 112 | // We have to create the basic dictionary ref WITH THE SAME PROPERTIES ALL THE TIME. 113 | // If ONE of the properties doesn't match, you will get SecItemCopyMatching fails etc. 114 | CFMutableDictionaryRef CreateDefaultSECKEYDictionary( CFDataRef keyChainId ); 115 | 116 | // addressOfItem should be a pointer to a pointer. 117 | // For example, SecKeyRef is actually type __SecKeyRef*, 118 | // and if you take &SecKeyRef that will be a double pointer. 119 | CFArrayRef CFArrayCreateWithItem( void* addressOfItem ); 120 | 121 | // Sec* helper functions 122 | extern const char *SecTrustResultName[]; 123 | 124 | bool SecCheck( OSStatus res, const char* msg ); 125 | 126 | // 1. Loading a SecCertificateRef from a path. 127 | SecCertificateRef SecCertificateFromPath( NSString* certPATH ); 128 | 129 | // 2. Saving your loaded certificate in keychain, with a certain keyChainId. 130 | bool SecCertificateSaveInKeyChain( SecCertificateRef cert, CFDataRef keyChainId ); 131 | 132 | // 3. Creating a SecKeyRef from a loaded Certificate (either that 133 | // was loaded from disk, or loaded from Keychain.) 134 | SecKeyRef SecKeyFromCertificate( SecCertificateRef cert ); 135 | 136 | // 4. Loading a SecKey from a Certificate that was 137 | // previously stored in Keychain. 138 | SecKeyRef SecKeyFromKeyChain( CFDataRef keyChainId ); 139 | 140 | // 5. Easiest method to use: SecKeyFromPath, which 141 | // goes CERTPATH => CERTIFICATE => SECKEY 142 | SecKeyRef SecKeyFromPathAndSaveInKeyChain( NSString* certPATH, CFDataRef keyChainId ); 143 | 144 | // 6. You can also delete a key from the keychain if need be. 145 | bool SecCertificateDeleteFromKeyChain( CFDataRef keyChainId ); 146 | 147 | void SecCertificatePrintInfo( SecCertificateRef cert ); 148 | 149 | 150 | 151 | // Additional Sec* operations for CRUD data storage and retrieval (simple binary data) 152 | CFMutableDictionaryRef getKeylookup( const char* keyname ) ; 153 | 154 | // provides serialization and deserialization for static types 155 | template 156 | bool SecCreate( const char* keyname, const T* data ) 157 | { 158 | CFMutableDictionaryRef keyLookup = getKeylookup( keyname ) ; 159 | CFDataRef cfData = CFDataCreate( 0, (const UInt8*)data, sizeof(T) ) ; 160 | 161 | // store binary data (any CFDataRef) in kSecAttrGeneric 162 | // for a kSecClassGenericPassword type keychain entry 163 | CFDictionaryAddValue( keyLookup, kSecAttrGeneric, cfData ) ;// the actual data we want to store. 164 | bool success = SecCheck( SecItemAdd( keyLookup, NULL ), "SecItemAdd" ) ; 165 | CFRelease( cfData ) ; 166 | CFRelease( keyLookup ) ; 167 | return success ; 168 | } 169 | 170 | // You should know the len, as sizeof(T) 171 | template 172 | bool SecRead( const char* keyname, T* data ) 173 | { 174 | CFMutableDictionaryRef keyLookup = getKeylookup( keyname ) ; 175 | CFDictionaryAddValue( keyLookup, kSecReturnAttributes, kCFBooleanTrue ) ; // makes it return a DICTIONARY 176 | CFMutableDictionaryRef dataFromKeychain ; 177 | OSStatus res = SecItemCopyMatching( keyLookup, (CFTypeRef *)&dataFromKeychain ) ; 178 | CFRelease( keyLookup ) ; 179 | 180 | bool success = 0 ; 181 | 182 | if( res == noErr ) 183 | { 184 | CFDataRef cfData = (CFDataRef)CFDictionaryGetValue( dataFromKeychain, kSecAttrGeneric ) ; // the cfData doesn't need CFRELEASE 185 | // because it is just GETVALUE, NOT CREATE or COPY. See http://stackoverflow.com/questions/10203990/ 186 | 187 | const UInt8* datFromKC = CFDataGetBytePtr( cfData ) ; 188 | if( cfData ) 189 | { 190 | success = 1 ; // we succeeded in retrieving the data 191 | memcpy( data, datFromKC, sizeof( T ) ) ; // copy sizeof(T) bytes. 192 | // you're responsible to alloc `data`'s memory space. 193 | } 194 | else { puts( "ERR: kSecAttrGeneric field not set, no CFData" ) ; } // record found, but the kSecAttrGeneric field was not set 195 | 196 | CFRelease( dataFromKeychain ) ; 197 | return success ; // ok 198 | } //else {} // OTHER ERROR, such as NOT FOUND 199 | 200 | return success ; 201 | } 202 | 203 | // Attempts to update, fails if row didn't exist (so creates it) 204 | template 205 | bool SecUpdate( const char* keyname, const T* data ) 206 | { 207 | CFMutableDictionaryRef keyLookup = getKeylookup( keyname ) ; 208 | 209 | // wrap the kvp to change in a dictionary 210 | CFDataRef cfData = CFDataCreate( 0, (const UInt8*)data, sizeof(T) ) ; 211 | CFMutableDictionaryRef dataAttrib = CFMutableDictionaryCreateEmpty() ; 212 | CFDictionaryAddValue( dataAttrib, kSecAttrGeneric, cfData ) ; 213 | 214 | bool success = SecCheck( SecItemUpdate( keyLookup, dataAttrib ), "SecItemUpdate" ) ; 215 | CFRelease( keyLookup ) ; 216 | CFRelease( dataAttrib ) ; 217 | CFRelease( cfData ) ; 218 | 219 | return success ; 220 | } 221 | 222 | bool SecDelete( const char* keyname ) ; 223 | 224 | 225 | #endif 226 | -------------------------------------------------------------------------------- /iOSRSA/SecKeyHelper.mm: -------------------------------------------------------------------------------- 1 | #import "SecKeyHelper.h" 2 | 3 | //  The base ctor is too large. 4 | CFMutableDictionaryRef CFMutableDictionaryCreateEmpty() 5 | { 6 | return CFDictionaryCreateMutable( 0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ) ; 7 | } 8 | 9 | // We have to create the basic dictionary ref WITH THE SAME PROPERTIES ALL THE TIME. 10 | // If ONE of the properties doesn't match, you will get SecItemCopyMatching fails etc. 11 | CFMutableDictionaryRef CreateDefaultSECKEYDictionary( CFDataRef keyChainId ) 12 | { 13 | CFMutableDictionaryRef dic = CFMutableDictionaryCreateEmpty() ; 14 | 15 | // The kSecClass can be 1 of 5 types, kSecClassKey is to be used for cryptographic KEYS. 16 | // see the header defn for kSecClassKey and http://stackoverflow.com/questions/11614047/what-makes-a-keychain-item-unique-in-ios 17 | CFDictionaryAddValue( dic, kSecClass, kSecClassKey ) ; 18 | 19 | // Set up the application identifier tag, so keychain knows this key 20 | // is associated with our app. `keyChainId` is called `keychainIdStr` 21 | // (defined in ViewController.m). You just use the same application tag 22 | // for all keychain items that belong to the same app. The application tag 23 | // is like a KEYRING, __metaphorically speaking__. 24 | CFDictionaryAddValue( dic, kSecAttrApplicationTag, keyChainId ) ; 25 | 26 | // Now I tell you the TYPE of the key being RSA, (as opposed to kSecAttrKeyTypeEC, 27 | // which would be an "elliptic curve" encryption type key (which I've never heard of prior to looking it up here)). 28 | CFDictionaryAddValue( dic, kSecAttrKeyType, kSecAttrKeyTypeRSA ) ; 29 | 30 | //CFDictionaryAddValue( dic, kSecReturnPersistentRef, kCFBooleanTrue ) ; // This makes some things fail. Leave it off 31 | // and work in local program memory space. 32 | return dic ; 33 | } 34 | 35 | // addressOfItem should be a pointer to a pointer. 36 | // For example, SecKeyRef is actually type __SecKeyRef*, 37 | // and if you take &SecKeyRef that will be a double pointer. 38 | CFArrayRef CFArrayCreateWithItem( void* addressOfItem ) 39 | { 40 | return CFArrayCreate( 0, (const void**)addressOfItem, 1, &kCFTypeArrayCallBacks ) ; 41 | } 42 | 43 | // Sec* helper functions 44 | const char *SecTrustResultName[]={ 45 | "kSecTrustResultInvalid", 46 | "kSecTrustResultProceed", 47 | "kSecTrustResultConfirm", 48 | "kSecTrustResultDeny", 49 | "kSecTrustResultUnspecified", 50 | "kSecTrustResultRecoverableTrustFailure", 51 | "kSecTrustResultFatalTrustFailure", 52 | "kSecTrustResultOtherError" 53 | } ; 54 | 55 | bool SecCheck( OSStatus res, const char* msg ) 56 | { 57 | if( res==errSecSuccess ) 58 | { 59 | printf( "< %s okie dokie >\n", msg ) ; // COMMENT THIS OUT TO SILENCE OK's 60 | } 61 | else 62 | { 63 | printf( "< NOT OK!! >: %s FAILED:\n >> ", msg ) ; 64 | switch( res ) 65 | { 66 | case errSecUnimplemented: 67 | puts( "errSecUnimplemented: Function or operation not implemented." ) ; break; 68 | case errSecParam: 69 | puts( "errSecParam: One or more parameters passed to a function where not valid." ) ; break; 70 | case errSecAllocate: 71 | puts( "errSecAllocate: Failed to allocate memory." ) ; break; 72 | case errSecNotAvailable: 73 | puts( "errSecNotAvailable: No keychain is available. You may need to restart your computer." ) ; break; 74 | case errSecDuplicateItem: 75 | puts( "errSecDuplicateItem: The specified item already exists in the keychain." ) ; break; 76 | case errSecItemNotFound: 77 | puts( "errSecItemNotFound: The specified item could not be found in the keychain." ) ; break; 78 | case errSecInteractionNotAllowed: 79 | puts( "errSecInteractionNotAllowed: User interaction is not allowed." ) ; break; 80 | case errSecDecode: 81 | puts( "errSecDecode: Unable to decode the provided data." ) ; break; 82 | case errSecAuthFailed: 83 | puts( "errSecAuthFailed: The user name or passphrase you entered is not correct." ) ; break; 84 | default: 85 | puts( "UNDEFINED ERROR" ) ; break; 86 | } 87 | } 88 | return res == errSecSuccess ; 89 | } 90 | 91 | // 1. Loading a SecCertificateRef from a path. 92 | SecCertificateRef SecCertificateFromPath( NSString* certPATH ) 93 | { 94 | NSData* certData = [NSData dataWithContentsOfFile:certPATH]; 95 | if( ![certData length] ) { 96 | puts( "ERROR: certData length was 0" ) ; 97 | return NULL ; 98 | } 99 | 100 | SecCertificateRef cert = SecCertificateCreateWithData( NULL, (__bridge CFDataRef)certData ) ; 101 | if( !cert ) 102 | { 103 | puts( "ERROR: SecCertificateCreateWithData failed" ) ; 104 | return NULL ; 105 | } 106 | 107 | return cert ; 108 | } 109 | 110 | // 2. Saving your loaded certificate in keychain, with a certain keyChainId. 111 | bool SecCertificateSaveInKeyChain( SecCertificateRef cert, CFDataRef keyChainId ) 112 | { 113 | printf( "Adding `%s` to keychain..\n", CFDataGetBytePtr( keyChainId ) ) ; 114 | // First you make a DICTIONARY. It's not to look up security definitions like "what is AES" 115 | // but instead to define a set of {key:value} pairs (just like json) 116 | 117 | // I much prefer the syntax of CFDictionary here. It is SO much cleaner, 118 | // plus insertion goes "key, value" as opposed to value: forKey. 119 | CFMutableDictionaryRef dic = CreateDefaultSECKEYDictionary( keyChainId ) ; 120 | 121 | CFDataRef CERTDATA = SecCertificateCopyData( cert ) ; 122 | // Now add to that the certificate data. 123 | CFDictionaryAddValue( dic, kSecValueData, CERTDATA ) ; 124 | CFRelease( CERTDATA ) ; 125 | 126 | CFTypeRef persistPeer = NULL; 127 | return SecCheck( SecItemAdd(dic, &persistPeer), "SecItemAdd" ) ; 128 | } 129 | 130 | // 3. Creating a SecKeyRef from a loaded Certificate (either that 131 | // was loaded from disk, or loaded from Keychain.) 132 | SecKeyRef SecKeyFromCertificate( SecCertificateRef cert ) 133 | { 134 | CFArrayRef cfArray = CFArrayCreateWithItem( &cert ) ; 135 | 136 | SecPolicyRef secPolicyRef = SecPolicyCreateBasicX509() ; 137 | SecTrustRef secTrustRef ; 138 | SecCheck( SecTrustCreateWithCertificates( cfArray, secPolicyRef, &secTrustRef ), "SecTrustCreateWithCertificates" ) ; 139 | CFRelease( cfArray ) ; 140 | 141 | SecTrustResultType secTrustResult ; 142 | SecCheck( SecTrustEvaluate( secTrustRef, &secTrustResult ), "SecTrustEvaluate" ) ; 143 | 144 | printf( "SecTrustEvaluate RESULT: %s\n", SecTrustResultName[secTrustResult] ) ; 145 | 146 | SecKeyRef SECKEY = SecTrustCopyPublicKey( secTrustRef ) ; 147 | if( !SECKEY ) 148 | puts( "ERROR: SecTrustCopyPublicKey failed" ) ; 149 | 150 | return SECKEY ; 151 | } 152 | 153 | // 4. Loading a SecKey from a Certificate that was 154 | // previously stored in Keychain. 155 | SecKeyRef SecKeyFromKeyChain( CFDataRef keyChainId ) 156 | { 157 | printf( "Attempting to retrieve key `%s` from keychain..\n", CFDataGetBytePtr( keyChainId ) ) ; 158 | 159 | CFMutableDictionaryRef dic = CreateDefaultSECKEYDictionary( keyChainId ) ; 160 | CFDictionaryAddValue( dic, kSecReturnData, kCFBooleanTrue ) ; 161 | 162 | CFDataRef certDATA ; 163 | if( !SecCheck( SecItemCopyMatching( dic, (CFTypeRef *)&certDATA), "SecItemCopyMatching" ) ) 164 | return NULL ; // NO KEY! 165 | 166 | SecCertificateRef cert = SecCertificateCreateWithData( 0, certDATA ) ; 167 | if( !cert ) 168 | { 169 | puts( "ERROR: Your 'certificate data' is NOT a valid DER-encoded X.509 certificate" ) ; 170 | return NULL ; 171 | } 172 | return SecKeyFromCertificate( cert ) ; 173 | } 174 | 175 | // 5. Easiest method to use: SecKeyFromPath, which 176 | // goes CERTPATH => CERTIFICATE => SECKEY 177 | SecKeyRef SecKeyFromPathAndSaveInKeyChain( NSString* certPATH, CFDataRef keyChainId ) 178 | { 179 | SecCertificateRef cert = SecCertificateFromPath( certPATH ) ; 180 | 181 | if( !cert ) 182 | { 183 | printf( "ERROR: Could not load certificate at path `%s`," 184 | "Are you sure you added it to the XCode workspace?\n", [certPATH UTF8String] ) ; 185 | return NULL ; 186 | } 187 | 188 | // SAVE IT in keychain 189 | SecCertificateSaveInKeyChain( cert, keyChainId ) ; 190 | 191 | return SecKeyFromCertificate( cert ) ; 192 | } 193 | 194 | // 6. You can also delete a key from the keychain if need be. 195 | bool SecCertificateDeleteFromKeyChain( CFDataRef keyChainId ) 196 | { 197 | printf( "DELETING ITEM `%s`\n", CFDataGetBytePtr(keyChainId) ) ; 198 | CFMutableDictionaryRef dic = CreateDefaultSECKEYDictionary( keyChainId ) ; 199 | return SecCheck( SecItemDelete(dic), "SecItemDelete" ) ; 200 | } 201 | 202 | void SecCertificatePrintInfo( SecCertificateRef cert ) 203 | { 204 | CFStringRef certSummary = SecCertificateCopySubjectSummary( cert ); 205 | printf( "Certificate summary: %s\n", CFStringGetCStringPtr( certSummary, kCFStringEncodingMacRoman ) ) ; 206 | CFRelease(certSummary); 207 | } 208 | 209 | 210 | 211 | 212 | 213 | 214 | // Additional Sec* operations for CRUD data storage and retrieval (simple binary data) 215 | CFMutableDictionaryRef getKeylookup( const char* keyname ) 216 | { 217 | CFMutableDictionaryRef keyLookup = CFMutableDictionaryCreateEmpty() ; 218 | CFDictionaryAddValue( keyLookup, kSecClass, kSecClassGenericPassword ) ; // "generic password" for arbitrary binary data 219 | CFStringRef cfAccount = CFStringCreateWithCString( NULL, keyname, kCFStringEncodingMacRoman ) ; 220 | CFDictionaryAddValue( keyLookup, kSecAttrAccount, cfAccount ) ; // uniquely identify the row. 221 | CFRelease( cfAccount ) ; 222 | return keyLookup ; 223 | } 224 | 225 | bool SecDelete( const char* keyname ) 226 | { 227 | CFMutableDictionaryRef keyLookup = getKeylookup( keyname ) ; 228 | bool success = SecCheck( SecItemDelete( keyLookup ), "SecItemDelete" ) ; 229 | CFRelease( keyLookup ) ; 230 | return success ; 231 | } 232 | 233 | 234 | -------------------------------------------------------------------------------- /iOSRSA.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9F591B9F172094080099233C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F591B9E172094080099233C /* Security.framework */; }; 11 | 9FB75DFE172439C70034F81B /* SecKeyHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FB75DFD172439C70034F81B /* SecKeyHelper.mm */; }; 12 | 9FC427C51721B654001312D1 /* certificate.cer in Resources */ = {isa = PBXBuildFile; fileRef = 9FC427C41721B654001312D1 /* certificate.cer */; }; 13 | 9FE4977F172093DD00FFFDD1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FE4977E172093DD00FFFDD1 /* UIKit.framework */; }; 14 | 9FE49781172093DD00FFFDD1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FE49780172093DD00FFFDD1 /* Foundation.framework */; }; 15 | 9FE49783172093DD00FFFDD1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9FE49782172093DD00FFFDD1 /* CoreGraphics.framework */; }; 16 | 9FE49789172093DD00FFFDD1 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9FE49787172093DD00FFFDD1 /* InfoPlist.strings */; }; 17 | 9FE4978B172093DD00FFFDD1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9FE4978A172093DD00FFFDD1 /* main.m */; }; 18 | 9FE4978F172093DD00FFFDD1 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FE4978E172093DD00FFFDD1 /* AppDelegate.mm */; }; 19 | 9FE49791172093DD00FFFDD1 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FE49790172093DD00FFFDD1 /* Default.png */; }; 20 | 9FE49793172093DD00FFFDD1 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FE49792172093DD00FFFDD1 /* Default@2x.png */; }; 21 | 9FE49795172093DD00FFFDD1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9FE49794172093DD00FFFDD1 /* Default-568h@2x.png */; }; 22 | 9FE49798172093DD00FFFDD1 /* ViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9FE49797172093DD00FFFDD1 /* ViewController.mm */; }; 23 | 9FE4979B172093DD00FFFDD1 /* ViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9FE49799172093DD00FFFDD1 /* ViewController.xib */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 9F591B9E172094080099233C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 28 | 9FB75DFD172439C70034F81B /* SecKeyHelper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SecKeyHelper.mm; sourceTree = ""; }; 29 | 9FBF3BAB1723449B006AADD7 /* SecKeyHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecKeyHelper.h; sourceTree = ""; }; 30 | 9FC427C41721B654001312D1 /* certificate.cer */ = {isa = PBXFileReference; lastKnownFileType = file; name = certificate.cer; path = iOSRSA/certificate.cer; sourceTree = ""; }; 31 | 9FE4977B172093DD00FFFDD1 /* iOSRSA.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSRSA.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 9FE4977E172093DD00FFFDD1 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 33 | 9FE49780172093DD00FFFDD1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 34 | 9FE49782172093DD00FFFDD1 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 35 | 9FE49786172093DD00FFFDD1 /* iOSRSA-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iOSRSA-Info.plist"; sourceTree = ""; }; 36 | 9FE49788172093DD00FFFDD1 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 37 | 9FE4978A172093DD00FFFDD1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 38 | 9FE4978C172093DD00FFFDD1 /* iOSRSA-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iOSRSA-Prefix.pch"; sourceTree = ""; }; 39 | 9FE4978D172093DD00FFFDD1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 40 | 9FE4978E172093DD00FFFDD1 /* AppDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AppDelegate.mm; sourceTree = ""; }; 41 | 9FE49790172093DD00FFFDD1 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 42 | 9FE49792172093DD00FFFDD1 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 43 | 9FE49794172093DD00FFFDD1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 44 | 9FE49796172093DD00FFFDD1 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 45 | 9FE49797172093DD00FFFDD1 /* ViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewController.mm; sourceTree = ""; }; 46 | 9FE4979A172093DD00FFFDD1 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController.xib; sourceTree = ""; }; 47 | /* End PBXFileReference section */ 48 | 49 | /* Begin PBXFrameworksBuildPhase section */ 50 | 9FE49778172093DD00FFFDD1 /* Frameworks */ = { 51 | isa = PBXFrameworksBuildPhase; 52 | buildActionMask = 2147483647; 53 | files = ( 54 | 9F591B9F172094080099233C /* Security.framework in Frameworks */, 55 | 9FE4977F172093DD00FFFDD1 /* UIKit.framework in Frameworks */, 56 | 9FE49781172093DD00FFFDD1 /* Foundation.framework in Frameworks */, 57 | 9FE49783172093DD00FFFDD1 /* CoreGraphics.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 9FE49772172093DD00FFFDD1 = { 65 | isa = PBXGroup; 66 | children = ( 67 | 9FC427C41721B654001312D1 /* certificate.cer */, 68 | 9FE49784172093DD00FFFDD1 /* iOSRSA */, 69 | 9FE4977D172093DD00FFFDD1 /* Frameworks */, 70 | 9FE4977C172093DD00FFFDD1 /* Products */, 71 | ); 72 | sourceTree = ""; 73 | }; 74 | 9FE4977C172093DD00FFFDD1 /* Products */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 9FE4977B172093DD00FFFDD1 /* iOSRSA.app */, 78 | ); 79 | name = Products; 80 | sourceTree = ""; 81 | }; 82 | 9FE4977D172093DD00FFFDD1 /* Frameworks */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | 9F591B9E172094080099233C /* Security.framework */, 86 | 9FE4977E172093DD00FFFDD1 /* UIKit.framework */, 87 | 9FE49780172093DD00FFFDD1 /* Foundation.framework */, 88 | 9FE49782172093DD00FFFDD1 /* CoreGraphics.framework */, 89 | ); 90 | name = Frameworks; 91 | sourceTree = ""; 92 | }; 93 | 9FE49784172093DD00FFFDD1 /* iOSRSA */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 9FBF3BAB1723449B006AADD7 /* SecKeyHelper.h */, 97 | 9FB75DFD172439C70034F81B /* SecKeyHelper.mm */, 98 | 9FE49796172093DD00FFFDD1 /* ViewController.h */, 99 | 9FE49797172093DD00FFFDD1 /* ViewController.mm */, 100 | 9FE4978D172093DD00FFFDD1 /* AppDelegate.h */, 101 | 9FE4978E172093DD00FFFDD1 /* AppDelegate.mm */, 102 | 9FE49799172093DD00FFFDD1 /* ViewController.xib */, 103 | 9FE49785172093DD00FFFDD1 /* Supporting Files */, 104 | ); 105 | path = iOSRSA; 106 | sourceTree = ""; 107 | }; 108 | 9FE49785172093DD00FFFDD1 /* Supporting Files */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 9FE49786172093DD00FFFDD1 /* iOSRSA-Info.plist */, 112 | 9FE49787172093DD00FFFDD1 /* InfoPlist.strings */, 113 | 9FE4978A172093DD00FFFDD1 /* main.m */, 114 | 9FE4978C172093DD00FFFDD1 /* iOSRSA-Prefix.pch */, 115 | 9FE49790172093DD00FFFDD1 /* Default.png */, 116 | 9FE49792172093DD00FFFDD1 /* Default@2x.png */, 117 | 9FE49794172093DD00FFFDD1 /* Default-568h@2x.png */, 118 | ); 119 | name = "Supporting Files"; 120 | sourceTree = ""; 121 | }; 122 | /* End PBXGroup section */ 123 | 124 | /* Begin PBXNativeTarget section */ 125 | 9FE4977A172093DD00FFFDD1 /* iOSRSA */ = { 126 | isa = PBXNativeTarget; 127 | buildConfigurationList = 9FE4979E172093DD00FFFDD1 /* Build configuration list for PBXNativeTarget "iOSRSA" */; 128 | buildPhases = ( 129 | 9FE49777172093DD00FFFDD1 /* Sources */, 130 | 9FE49778172093DD00FFFDD1 /* Frameworks */, 131 | 9FE49779172093DD00FFFDD1 /* Resources */, 132 | ); 133 | buildRules = ( 134 | ); 135 | dependencies = ( 136 | ); 137 | name = iOSRSA; 138 | productName = iOSRSA; 139 | productReference = 9FE4977B172093DD00FFFDD1 /* iOSRSA.app */; 140 | productType = "com.apple.product-type.application"; 141 | }; 142 | /* End PBXNativeTarget section */ 143 | 144 | /* Begin PBXProject section */ 145 | 9FE49773172093DD00FFFDD1 /* Project object */ = { 146 | isa = PBXProject; 147 | attributes = { 148 | LastUpgradeCheck = 0460; 149 | ORGANIZATIONNAME = "William Sherif"; 150 | }; 151 | buildConfigurationList = 9FE49776172093DD00FFFDD1 /* Build configuration list for PBXProject "iOSRSA" */; 152 | compatibilityVersion = "Xcode 3.2"; 153 | developmentRegion = English; 154 | hasScannedForEncodings = 0; 155 | knownRegions = ( 156 | English, 157 | en, 158 | ); 159 | mainGroup = 9FE49772172093DD00FFFDD1; 160 | productRefGroup = 9FE4977C172093DD00FFFDD1 /* Products */; 161 | projectDirPath = ""; 162 | projectRoot = ""; 163 | targets = ( 164 | 9FE4977A172093DD00FFFDD1 /* iOSRSA */, 165 | ); 166 | }; 167 | /* End PBXProject section */ 168 | 169 | /* Begin PBXResourcesBuildPhase section */ 170 | 9FE49779172093DD00FFFDD1 /* Resources */ = { 171 | isa = PBXResourcesBuildPhase; 172 | buildActionMask = 2147483647; 173 | files = ( 174 | 9FE49789172093DD00FFFDD1 /* InfoPlist.strings in Resources */, 175 | 9FE49791172093DD00FFFDD1 /* Default.png in Resources */, 176 | 9FE49793172093DD00FFFDD1 /* Default@2x.png in Resources */, 177 | 9FE49795172093DD00FFFDD1 /* Default-568h@2x.png in Resources */, 178 | 9FE4979B172093DD00FFFDD1 /* ViewController.xib in Resources */, 179 | 9FC427C51721B654001312D1 /* certificate.cer in Resources */, 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | }; 183 | /* End PBXResourcesBuildPhase section */ 184 | 185 | /* Begin PBXSourcesBuildPhase section */ 186 | 9FE49777172093DD00FFFDD1 /* Sources */ = { 187 | isa = PBXSourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 9FE4978B172093DD00FFFDD1 /* main.m in Sources */, 191 | 9FE4978F172093DD00FFFDD1 /* AppDelegate.mm in Sources */, 192 | 9FE49798172093DD00FFFDD1 /* ViewController.mm in Sources */, 193 | 9FB75DFE172439C70034F81B /* SecKeyHelper.mm in Sources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | /* End PBXSourcesBuildPhase section */ 198 | 199 | /* Begin PBXVariantGroup section */ 200 | 9FE49787172093DD00FFFDD1 /* InfoPlist.strings */ = { 201 | isa = PBXVariantGroup; 202 | children = ( 203 | 9FE49788172093DD00FFFDD1 /* en */, 204 | ); 205 | name = InfoPlist.strings; 206 | sourceTree = ""; 207 | }; 208 | 9FE49799172093DD00FFFDD1 /* ViewController.xib */ = { 209 | isa = PBXVariantGroup; 210 | children = ( 211 | 9FE4979A172093DD00FFFDD1 /* en */, 212 | ); 213 | name = ViewController.xib; 214 | sourceTree = ""; 215 | }; 216 | /* End PBXVariantGroup section */ 217 | 218 | /* Begin XCBuildConfiguration section */ 219 | 9FE4979C172093DD00FFFDD1 /* Debug */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | ALWAYS_SEARCH_USER_PATHS = NO; 223 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 224 | CLANG_CXX_LIBRARY = "libc++"; 225 | CLANG_ENABLE_OBJC_ARC = YES; 226 | CLANG_WARN_CONSTANT_CONVERSION = YES; 227 | CLANG_WARN_EMPTY_BODY = YES; 228 | CLANG_WARN_ENUM_CONVERSION = YES; 229 | CLANG_WARN_INT_CONVERSION = YES; 230 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 231 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 232 | COPY_PHASE_STRIP = NO; 233 | GCC_C_LANGUAGE_STANDARD = gnu99; 234 | GCC_DYNAMIC_NO_PIC = NO; 235 | GCC_OPTIMIZATION_LEVEL = 0; 236 | GCC_PREPROCESSOR_DEFINITIONS = ( 237 | "DEBUG=1", 238 | "$(inherited)", 239 | ); 240 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 241 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 242 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 243 | GCC_WARN_UNUSED_VARIABLE = YES; 244 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 245 | ONLY_ACTIVE_ARCH = YES; 246 | SDKROOT = iphoneos; 247 | TARGETED_DEVICE_FAMILY = 2; 248 | }; 249 | name = Debug; 250 | }; 251 | 9FE4979D172093DD00FFFDD1 /* Release */ = { 252 | isa = XCBuildConfiguration; 253 | buildSettings = { 254 | ALWAYS_SEARCH_USER_PATHS = NO; 255 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 256 | CLANG_CXX_LIBRARY = "libc++"; 257 | CLANG_ENABLE_OBJC_ARC = YES; 258 | CLANG_WARN_CONSTANT_CONVERSION = YES; 259 | CLANG_WARN_EMPTY_BODY = YES; 260 | CLANG_WARN_ENUM_CONVERSION = YES; 261 | CLANG_WARN_INT_CONVERSION = YES; 262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 263 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 264 | COPY_PHASE_STRIP = YES; 265 | GCC_C_LANGUAGE_STANDARD = gnu99; 266 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 267 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 270 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 271 | SDKROOT = iphoneos; 272 | TARGETED_DEVICE_FAMILY = 2; 273 | VALIDATE_PRODUCT = YES; 274 | }; 275 | name = Release; 276 | }; 277 | 9FE4979F172093DD00FFFDD1 /* Debug */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 281 | GCC_PREFIX_HEADER = "iOSRSA/iOSRSA-Prefix.pch"; 282 | INFOPLIST_FILE = "iOSRSA/iOSRSA-Info.plist"; 283 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 284 | PRODUCT_NAME = "$(TARGET_NAME)"; 285 | WRAPPER_EXTENSION = app; 286 | }; 287 | name = Debug; 288 | }; 289 | 9FE497A0172093DD00FFFDD1 /* Release */ = { 290 | isa = XCBuildConfiguration; 291 | buildSettings = { 292 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 293 | GCC_PREFIX_HEADER = "iOSRSA/iOSRSA-Prefix.pch"; 294 | INFOPLIST_FILE = "iOSRSA/iOSRSA-Info.plist"; 295 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 296 | PRODUCT_NAME = "$(TARGET_NAME)"; 297 | WRAPPER_EXTENSION = app; 298 | }; 299 | name = Release; 300 | }; 301 | /* End XCBuildConfiguration section */ 302 | 303 | /* Begin XCConfigurationList section */ 304 | 9FE49776172093DD00FFFDD1 /* Build configuration list for PBXProject "iOSRSA" */ = { 305 | isa = XCConfigurationList; 306 | buildConfigurations = ( 307 | 9FE4979C172093DD00FFFDD1 /* Debug */, 308 | 9FE4979D172093DD00FFFDD1 /* Release */, 309 | ); 310 | defaultConfigurationIsVisible = 0; 311 | defaultConfigurationName = Release; 312 | }; 313 | 9FE4979E172093DD00FFFDD1 /* Build configuration list for PBXNativeTarget "iOSRSA" */ = { 314 | isa = XCConfigurationList; 315 | buildConfigurations = ( 316 | 9FE4979F172093DD00FFFDD1 /* Debug */, 317 | 9FE497A0172093DD00FFFDD1 /* Release */, 318 | ); 319 | defaultConfigurationIsVisible = 0; 320 | defaultConfigurationName = Release; 321 | }; 322 | /* End XCConfigurationList section */ 323 | }; 324 | rootObject = 9FE49773172093DD00FFFDD1 /* Project object */; 325 | } 326 | --------------------------------------------------------------------------------