]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/Security/SecExternalRep.cpp
Security-57336.10.29.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / Security / SecExternalRep.cpp
diff --git a/OSX/libsecurity_keychain/Security/SecExternalRep.cpp b/OSX/libsecurity_keychain/Security/SecExternalRep.cpp
deleted file mode 100644 (file)
index 14784c1..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (c) 2004,2011,2013-2014 Apple Inc. All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- *
- * SecExternalRep.cpp - private class representing an external representation of
- *                                         a SecKeychainItemRef, used by SecImportExport.h
- */
-
-#include "SecExternalRep.h"
-#include "SecImportExportPem.h"
-#include "SecImportExportAgg.h"
-#include "SecImportExportUtils.h"
-#include "SecImportExportPkcs8.h"
-#include "SecImportExportCrypto.h"
-#include "SecImportExportOpenSSH.h"
-#include <security_utilities/errors.h>
-#include <Security/SecBase.h>
-#include <Security/SecKeyPriv.h>
-#include <Security/SecCertificate.h>
-#include <Security/cssmapi.h>
-
-using namespace Security;
-using namespace KeychainCore;
-
-
-#pragma mark --- SecExportRep Subclasses seen only by SecExportRep::vend() ---
-
-namespace SecExport {
-
-class Key : public SecExportRep 
-{
-       friend class SecExportRep;
-protected:
-       Key(
-               CFTypeRef                                               kcItemRef);
-       ~Key();
-       OSStatus exportRep(
-               SecExternalFormat                                       format, 
-               SecItemImportExportFlags                        flags,  
-               const SecKeyImportExportParameters      *keyParams,             // optional 
-               CFMutableDataRef                                        outData,                // data appended here
-               const char                                                      **pemHeader);   // e.g., "RSA PUBLIC KEY"
-               
-private:
-       CSSM_ALGORITHMS                                         mKeyAlg;        
-       const CSSM_KEY                                          *mCssmKey;      
-};
-
-class Cert : public SecExportRep 
-{
-       friend class SecExportRep;
-protected:
-       Cert(
-               CFTypeRef                                               kcItemRef);
-       ~Cert();
-       OSStatus exportRep(
-               SecExternalFormat                                       format, 
-               SecItemImportExportFlags                        flags,  
-               const SecKeyImportExportParameters      *keyParams,             // optional 
-               CFMutableDataRef                                        outData,                // data appended here
-               const char                                                      **pemHeader);   // e.g., "CERTIFICATE"
-};
-
-}   /* namespace SecExport */
-
-#pragma mark --- SecExportRep: Representation of an internal object on export ---
-
-SecExportRep::SecExportRep(
-       CFTypeRef                       kcItemRef) :
-               mKcItem((SecKeychainItemRef)kcItemRef),
-               mPemParamLines(NULL)
-{
-       CFRetain(mKcItem);
-}
-
-SecExportRep::~SecExportRep()
-{
-       if(mKcItem) {
-               CFRelease(mKcItem);
-       }
-       if(mPemParamLines) {
-               CFRelease(mPemParamLines);
-       }
-}
-
-SecExportRep::SecExportRep() {
-       MacOSError::throwMe(errSecInvalidItemRef);
-}
-
-/* must be implemented by subclass */
-OSStatus SecExportRep::exportRep(
-       SecExternalFormat                                       format, 
-       SecItemImportExportFlags                        flags,  
-       const SecKeyImportExportParameters      *keyParams,             // optional 
-       CFMutableDataRef                                        outData,                // data appended here
-       const char                                                      **pemHeader)    // e.g., "X509 CERTIFICATE"
-{
-       MacOSError::throwMe(errSecInvalidItemRef);
-}
-
-/*
- * Sole public means of obtaining a SecExportRep object. In fact only instances
- * of subclasses are vended but caller does not know that.
- * 
- * Gleans SecExternalItemType from incoming type, throws MacOSError if
- * incoming type is bogus.
- *
- * Vended object holds a reference to kcItem for its lifetime. 
- */
-SecExportRep *SecExportRep::vend(      
-       CFTypeRef                                               kcItemRef)
-{
-       CFTypeID itemType = CFGetTypeID(kcItemRef);
-       if(itemType == SecCertificateGetTypeID()) {
-               return new SecExport::Cert(kcItemRef);
-       }
-       else if(itemType == SecKeyGetTypeID()) {
-               return new SecExport::Key(kcItemRef);
-       }
-       else {
-               MacOSError::throwMe(errSecInvalidItemRef);
-       }
-}
-
-#pragma mark --- Key External rep ---
-
-SecExport::Key::Key(
-       CFTypeRef kcItemRef) :
-               SecExportRep(kcItemRef)
-{
-       
-       /* figure out if it's public, private, or session */
-       OSStatus ortn;
-       ortn = SecKeyGetCSSMKey((SecKeyRef)kcItemRef, &mCssmKey);
-       if(ortn) {
-               SecImpExpDbg("SecKeyGetCSSMKey failure in SecExportRep::Key()");
-               MacOSError::throwMe(ortn);
-       }
-       switch(mCssmKey->KeyHeader.KeyClass) {
-               case CSSM_KEYCLASS_PUBLIC_KEY:
-                       mExternType = kSecItemTypePublicKey;
-                       SecImpExpDbg("SecExportRep::Key(): SET_PubKey");
-                       break;
-               case CSSM_KEYCLASS_PRIVATE_KEY:
-                       mExternType = kSecItemTypePrivateKey;
-                       SecImpExpDbg("SecExportRep::Key(): SET_PrivKey");
-                       break;
-               case CSSM_KEYCLASS_SESSION_KEY:
-                       mExternType = kSecItemTypeSessionKey;
-                       SecImpExpDbg("SecExportRep::Key(): SET_SessionKey");
-                       break;
-               default:
-                       SecImpExpDbg("SecExportRep::Key(): invalid KeyClass (%lu)",  
-                               (unsigned long)mCssmKey->KeyHeader.KeyClass);
-                       MacOSError::throwMe(errSecInvalidItemRef);
-       }
-       mKeyAlg = mCssmKey->KeyHeader.AlgorithmId;
-}
-
-SecExport::Key::~Key()
-{
-       /* nothing for now */
-}
-
-/* 
- * The heart of this class: cook up external representation, appending to 
- * existing CFMutableDataRef.
- */
-OSStatus SecExport::Key::exportRep(
-       SecExternalFormat                                       format, 
-       SecItemImportExportFlags                        flags,                  
-       const SecKeyImportExportParameters      *keyParams,     // optional 
-       CFMutableDataRef                                        outData,        // data appended here
-       const char                                                      **pemHeader)// e.g., "X509 CERTIFICATE"
-{
-       assert(outData != NULL);
-       assert(mKcItem != NULL);
-       assert(mCssmKey != NULL);
-               
-       /*
-        * Currently only OpsnSSH formats allow for a DescriptiveData field
-        * in either wrapped or NULL wrap forms. (In OpenSSH parlance this is 
-        * the 'comment' field). Infer the DescriptiveData to be embedded
-        * in the exported key from the item's PrintName attribute.
-        */
-       CssmAutoData descrData(Allocator::standard());
-       switch(format) {
-               case kSecFormatSSH:
-               case kSecFormatSSHv2:
-               case kSecFormatWrappedSSH:
-                       impExpOpensshInferDescData((SecKeyRef)mKcItem, descrData);
-                       break;
-               default:
-                       break;
-       }
-       
-       /* 
-        * Handle wrapped key formats. 
-        */
-       switch(format) {
-               case kSecFormatWrappedPKCS8:
-                       return impExpPkcs8Export((SecKeyRef)mKcItem, flags, keyParams,
-                               outData, pemHeader);
-               case kSecFormatWrappedOpenSSL:
-                       return impExpWrappedKeyOpenSslExport((SecKeyRef)mKcItem, flags, keyParams,
-                               outData, pemHeader, &mPemParamLines);
-               case kSecFormatWrappedSSH:
-                       return impExpWrappedOpenSSHExport((SecKeyRef)mKcItem, flags, keyParams, 
-                               descrData, outData);
-               case kSecFormatWrappedLSH:
-                       return errSecUnsupportedFormat;
-               default:
-                       break;
-       }
-       
-       /* 
-        * Remaining formats just do a NULL key wrap. Figure out the appropriate
-        * CDSA-specific format and wrap parameters. 
-        */
-       OSStatus ortn = errSecSuccess;
-       CSSM_KEYBLOB_FORMAT blobForm;
-       
-       switch(mExternType) {
-               case kSecItemTypePublicKey:
-                       switch(mKeyAlg) {
-                               case CSSM_ALGID_RSA:
-                                       *pemHeader = PEM_STRING_RSA_PUBLIC;
-                                       break;  
-                               case CSSM_ALGID_DH:
-                                       *pemHeader = PEM_STRING_DH_PUBLIC;
-                                       break;  
-                               case CSSM_ALGID_DSA:
-                                       *pemHeader = PEM_STRING_DSA_PUBLIC;
-                                       break; 
-                               case CSSM_ALGID_ECDSA:
-                                       *pemHeader = PEM_STRING_ECDSA_PUBLIC;
-                                       break; 
-                               default:
-                                       SecImpExpDbg("SecExportRep::exportRep unknown public key alg %lu",
-                                               (unsigned long)mKeyAlg);
-                                       return errSecUnsupportedFormat;
-                       }               /* end switch(mKeyAlg) */
-                       break;  /* from case externType kSecItemTypePublicKey */
-                       
-               case kSecItemTypePrivateKey:
-                       switch(mKeyAlg) {
-                               case CSSM_ALGID_RSA:
-                                       *pemHeader = PEM_STRING_RSA;
-                                       break; 
-                               case CSSM_ALGID_DH:
-                                       *pemHeader = PEM_STRING_DH_PRIVATE;
-                                       break; 
-                               case CSSM_ALGID_DSA:
-                                       *pemHeader = PEM_STRING_DSA;
-                                       break; 
-                               case CSSM_ALGID_ECDSA:
-                                       *pemHeader = PEM_STRING_ECDSA_PRIVATE;
-                                       break; 
-                               default:
-                                       SecImpExpDbg("SecExportRep::exportRep unknown private key alg "
-                                               "%lu", (unsigned long)mKeyAlg);
-                                       return errSecUnsupportedFormat;
-                       }               /* end switch(mKeyAlg) */
-                       break;  /* from case externType kSecItemTypePrivateKey */
-                       
-               case kSecItemTypeSessionKey:
-                       *pemHeader = PEM_STRING_SESSION;
-                       break; 
-               default:
-                       assert(0);
-                       return errSecInvalidItemRef;
-       }   /* switch(mExternType) */
-       
-       /* Map our external params to CDSA blob format */
-       CSSM_KEYCLASS keyClass;
-       ortn = impExpKeyForm(format, mExternType, mKeyAlg, &blobForm, &keyClass);
-       if(ortn) {
-               return ortn;
-       }
-
-       /* Specify format of null-wrapped key */
-       CSSM_ATTRIBUTE_TYPE formatAttrType = CSSM_ATTRIBUTE_NONE;
-       switch(mExternType) {
-               case kSecItemTypePrivateKey:
-                       formatAttrType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT;
-                       break;
-               case kSecItemTypePublicKey:
-                       formatAttrType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT;
-                       break;
-               /* symmetric key doesn't have a format */
-               default:
-                       break;
-       }
-       
-       CSSM_CSP_HANDLE cspHand;
-       ortn = SecKeyGetCSPHandle((SecKeyRef)mKcItem, &cspHand);
-       if(ortn) {
-               SecImpExpDbg("SecExportRep::exportRep SecKeyGetCSPHandle error");
-               return ortn;
-       }
-
-       /* perform the NULL wrap --> wrapped Key */
-       CSSM_KEY wrappedKey;
-       memset(&wrappedKey, 0, sizeof(wrappedKey));
-       const CSSM_DATA &dd = descrData;
-       ortn = impExpExportKeyCommon(cspHand, 
-               (SecKeyRef)mKcItem, 
-               NULL,                                                   // wrappingKey not used for NULL
-               &wrappedKey,                                    // destination
-               CSSM_ALGID_NONE,                                
-               CSSM_ALGMODE_NONE, 
-               CSSM_PADDING_NONE,
-               CSSM_KEYBLOB_WRAPPED_FORMAT_NONE, 
-               formatAttrType,
-               blobForm,
-               &dd,                                                    // descriptiveData
-               NULL);                                                  // IV
-               
-       if(ortn == CSSM_OK) {
-               /* pass key data back to caller */
-               CFDataAppendBytes(outData, wrappedKey.KeyData.Data, wrappedKey.KeyData.Length);
-       }
-       CSSM_FreeKey(cspHand, NULL, &wrappedKey, CSSM_FALSE);
-       return ortn;
-}
-
-#pragma mark --- Certificate External rep ---
-
-SecExport::Cert::Cert(
-       CFTypeRef kcItemRef) :
-               SecExportRep(kcItemRef)
-{
-       mExternType = kSecItemTypeCertificate;
-}
-
-SecExport::Cert::~Cert()
-{
-       /* nothing for now */
-}
-
-/* 
- * The heart of this class: cook up external representation, appending to 
- * existing CFMutableDataRef.
- */
-OSStatus SecExport::Cert::exportRep(
-       SecExternalFormat                                       format, 
-       SecItemImportExportFlags                        flags,                  
-       const SecKeyImportExportParameters      *keyParams,     // optional 
-       CFMutableDataRef                                        outData,        // data appended here
-       const char                                                      **pemHeader)// e.g., "X509 CERTIFICATE"
-{
-       assert(outData != NULL);
-       assert(mKcItem != NULL);
-               
-       switch(format) {
-               case kSecFormatUnknown:         // default
-               case kSecFormatX509Cert:        // currently, only supported format
-                       break;
-               default:
-                       SecImpExpDbg("SecExportRep::exportRep unsupported format for cert");
-                       return errSecUnsupportedFormat;
-       }
-       
-       CFDataRef cdata = SecCertificateCopyData((SecCertificateRef)mKcItem);
-       if(!cdata) {
-               SecImpExpDbg("SecExportRep::exportRep SecCertificateGetData error");
-               return errSecUnsupportedFormat;
-       }
-
-       CFDataAppendBytes(outData, CFDataGetBytePtr(cdata), CFDataGetLength(cdata));
-       CFRelease(cdata);
-       *pemHeader = PEM_STRING_X509;
-       return errSecSuccess;
-}
-       
-#pragma mark --- SecImportRep: Representation of an external object on import ---
-
-/* 
- * for import, when we have the external representation.
- * All arguments except for the CFDataRef are optional (i.e., "unknown"
- * is legal).
- */
-SecImportRep::SecImportRep(
-       CFDataRef                                               external,
-       SecExternalItemType                             externType,             // may be unknown 
-       SecExternalFormat                               externFormat,   // may be unknown
-       CSSM_ALGORITHMS                                 keyAlg,                 // may be unknown, CSSM_ALGID_NONE
-       CFArrayRef                                              pemParamLines /* = NULL */ ) :
-               mPrintName(NULL),
-               mExternal(external),
-               mExternType(externType),
-               mExternFormat(externFormat),
-               mKeyAlg(keyAlg),
-               mPemParamLines(pemParamLines)
-{
-       CFRetain(mExternal);
-}
-
-SecImportRep::~SecImportRep()
-{
-       if(mPrintName) {
-               free(mPrintName);
-       }
-       if(mExternal) {
-               CFRelease(mExternal);
-       }
-       if(mPemParamLines) {
-               CFRelease(mPemParamLines);
-       }
-}
-
-/* 
- * Convert to one or more SecItemRefs and/or import to keychain.
- * The cspHand handle MUST be a CSPDL handle, not a raw CSP handle. 
- */
-OSStatus SecImportRep::importRep(
-       SecKeychainRef                                          importKeychain,         // optional
-       CSSM_CSP_HANDLE                                         cspHand,                        // required
-       SecItemImportExportFlags                        flags,
-       const SecKeyImportExportParameters      *keyParams,                     // optional 
-       ImpPrivKeyImportState                           &keyImportState,        // IN/OUT
-       CFMutableArrayRef                                       outArray)                       // optional, append here 
-{
-       /* caller must have sorted this out by now */
-       assert((mExternType != kSecItemTypeUnknown) &&
-                  (mExternFormat != kSecFormatUnknown));
-                  
-       /* app could conceivably botch these with crafty PEM hacking */
-       if((mExternal == NULL) || (CFDataGetLength(mExternal) == 0)) {
-               return errSecParam;
-       }
-       
-       /* handle the easy ones first */
-       switch(mExternFormat) {
-               case kSecFormatPKCS12:
-                       return impExpPkcs12Import(mExternal, flags, keyParams, 
-                               keyImportState, importKeychain, cspHand, outArray);
-               case kSecFormatX509Cert:
-               case kSecFormatPKCS7:
-               {
-                       OSStatus rx = impExpPkcs7Import(mExternal, flags, keyParams, importKeychain, 
-                                       outArray);
-                       if (rx == errSecUnknownFormat)
-                       {
-                               CSSM_DATA cdata;
-                               cdata.Data = (uint8 *)CFDataGetBytePtr(mExternal);
-                               cdata.Length = (CSSM_SIZE)CFDataGetLength(mExternal);
-                               return impExpImportCertCommon(&cdata, importKeychain, outArray);
-                       }
-                       return rx;
-               }
-               case kSecFormatNetscapeCertSequence:
-                       return impExpNetscapeCertImport(mExternal, flags, keyParams, importKeychain,
-                               outArray);
-               default:
-                       break;
-       }
-               
-       if((mExternType == kSecItemTypeCertificate) || 
-          (mExternType == kSecItemTypeAggregate)) {
-               SecImpExpDbg("SecImportRep::importRep screwup");
-               return errSecUnimplemented;
-       }
-
-       /* 
-        * All that's left: keys. 
-        */
-       if((mExternType == kSecItemTypePrivateKey) && (keyImportState == PIS_NoMore)) {
-               /* multi key import against caller's wishes */
-               return errSecMultiplePrivKeys;
-       }
-
-       /* optionally infer PrintName attribute */
-       switch(mExternFormat) {
-               case kSecFormatSSH:
-               case kSecFormatWrappedSSH:
-               case kSecFormatSSHv2:
-                       mPrintName = impExpOpensshInferPrintName(mExternal, mExternType, mExternFormat);
-                       break;
-               default:
-                       /* use defaults */
-                       break;
-       }
-       
-       OSStatus ortn = errSecSuccess;
-       
-       switch(mExternFormat) {
-               case kSecFormatOpenSSL:
-               case kSecFormatSSH:     
-               case kSecFormatSSHv2:
-               case kSecFormatBSAFE:
-               case kSecFormatRawKey:
-            if(mExternal != NULL || CFDataGetLength(mExternal) != 0){
-                ortn = impExpImportRawKey(mExternal, mExternFormat, mExternType,
-                                          mKeyAlg, importKeychain, cspHand, flags, keyParams, mPrintName, outArray);
-            }
-            else{
-                MacOSError::throwMe(errSecUnsupportedKeySize);
-            }
-            break;
-               case kSecFormatWrappedPKCS8:
-                       ortn = impExpPkcs8Import(mExternal, importKeychain, cspHand, flags,
-                               keyParams, outArray);
-                       break;
-               case kSecFormatWrappedOpenSSL:
-                       ortn =  importWrappedKeyOpenssl(importKeychain, cspHand, flags, keyParams, 
-                               outArray);
-                       break;
-               case kSecFormatWrappedSSH:
-                       ortn =  impExpWrappedOpenSSHImport(mExternal, importKeychain, cspHand, 
-                               flags, keyParams, mPrintName, outArray);
-                       break;
-               case kSecFormatWrappedLSH:
-               default:
-                       return errSecUnknownFormat;
-       }
-       if((ortn == errSecSuccess) && (keyImportState == PIS_AllowOne)) {
-               /* reached our limit */
-               keyImportState = PIS_NoMore;
-       }
-       return ortn;
-}
-