]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_cryptkit/lib/NSCipherFile.m
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_cryptkit / lib / NSCipherFile.m
diff --git a/Security/libsecurity_cryptkit/lib/NSCipherFile.m b/Security/libsecurity_cryptkit/lib/NSCipherFile.m
new file mode 100644 (file)
index 0000000..93598d7
--- /dev/null
@@ -0,0 +1,360 @@
+/* Copyright (c) 1998,2011,2014 Apple 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, INC. AND THE
+ * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
+ * 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 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