├── 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 |
--------------------------------------------------------------------------------