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 */ 27typedef 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 361