/* Copyright (c) 1998 Apple Computer, Inc. All rights reserved. * * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER, * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL * EXPOSE YOU TO LIABILITY. *************************************************************************** * * NSCipherFile.m - ObjC wrapper for feeCipherFile * * Revision History * ---------------- * 28 Oct 96 Doug Mitchell at NeXT * Created. */ #import "NSCipherFile.h" #import "feeCipherFile.h" #import "falloc.h" #import "NSFEEPublicKeyPrivate.h" /* for -feePubKey */ /* * Private instance data. */ typedef struct { feeCipherFile cfile; } _cfPriv; @implementation NSCipherFile - (void)dealloc { if(_priv) { _cfPriv *cfPriv = _priv; if(cfPriv->cfile) { feeCFileFree(cfPriv->cfile); } } [super dealloc]; } /* * Alloc and return an autoreleased NSCipherFile object associated with * the specified data. */ + newFromCipherText : (NSData *)cipherText encrType : (cipherFileEncrType)encrType sendPubKeyData : (NSData *)sendPubKeyData otherKeyData : (NSData *)otherKeyData sigData : (NSData *)sigData // optional; nil means no signature userData : (unsigned)userData // for caller's convenience { NSCipherFile *result; _cfPriv *cfPriv; result = [[self alloc] autorelease]; result->_priv = cfPriv = fmalloc(sizeof(_cfPriv)); cfPriv->cfile = feeCFileNewFromCipherText(encrType, [cipherText bytes], [cipherText length], [sendPubKeyData bytes], [sendPubKeyData length], [otherKeyData bytes], [otherKeyData length], [sigData bytes], [sigData length], userData); if(cfPriv->cfile) { return result; } else { return nil; } } /* * Obtain the contents of a feeCipherFile as NSData. */ - (NSData *)dataRepresentation { _cfPriv *cfPriv = _priv; NSData *result; const unsigned char *rep; unsigned repLen; feeReturn frtn; if(cfPriv == NULL) { return nil; } frtn = feeCFileDataRepresentation(cfPriv->cfile, &rep, &repLen); if(frtn) { return nil; } result = [NSData dataWithBytesNoCopy:(unsigned char *)rep length:repLen]; return result; } /* * Alloc and return an autoreleased NSCipherFile object given a data * representation. */ + newFromDataRepresentation : (NSData *)dataRep { NSCipherFile *result; _cfPriv *cfPriv; feeReturn frtn; result = [[self alloc] autorelease]; result->_priv = cfPriv = fmalloc(sizeof(_cfPriv)); frtn = feeCFileNewFromDataRep([dataRep bytes], [dataRep length], &cfPriv->cfile); if(frtn) { return nil; } else { return result; } } /* * Given an NSCipherFile object, obtain its constituent parts. */ - (cipherFileEncrType)encryptionType { _cfPriv *cfPriv = _priv; if(cfPriv == NULL) { return CFE_Other; } return feeCFileEncrType(cfPriv->cfile); } - (NSData *)cipherText { _cfPriv *cfPriv = _priv; const unsigned char *ctext; unsigned ctextLen; if(cfPriv == NULL) { return nil; } ctext = feeCFileCipherText(cfPriv->cfile, &ctextLen); return [NSData dataWithBytesNoCopy:(unsigned char *)ctext length:ctextLen]; } - (NSData *)sendPubKeyData { _cfPriv *cfPriv = _priv; const unsigned char *key; unsigned keyLen; if(cfPriv == NULL) { return nil; } key = feeCFileSendPubKeyData(cfPriv->cfile, &keyLen); if(key) { return [NSData dataWithBytesNoCopy:(unsigned char *)key length:keyLen]; } else { return nil; } } - (NSData *)otherKeyData { _cfPriv *cfPriv = _priv; const unsigned char *key; unsigned keyLen; if(cfPriv == NULL) { return nil; } key = feeCFileOtherKeyData(cfPriv->cfile, &keyLen); if(key) { return [NSData dataWithBytesNoCopy:(unsigned char *)key length:keyLen]; } else { return nil; } } - (NSData *)sigData { _cfPriv *cfPriv = _priv; const unsigned char *sig; unsigned sigLen; if(cfPriv == NULL) { return nil; } sig = feeCFileSigData(cfPriv->cfile, &sigLen); if(sig) { return [NSData dataWithBytesNoCopy:(unsigned char *)sig length:sigLen]; } else { return nil; } } - (unsigned)userData { _cfPriv *cfPriv = _priv; if(cfPriv == NULL) { return 0; } return feeCFileUserData(cfPriv->cfile); } /* * High-level cipherFile support. */ /* * Create a cipherfile of specified cipherFileEncrType for given plaintext. */ +(feeReturn)createCipherFileForPrivKey : (NSFEEPublicKey *)sendPrivKey recvPubKey : (NSFEEPublicKey *)recvPubKey encrType : (cipherFileEncrType)encrType plainText : (NSData *)plainText genSig : (BOOL)genSig doEnc64 : (BOOL)doEnc64 // YES ==> perform enc64 userData : (unsigned)userData // for caller's convenience cipherFileData : (NSData **)cipherFileData // RETURNED { feeReturn frtn; unsigned char *cfileData; unsigned cfileDataLen; feePubKey privKey = NULL; if(sendPrivKey) { privKey = [sendPrivKey feePubKey]; } frtn = createCipherFile(privKey, [recvPubKey feePubKey], encrType, [plainText bytes], [plainText length], genSig, doEnc64, userData, &cfileData, &cfileDataLen); if(frtn) { return frtn; } *cipherFileData = [NSData dataWithBytesNoCopy:(unsigned char *)cfileData length:cfileDataLen]; return frtn; } /* * Parse and decrypt a data representation of an NSCipherFile object. */ + (feeReturn)parseCipherFileData : (NSFEEPublicKey *)recvPrivKey sendPubKey : (NSFEEPublicKey *)sendPubKey cipherFileData : (NSData *)cipherFileData doDec64 : (BOOL)doDec64 encrType : (cipherFileEncrType *)encrType // RETURNED plainText : (NSData **)plainText // RETURNED sigStatus : (feeSigStatus *)sigStatus // RETURNED sigSigner : (NSString **)sigSigner // RETURNED userData : (unsigned *)userData // RETURNED { feeReturn frtn; unsigned char *ptext; unsigned ptextLen; feeUnichar *signer; unsigned signerLen; feePubKey _pubKey = NULL; if(recvPrivKey == nil) { return FR_IllegalArg; // always required } if(sendPubKey) { _pubKey = [sendPubKey feePubKey]; } frtn = parseCipherFile([recvPrivKey feePubKey], _pubKey, [cipherFileData bytes], [cipherFileData length], doDec64, encrType, &ptext, &ptextLen, sigStatus, &signer, &signerLen, userData); if(frtn) { return frtn; } *plainText = [NSData dataWithBytesNoCopy:ptext length:ptextLen]; *sigSigner = [NSString stringWithCharacters:signer length:signerLen]; ffree(signer); return frtn; } /* * Parse and decrypt an NSCipherFile object obtained via * +newFromDataRepresentation. * * recvPrivKey is required in all cases. If sendPubKey is present, * sendPubKey - rather than the embedded sender's public key - will be * used for signature validation. */ - (feeReturn)decryptCipherFileData : (NSFEEPublicKey *)recvPrivKey sendPubKey : (NSFEEPublicKey *)sendPubKey plainText : (NSData **)plainText // RETURNED sigStatus : (feeSigStatus *)sigStatus // RETURNED sigSigner : (NSString **)sigSigner // RETURNED { _cfPriv *cfPriv = _priv; feeReturn frtn; unsigned char *ptext; unsigned ptextLen; feeUnichar *signer; unsigned signerLen; feePubKey _pubKey = NULL; if(cfPriv == NULL) { return FR_IllegalArg; } if(recvPrivKey == nil) { return FR_IllegalArg; // always required } if(sendPubKey) { _pubKey = [sendPubKey feePubKey]; } frtn = decryptCipherFile(cfPriv->cfile, [recvPrivKey feePubKey], _pubKey, &ptext, &ptextLen, sigStatus, &signer, &signerLen); if(frtn) { return frtn; } *plainText = [NSData dataWithBytesNoCopy:ptext length:ptextLen]; *sigSigner = [NSString stringWithCharacters:signer length:signerLen]; ffree(signer); return frtn; } @end