]> git.saurik.com Git - apple/security.git/blob - certificates/ota_cert_tool/ios_ota_cert_tool/PSUtilities.m
Security-57031.1.35.tar.gz
[apple/security.git] / certificates / ota_cert_tool / ios_ota_cert_tool / PSUtilities.m
1 //
2 // PSUtilities.m
3 // ios_ota_cert_tool
4 //
5 // Created by James Murphy on 12/12/12.
6 // Copyright (c) 2012 James Murphy. All rights reserved.
7 //
8
9 #import "PSUtilities.h"
10 #import <Security/Security.h>
11
12 @implementation PSUtilities
13
14 + (void)outputError:(NSString *)message withError:(CFErrorRef)error
15 {
16 NSString* output = nil;
17 if (nil != error)
18 {
19 CFStringRef aCFStr = CFErrorCopyDescription(error);
20 if (NULL != aCFStr)
21 {
22 output = [NSString stringWithFormat:@"%@ error: %@", message, aCFStr];
23 CFRelease(aCFStr);
24 }
25 }
26
27 if (nil == output)
28 {
29 output = message;
30 }
31
32 NSLog(@"%@",output);
33 if (NULL != error)
34 {
35 CFRelease(error);
36 }
37 }
38
39 + (NSString *)digestAndEncode:(CFDataRef)cfData useSHA1:(BOOL)useSHA1;
40 {
41 CFErrorRef cfError = NULL;
42 NSString* result = nil;
43 CFTypeRef digestType = kSecDigestSHA2;
44 CFIndex digestLength = 256;
45
46 if (useSHA1)
47 {
48 digestType = kSecDigestSHA1;
49 digestLength = 0;
50 }
51
52 SecTransformRef digestXForm = SecDigestTransformCreate(digestType, digestLength, &cfError);
53 if (NULL != cfError)
54 {
55 CFRelease(cfData);
56 [PSUtilities outputError:@"Could not create the digesting transform." withError:cfError];
57 return result;
58 }
59
60 if (!SecTransformSetAttribute(digestXForm, kSecTransformInputAttributeName, cfData, &cfError))
61 {
62 CFRelease(cfData);
63 CFRelease(digestXForm);
64 [PSUtilities outputError:@"Could not set the input attribute" withError:cfError];
65 return result;
66 }
67
68 SecTransformRef base64Xform = SecEncodeTransformCreate(kSecBase64Encoding, &cfError);
69
70 if (NULL != cfError)
71 {
72 CFRelease(digestXForm);
73 [PSUtilities outputError:@"Could not create the encoding transform." withError:cfError];
74 return result;
75 }
76
77 SecGroupTransformRef groupXForm = SecTransformCreateGroupTransform();
78 if (NULL == groupXForm)
79 {
80 CFRelease(digestXForm);
81 CFRelease(base64Xform);
82 NSLog(@"Could not create the group transform");
83 return result;
84 }
85
86 SecTransformConnectTransforms(digestXForm, kSecTransformOutputAttributeName,
87 base64Xform, kSecTransformInputAttributeName,
88 groupXForm, &cfError);
89 CFRelease(digestXForm);
90 CFRelease(base64Xform);
91
92 if (NULL != cfError)
93 {
94 [PSUtilities outputError:@"Could not connect the transforms" withError:cfError];
95 return result;
96 }
97
98 CFDataRef cfResult = (CFDataRef)SecTransformExecute(groupXForm, &cfError);
99 CFRelease(groupXForm);
100 if (NULL != cfError)
101 {
102 [PSUtilities outputError:@"Could not execute the transform." withError:cfError];
103 return result;
104 }
105 const void* pPtr = (const void*)CFDataGetBytePtr(cfResult);
106 NSUInteger len = (NSUInteger)CFDataGetLength(cfResult);
107
108 NSData* temp_data = [[NSData alloc] initWithBytes:pPtr length:len];
109 result = [[NSString alloc] initWithData:temp_data encoding:NSUTF8StringEncoding];
110
111 return result;
112
113 }
114
115 + (CFDataRef)readFile:(NSString *)file_path
116 {
117 CFDataRef result = NULL;
118
119 @autoreleasepool
120 {
121 NSError* error = nil;
122
123 if (nil == file_path)
124 {
125 NSLog(@"PSUtilities.readFile called with a nil file path");
126 return result;
127
128 }
129
130 NSFileManager* fileManager = [NSFileManager defaultManager];
131 BOOL isDir = NO;
132 if (![fileManager fileExistsAtPath:file_path isDirectory:&isDir])
133 {
134 NSLog(@"PSUtilities.readFile %@ does not exist", file_path);
135 return result;
136 }
137
138 if (isDir)
139 {
140 NSLog(@"PSUtilities.readFile %@ does exist but it is a directory", file_path);
141 return result;
142 }
143
144
145 NSData* temp_data = [NSData dataWithContentsOfFile:file_path options:0 error:&error];
146 if (nil != error)
147 {
148 NSLog(@"NSData dataWithContentsOfFile returned error %@", file_path);
149 return result;
150 }
151
152 result = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)[temp_data bytes], (CFIndex)[temp_data length]);
153
154 }
155
156 return result;
157 }
158
159 + (SecCertificateRef)getCertificateFromData:(CFDataRef)data
160 {
161 SecCertificateRef result = NULL;
162 SecExternalFormat inputFormat = kSecFormatUnknown;
163 SecExternalItemType itemType = kSecItemTypeUnknown;
164 SecItemImportExportFlags flags = 0;
165 CFArrayRef outItems = NULL;
166
167 OSStatus err = SecKeychainItemImport(data, NULL, &inputFormat, &itemType, flags,
168 NULL, NULL, &outItems);
169 if (errSecSuccess != err)
170 {
171 NSLog(@"Could not import data");
172 }
173
174 if (NULL != outItems)
175 {
176 CFIndex num_items = CFArrayGetCount(outItems);
177 if (num_items > 0)
178 {
179 CFTypeRef anItem = (CFTypeRef)CFArrayGetValueAtIndex(outItems, 0);
180 if (NULL != anItem && (CFGetTypeID(anItem) == SecCertificateGetTypeID()))
181 {
182 result = (SecCertificateRef)anItem;
183 }
184 }
185
186 if (NULL != result)
187 {
188 CFRetain(result);
189 }
190 CFRelease(outItems);
191 }
192 return result;
193 }
194
195 + (CFDataRef)getKeyDataFromCertificate:(SecCertificateRef)cert
196 {
197 CFDataRef result = NULL;
198
199 if (NULL == cert)
200 {
201 return result;
202 }
203
204 SecKeyRef aPublicKey = NULL;
205 OSStatus err = SecCertificateCopyPublicKey(cert, &aPublicKey);
206 if (errSecSuccess == err && NULL != aPublicKey)
207 {
208 err = SecItemExport(aPublicKey, kSecFormatBSAFE, 0, NULL, &result);
209 if (errSecSuccess != err)
210 {
211 result = NULL;
212 }
213 CFRelease(aPublicKey);
214 }
215 return result;
216 }
217
218 + (SecKeyRef)getPrivateKeyWithName:(NSString *)keyName
219 {
220 SecKeyRef result = NULL;
221 NSArray* key_array = [NSArray arrayWithObjects:kSecClass, kSecAttrLabel, kSecReturnRef, nil];
222 NSArray* obj_array = [NSArray arrayWithObjects:kSecClassKey, keyName, kCFBooleanTrue, nil];
223 NSDictionary* query = [NSDictionary dictionaryWithObjects:obj_array forKeys:key_array];
224
225 OSStatus err = SecItemCopyMatching(CFBridgingRetain(query), (CFTypeRef *)&result);
226 if (errSecSuccess != err)
227 {
228 NSLog(@"Unable to find the Private Key");
229 }
230 return result;
231 }
232
233 + (NSString *)signAndEncode:(CFDataRef)data usingKey:(SecKeyRef)key useSHA1:(BOOL)useSHA1
234 {
235 NSString* result = nil;
236 if (NULL == data || NULL == key)
237 {
238 return result;
239 }
240
241 CFTypeRef digestType = kSecDigestHMACSHA2;
242 CFIndex digestLength = 256;
243
244 if (useSHA1)
245 {
246 digestType = kSecDigestSHA1;
247 digestLength = 0;
248 }
249
250 CFErrorRef error = NULL;
251 SecTransformRef signXForm = SecSignTransformCreate(key, &error);
252 if (NULL != error)
253 {
254 [PSUtilities outputError:@"Unable to create the signing transform" withError:error];
255 return result;
256 }
257
258 if (!SecTransformSetAttribute(signXForm, kSecTransformInputAttributeName, data, &error))
259 {
260 CFRelease(signXForm);
261 [PSUtilities outputError:@"Could not set the input attribute" withError:error];
262 return result;
263 }
264
265 if (!SecTransformSetAttribute(signXForm, kSecDigestTypeAttribute, digestType, &error))
266 {
267 CFRelease(signXForm);
268 [PSUtilities outputError:@"Unable to set the digest type attribute" withError:error];
269 return result;
270 }
271
272 CFNumberRef digest_length_number = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &digestLength);
273 if (!SecTransformSetAttribute(signXForm, kSecDigestLengthAttribute, digest_length_number, &error))
274 {
275 CFRelease(signXForm);
276 CFRelease(digest_length_number);
277 [PSUtilities outputError:@"Unable to set the digest length attribute" withError:error];
278 return result;
279 }
280 CFRelease(digest_length_number);
281
282 if (!SecTransformSetAttribute(signXForm, kSecInputIsAttributeName, kSecInputIsPlainText, &error))
283 {
284 CFRelease(signXForm);
285 [PSUtilities outputError:@"Unable to set the is plain text attribute" withError:error];
286 return result;
287 }
288
289 SecTransformRef base64Xform = SecEncodeTransformCreate(kSecBase64Encoding, &error);
290 if (NULL != error)
291 {
292 CFRelease(signXForm);
293 [PSUtilities outputError:@"Could not create the encoding transform." withError:error];
294 return result;
295 }
296
297 SecGroupTransformRef groupXForm = SecTransformCreateGroupTransform();
298 if (NULL == groupXForm)
299 {
300 CFRelease(signXForm);
301 CFRelease(base64Xform);
302 NSLog(@"Could not create the group transform");
303 return result;
304 }
305
306 SecTransformConnectTransforms(signXForm, kSecTransformOutputAttributeName,
307 base64Xform, kSecTransformInputAttributeName,
308 groupXForm, &error);
309 CFRelease(signXForm);
310 CFRelease(base64Xform);
311 if (NULL != error)
312 {
313 [PSUtilities outputError:@"Could connect the signing and encoding transforms." withError:error];
314 return result;
315 }
316
317 CFDataRef cfResult = (CFDataRef)SecTransformExecute(groupXForm, &error);
318 CFRelease(groupXForm);
319 if (NULL != error)
320 {
321 [PSUtilities outputError:@"Could not execute the transform." withError:error];
322 return result;
323 }
324 const void* pPtr = (const void*)CFDataGetBytePtr(cfResult);
325 NSUInteger len = (NSUInteger)CFDataGetLength(cfResult);
326
327 NSData* temp_data = [[NSData alloc] initWithBytes:pPtr length:len];
328 result = [[NSString alloc] initWithData:temp_data encoding:NSUTF8StringEncoding];
329 return result;
330 }
331
332
333 @end