]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_keychain/lib/SecImport.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / Security / libsecurity_keychain / lib / SecImport.cpp
diff --git a/Security/libsecurity_keychain/lib/SecImport.cpp b/Security/libsecurity_keychain/lib/SecImport.cpp
deleted file mode 100644 (file)
index 3a13565..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (c) 2004,2011-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@
- *
- * SecImport.cpp - high-level facility for importing Sec layer objects.
- */
-
-#include "SecImportExport.h"
-#include "SecExternalRep.h"
-#include "SecImportExportPem.h"
-#include "SecImportExportUtils.h"
-#include <security_cdsa_utils/cuCdsaUtils.h>
-#include <security_utilities/globalizer.h>
-#include <Security/SecBase.h>
-
-#define SecImpInferDbg(args...)        secdebug("SecImpInfer", ## args)
-
-using namespace Security;
-using namespace KeychainCore;
-
-/*
- * Do our best to ensure that a SecImportRep's type and format are known.
- * A return of true means that both format and type (and, if the item
- * is a raw public or private key, the algorithm) are known.
- */
-static bool impExpInferTypeAndFormat(
-       SecImportRep            *rep,
-       CFStringRef                     fileStr,
-       SecExternalFormat   inputFormat,
-       SecExternalItemType     itemType)
-{
-       /* fill in blanks if caller knows them */
-       if((rep->mExternType == kSecItemTypeUnknown) && (itemType != kSecItemTypeUnknown)) {
-               rep->mExternType = itemType;
-       }
-       if((rep->mExternFormat == kSecFormatUnknown) && (inputFormat != kSecFormatUnknown)) {
-               rep->mExternFormat = inputFormat;
-       }
-
-       /* some types can be inferred from format */
-       if(rep->mExternType == kSecItemTypeUnknown) {
-               SecExternalFormat format;
-               if(rep->mExternFormat == kSecFormatUnknown) {
-                       /* caller specified */
-                       format = inputFormat;
-               }
-               else {
-                       /* maybe this is already set */
-                       format = rep->mExternFormat;
-               }
-               switch(format) {
-                       case kSecFormatUnknown:
-                               break;
-                       case kSecFormatPKCS7:
-                       case kSecFormatPKCS12:
-                       case kSecFormatPEMSequence:
-                       case kSecFormatNetscapeCertSequence:
-                               rep->mExternType = kSecItemTypeAggregate;
-                               break;
-                       case kSecFormatRawKey:
-                               rep->mExternType = kSecItemTypeSessionKey;
-                               break;
-                       case kSecFormatX509Cert:
-                               rep->mExternType = kSecItemTypeCertificate;
-                               break;
-                       case kSecFormatWrappedPKCS8:
-                       case kSecFormatWrappedOpenSSL:
-                       case kSecFormatWrappedSSH:
-                               rep->mExternType = kSecItemTypePrivateKey;
-                               break;
-                       case kSecFormatSSHv2:
-                               rep->mExternType = kSecItemTypePublicKey;
-                               break;
-                       case kSecFormatOpenSSL:
-                       case kSecFormatBSAFE:
-                       case kSecFormatWrappedLSH:
-                       default:
-                               /* can be private or session (right? */
-                               break;
-               }
-       }
-
-       /* some formats can be inferred from type */
-       if(rep->mExternFormat == kSecFormatUnknown) {
-               SecExternalItemType thisType;
-               if(rep->mExternType == kSecItemTypeUnknown) {
-                       /* caller specified */
-                       thisType = itemType;
-               }
-               else {
-                       /* maybe this is already set */
-                       thisType = rep->mExternType;
-               }
-               switch(thisType) {
-                       case kSecItemTypeCertificate:
-                               rep->mExternFormat = kSecFormatX509Cert;
-                               break;
-                       /* any others? */
-                       default:
-                               break;
-               }
-       }
-
-       /*
-        * Wrapped private keys don't need algorithm
-        * Some formats implies algorithm
-        */
-       bool isWrapped = false;
-       switch(rep->mExternFormat) {
-               case kSecFormatWrappedPKCS8:
-               case kSecFormatWrappedOpenSSL:
-               case kSecFormatWrappedLSH:
-                       isWrapped = true;
-                       break;
-               case kSecFormatWrappedSSH:
-                       isWrapped = true;
-                       rep->mKeyAlg = CSSM_ALGID_RSA;
-                       break;
-               case kSecFormatSSH:
-                       rep->mKeyAlg = CSSM_ALGID_RSA;
-                       break;
-               default:
-                       break;
-       }
-
-       /* Are we there yet? */
-       bool done = true;
-       if((rep->mExternType   == kSecItemTypeUnknown) ||
-          (rep->mExternFormat == kSecFormatUnknown)) {
-               done = false;
-       }
-       if(done) {
-               switch(rep->mExternType) {
-                       case kSecItemTypePrivateKey:
-                       case kSecItemTypePublicKey:
-                               if(!isWrapped && (rep->mKeyAlg == CSSM_ALGID_NONE)) {
-                                       /* gotta know this too */
-                                       done = false;
-                               }
-                               break;
-                       default:
-                               break;
-               }
-       }
-       if(!done) {
-               /* infer from filename if possible */
-               done = impExpImportParseFileExten(fileStr, &rep->mExternFormat,
-                       &rep->mExternType);
-       }
-       if(done) {
-          return true;
-       }
-
-       /* invoke black magic: try decoding various forms */
-       return impExpImportGuessByExamination(rep->mExternal, &rep->mExternFormat,
-               &rep->mExternType, &rep->mKeyAlg);
-}
-
-class CSPDLMaker
-{
-protected:
-       CSSM_CSP_HANDLE mHandle;
-    RecursiveMutex mMutex;
-
-public:
-       CSPDLMaker() : mHandle(cuCspStartup(CSSM_FALSE)) {}
-       operator CSSM_CSP_HANDLE() {return mHandle;}
-};
-
-static ModuleNexus<CSPDLMaker> gCSPHandle;
-
-OSStatus SecKeychainItemImport(
-       CFDataRef                                                       importedData,
-       CFStringRef                                                     fileNameOrExtension,    // optional
-       SecExternalFormat                                       *inputFormat,                   // optional, IN/OUT
-       SecExternalItemType                                     *itemType,                              // optional, IN/OUT
-       SecItemImportExportFlags                        flags,
-       const SecKeyImportExportParameters  *keyParams,                         // optional
-       SecKeychainRef                                          importKeychain,                 // optional
-       CFArrayRef                                                      *outItems)                              /* optional */
-{
-       BEGIN_IMP_EXP_SECAPI
-
-       bool                            isPem;
-       OSStatus                        ortn = errSecSuccess;
-       OSStatus                        pem_ortn = errSecSuccess;
-       SecImportRep            *rep = NULL;
-       SecExternalFormat   callerInputFormat;
-       SecExternalItemType callerItemType;
-       CSSM_CSP_HANDLE         cspHand = 0;
-       CFIndex                         dex;
-       CFStringRef                     ourFileStr = NULL;
-
-       if((importedData == NULL) || (CFDataGetLength(importedData) == 0)) {
-               return errSecParam;
-       }
-       /* all other args are optional */
-
-       if(inputFormat) {
-               callerInputFormat = *inputFormat;
-       }
-       else {
-               callerInputFormat = kSecFormatUnknown;
-       }
-       if(itemType) {
-               callerItemType = *itemType;
-       }
-       else {
-               callerItemType = kSecItemTypeUnknown;
-       }
-
-       CFIndex numReps = 0;
-       SecExternalFormat tempFormat = callerInputFormat;
-       SecExternalItemType tempType = callerItemType;
-       ImpPrivKeyImportState keyImportState = PIS_NoLimit;
-
-       CFMutableArrayRef importReps = CFArrayCreateMutable(NULL, 0, NULL);
-       CFMutableArrayRef createdKcItems = CFArrayCreateMutable(NULL, 0,
-               &kCFTypeArrayCallBacks);
-       /* subsequent errors to errOut: */
-
-       /*
-        * importedData --> one or more SecImportReps.
-        * Note successful PEM decode can override caller's inputFormat and/or itemType.
-        */
-       pem_ortn = impExpParsePemToImportRefs(importedData, importReps, &isPem);
-       /* remember how PEM decode failed, but continue to examine other possibilities */
-       if(!isPem) {
-               /* incoming blob is one binary item, type possibly unknown */
-               rep = new SecImportRep(importedData, callerItemType, callerInputFormat,
-                       CSSM_ALGID_NONE);
-               CFArrayAppendValue(importReps, rep);
-               if(fileNameOrExtension) {
-                       ourFileStr = fileNameOrExtension;
-                       CFRetain(ourFileStr);
-               }
-       }
-       else {
-               /*
-                * Strip off possible .pem extension in case there's another one in
-                * front of it
-                */
-               assert(CFArrayGetCount(importReps) >= 1);
-               if(fileNameOrExtension) {
-                       if(CFStringHasSuffix(fileNameOrExtension, CFSTR(".pem"))) {
-                               ourFileStr = impExpImportDeleteExtension(fileNameOrExtension);
-                       }
-                       else {
-                               ourFileStr = fileNameOrExtension;
-                               CFRetain(ourFileStr);
-                       }
-               }
-       }
-
-       /*
-        * Ensure we know type and format (and, for raw keys, algorithm) of each item.
-        */
-       numReps = CFArrayGetCount(importReps);
-       if(numReps > 1) {
-               /*
-                * Incoming kSecFormatPEMSequence, caller specs are useless now.
-                * Hopefully the PEM parsing disclosed the info we'll need.
-                */
-               if(ourFileStr) {
-                       CFRelease(ourFileStr);
-                       ourFileStr = NULL;
-               }
-               tempFormat = kSecFormatUnknown;
-               tempType = kSecItemTypeUnknown;
-       }
-       for(dex=0; dex<numReps; dex++) {
-               rep = (SecImportRep *)CFArrayGetValueAtIndex(importReps, dex);
-               bool ok = impExpInferTypeAndFormat(rep, ourFileStr, tempFormat, tempType);
-               if(!ok) {
-                       ortn = errSecUnknownFormat;
-                       goto errOut;
-               }
-       }
-
-       /* Get a CSPDL handle, somehow, as convenience for lower level code */
-       if(importKeychain != NULL) {
-               ortn = SecKeychainGetCSPHandle(importKeychain, &cspHand);
-               if(ortn) {
-                       goto errOut;
-               }
-       }
-       else {
-               cspHand = gCSPHandle();
-       }
-
-       if(keyParams && (keyParams->flags & kSecKeyImportOnlyOne)) {
-               keyImportState = PIS_AllowOne;
-       }
-
-       /* Everything looks good: Go */
-       for(CFIndex dex=0; dex<numReps; dex++) {
-               rep = (SecImportRep *)CFArrayGetValueAtIndex(importReps, dex);
-               ortn = rep->importRep(importKeychain, cspHand, flags, keyParams,
-                       keyImportState, createdKcItems);
-               if(ortn) {
-                       goto errOut;
-               }
-       }
-
-       /* Give as much info to caller as we can even if we got an error on import */
-       if(inputFormat != NULL) {
-               if(numReps > 1) {
-                       assert(isPem);
-                       *inputFormat = kSecFormatPEMSequence;
-               }
-               else {
-                       /* format from sole item in importReps */
-                       assert(numReps != 0);
-                       rep = (SecImportRep *)CFArrayGetValueAtIndex(importReps, 0);
-                       *inputFormat = rep->mExternFormat;
-               }
-       }
-       if(itemType != NULL) {
-               if(numReps > 1) {
-                       assert(isPem);
-                       *itemType = kSecItemTypeAggregate;
-               }
-               else {
-                       /* itemType from sole item in importReps */
-                       assert(numReps != 0);
-                       rep = (SecImportRep *)CFArrayGetValueAtIndex(importReps, 0);
-                       *itemType = rep->mExternType;
-               }
-       }
-       if((ortn == errSecSuccess) && (outItems != NULL)) {
-               /* return the array */
-               *outItems = createdKcItems;
-               createdKcItems = NULL;
-       }
-       /* else caller doesn't want SecKeychainItemsRefs; we'll release below */
-
-errOut:
-       if(createdKcItems) {
-               CFRelease(createdKcItems);
-       }
-       if(importReps != NULL) {
-               /* CFArray of our own classes, no auto release */
-               CFIndex num = CFArrayGetCount(importReps);
-               for(dex=0; dex<num; dex++) {
-                       rep = (SecImportRep *)CFArrayGetValueAtIndex(importReps, dex);
-                       delete rep;
-               }
-               CFRelease(importReps);
-       }
-       if(ourFileStr) {
-               CFRelease(ourFileStr);
-       }
-       if(ortn) {
-               /* error occurred importing non-PEM representation */
-               return SecKeychainErrFromOSStatus(ortn);
-       }
-       if(pem_ortn == errSecUnsupportedFormat && numReps == 0) {
-               /* error occurred importing as PEM, and no other rep was imported */
-               return SecKeychainErrFromOSStatus(pem_ortn);
-       }
-       return errSecSuccess;
-
-       END_IMP_EXP_SECAPI
-}
-
-OSStatus SecItemImport(
-       CFDataRef                                                       importedData,
-       CFStringRef                                                     fileNameOrExtension,    /* optional */
-       SecExternalFormat                                       *inputFormat,                   /* optional, IN/OUT */
-       SecExternalItemType                                     *itemType,                              /* optional, IN/OUT */
-       SecItemImportExportFlags                        flags,
-       const SecItemImportExportKeyParameters  *keyParams,                             /* optional */
-       SecKeychainRef                                          importKeychain,                 /* optional */
-       CFArrayRef                                                      *outItems)
-{
-
-       SecKeyImportExportParameters* oldStructPtr = NULL;
-       SecKeyImportExportParameters oldStruct;
-       memset(&oldStruct, 0, sizeof(oldStruct));
-
-
-       if (NULL != keyParams)
-       {
-               if (ConvertSecKeyImportExportParametersToSecImportExportKeyParameters(NULL,
-                       keyParams, &oldStruct))
-               {
-                       oldStructPtr = &oldStruct;
-               }
-       }
-
-       return SecKeychainItemImport(importedData, fileNameOrExtension, inputFormat,
-               itemType, flags, oldStructPtr, importKeychain, outItems);
-}
-