]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/NSCipherFile.m
Security-57740.51.3.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / lib / NSCipherFile.m
1 /* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
2 *
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
10 *
11 * NSCipherFile.m - ObjC wrapper for feeCipherFile
12 *
13 * Revision History
14 * ----------------
15 * 28 Oct 96 at NeXT
16 * Created.
17 */
18
19 #import "NSCipherFile.h"
20 #import "feeCipherFile.h"
21 #import "falloc.h"
22 #import "NSFEEPublicKeyPrivate.h" /* for -feePubKey */
23
24 /*
25 * Private instance data.
26 */
27 typedef struct {
28 feeCipherFile cfile;
29 } _cfPriv;
30
31 @implementation NSCipherFile
32
33 - (void)dealloc
34 {
35 if(_priv) {
36 _cfPriv *cfPriv = _priv;
37 if(cfPriv->cfile) {
38 feeCFileFree(cfPriv->cfile);
39 }
40 }
41 [super dealloc];
42 }
43
44 /*
45 * Alloc and return an autoreleased NSCipherFile object associated with
46 * the specified data.
47 */
48 + newFromCipherText : (NSData *)cipherText
49 encrType : (cipherFileEncrType)encrType
50 sendPubKeyData : (NSData *)sendPubKeyData
51 otherKeyData : (NSData *)otherKeyData
52 sigData : (NSData *)sigData // optional; nil means no signature
53 userData : (unsigned)userData // for caller's convenience
54 {
55 NSCipherFile *result;
56 _cfPriv *cfPriv;
57
58 result = [[self alloc] autorelease];
59 result->_priv = cfPriv = fmalloc(sizeof(_cfPriv));
60 cfPriv->cfile = feeCFileNewFromCipherText(encrType,
61 [cipherText bytes],
62 [cipherText length],
63 [sendPubKeyData bytes],
64 [sendPubKeyData length],
65 [otherKeyData bytes],
66 [otherKeyData length],
67 [sigData bytes],
68 [sigData length],
69 userData);
70 if(cfPriv->cfile) {
71 return result;
72 }
73 else {
74 return nil;
75 }
76 }
77
78 /*
79 * Obtain the contents of a feeCipherFile as NSData.
80 */
81 - (NSData *)dataRepresentation
82 {
83 _cfPriv *cfPriv = _priv;
84 NSData *result;
85 const unsigned char *rep;
86 unsigned repLen;
87 feeReturn frtn;
88
89 if(cfPriv == NULL) {
90 return nil;
91 }
92 frtn = feeCFileDataRepresentation(cfPriv->cfile,
93 &rep,
94 &repLen);
95 if(frtn) {
96 return nil;
97 }
98 result = [NSData dataWithBytesNoCopy:(unsigned char *)rep
99 length:repLen];
100 return result;
101 }
102
103 /*
104 * Alloc and return an autoreleased NSCipherFile object given a data
105 * representation.
106 */
107 + newFromDataRepresentation : (NSData *)dataRep
108 {
109 NSCipherFile *result;
110 _cfPriv *cfPriv;
111 feeReturn frtn;
112
113 result = [[self alloc] autorelease];
114 result->_priv = cfPriv = fmalloc(sizeof(_cfPriv));
115 frtn = feeCFileNewFromDataRep([dataRep bytes],
116 [dataRep length],
117 &cfPriv->cfile);
118 if(frtn) {
119 return nil;
120 }
121 else {
122 return result;
123 }
124 }
125
126 /*
127 * Given an NSCipherFile object, obtain its constituent parts.
128 */
129 - (cipherFileEncrType)encryptionType
130 {
131 _cfPriv *cfPriv = _priv;
132
133 if(cfPriv == NULL) {
134 return CFE_Other;
135 }
136 return feeCFileEncrType(cfPriv->cfile);
137 }
138
139 - (NSData *)cipherText
140 {
141 _cfPriv *cfPriv = _priv;
142 const unsigned char *ctext;
143 unsigned ctextLen;
144
145 if(cfPriv == NULL) {
146 return nil;
147 }
148 ctext = feeCFileCipherText(cfPriv->cfile, &ctextLen);
149 return [NSData dataWithBytesNoCopy:(unsigned char *)ctext
150 length:ctextLen];
151 }
152
153 - (NSData *)sendPubKeyData
154 {
155 _cfPriv *cfPriv = _priv;
156 const unsigned char *key;
157 unsigned keyLen;
158
159 if(cfPriv == NULL) {
160 return nil;
161 }
162 key = feeCFileSendPubKeyData(cfPriv->cfile, &keyLen);
163 if(key) {
164 return [NSData dataWithBytesNoCopy:(unsigned char *)key
165 length:keyLen];
166 }
167 else {
168 return nil;
169 }
170 }
171
172 - (NSData *)otherKeyData
173 {
174 _cfPriv *cfPriv = _priv;
175 const unsigned char *key;
176 unsigned keyLen;
177
178 if(cfPriv == NULL) {
179 return nil;
180 }
181 key = feeCFileOtherKeyData(cfPriv->cfile, &keyLen);
182 if(key) {
183 return [NSData dataWithBytesNoCopy:(unsigned char *)key
184 length:keyLen];
185 }
186 else {
187 return nil;
188 }
189 }
190
191 - (NSData *)sigData
192 {
193 _cfPriv *cfPriv = _priv;
194 const unsigned char *sig;
195 unsigned sigLen;
196
197 if(cfPriv == NULL) {
198 return nil;
199 }
200 sig = feeCFileSigData(cfPriv->cfile, &sigLen);
201 if(sig) {
202 return [NSData dataWithBytesNoCopy:(unsigned char *)sig
203 length:sigLen];
204 }
205 else {
206 return nil;
207 }
208 }
209
210 - (unsigned)userData
211 {
212 _cfPriv *cfPriv = _priv;
213
214 if(cfPriv == NULL) {
215 return 0;
216 }
217 return feeCFileUserData(cfPriv->cfile);
218 }
219
220 /*
221 * High-level cipherFile support.
222 */
223
224 /*
225 * Create a cipherfile of specified cipherFileEncrType for given plaintext.
226 */
227 +(feeReturn)createCipherFileForPrivKey : (NSFEEPublicKey *)sendPrivKey
228 recvPubKey : (NSFEEPublicKey *)recvPubKey
229 encrType : (cipherFileEncrType)encrType
230 plainText : (NSData *)plainText
231 genSig : (BOOL)genSig
232 doEnc64 : (BOOL)doEnc64 // YES ==> perform enc64
233 userData : (unsigned)userData // for caller's convenience
234 cipherFileData : (NSData **)cipherFileData // RETURNED
235 {
236 feeReturn frtn;
237 unsigned char *cfileData;
238 unsigned cfileDataLen;
239 feePubKey privKey = NULL;
240
241 if(sendPrivKey) {
242 privKey = [sendPrivKey feePubKey];
243 }
244 frtn = createCipherFile(privKey,
245 [recvPubKey feePubKey],
246 encrType,
247 [plainText bytes],
248 [plainText length],
249 genSig,
250 doEnc64,
251 userData,
252 &cfileData,
253 &cfileDataLen);
254 if(frtn) {
255 return frtn;
256 }
257 *cipherFileData =
258 [NSData dataWithBytesNoCopy:(unsigned char *)cfileData
259 length:cfileDataLen];
260 return frtn;
261 }
262
263 /*
264 * Parse and decrypt a data representation of an NSCipherFile object.
265 */
266 + (feeReturn)parseCipherFileData : (NSFEEPublicKey *)recvPrivKey
267 sendPubKey : (NSFEEPublicKey *)sendPubKey
268 cipherFileData : (NSData *)cipherFileData
269 doDec64 : (BOOL)doDec64
270 encrType : (cipherFileEncrType *)encrType // RETURNED
271 plainText : (NSData **)plainText // RETURNED
272 sigStatus : (feeSigStatus *)sigStatus // RETURNED
273 sigSigner : (NSString **)sigSigner // RETURNED
274 userData : (unsigned *)userData // RETURNED
275 {
276 feeReturn frtn;
277 unsigned char *ptext;
278 unsigned ptextLen;
279 feeUnichar *signer;
280 unsigned signerLen;
281 feePubKey _pubKey = NULL;
282
283 if(recvPrivKey == nil) {
284 return FR_IllegalArg; // always required
285 }
286 if(sendPubKey) {
287 _pubKey = [sendPubKey feePubKey];
288 }
289
290 frtn = parseCipherFile([recvPrivKey feePubKey],
291 _pubKey,
292 [cipherFileData bytes],
293 [cipherFileData length],
294 doDec64,
295 encrType,
296 &ptext,
297 &ptextLen,
298 sigStatus,
299 &signer,
300 &signerLen,
301 userData);
302 if(frtn) {
303 return frtn;
304 }
305 *plainText = [NSData dataWithBytesNoCopy:ptext length:ptextLen];
306 *sigSigner = [NSString stringWithCharacters:signer length:signerLen];
307 ffree(signer);
308 return frtn;
309 }
310
311 /*
312 * Parse and decrypt an NSCipherFile object obtained via
313 * +newFromDataRepresentation.
314 *
315 * recvPrivKey is required in all cases. If sendPubKey is present,
316 * sendPubKey - rather than the embedded sender's public key - will be
317 * used for signature validation.
318 */
319 - (feeReturn)decryptCipherFileData : (NSFEEPublicKey *)recvPrivKey
320 sendPubKey : (NSFEEPublicKey *)sendPubKey
321 plainText : (NSData **)plainText // RETURNED
322 sigStatus : (feeSigStatus *)sigStatus // RETURNED
323 sigSigner : (NSString **)sigSigner // RETURNED
324 {
325 _cfPriv *cfPriv = _priv;
326 feeReturn frtn;
327 unsigned char *ptext;
328 unsigned ptextLen;
329 feeUnichar *signer;
330 unsigned signerLen;
331 feePubKey _pubKey = NULL;
332
333 if(cfPriv == NULL) {
334 return FR_IllegalArg;
335 }
336 if(recvPrivKey == nil) {
337 return FR_IllegalArg; // always required
338 }
339 if(sendPubKey) {
340 _pubKey = [sendPubKey feePubKey];
341 }
342
343 frtn = decryptCipherFile(cfPriv->cfile,
344 [recvPrivKey feePubKey],
345 _pubKey,
346 &ptext,
347 &ptextLen,
348 sigStatus,
349 &signer,
350 &signerLen);
351 if(frtn) {
352 return frtn;
353 }
354 *plainText = [NSData dataWithBytesNoCopy:ptext length:ptextLen];
355 *sigSigner = [NSString stringWithCharacters:signer length:signerLen];
356 ffree(signer);
357 return frtn;
358
359 }
360 @end