X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_keychain/lib/SecImport.cpp?ds=inline diff --git a/Security/libsecurity_keychain/lib/SecImport.cpp b/Security/libsecurity_keychain/lib/SecImport.cpp deleted file mode 100644 index 3a135656..00000000 --- a/Security/libsecurity_keychain/lib/SecImport.cpp +++ /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 -#include -#include - -#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 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; dexflags & kSecKeyImportOnlyOne)) { - keyImportState = PIS_AllowOne; - } - - /* Everything looks good: Go */ - for(CFIndex dex=0; deximportRep(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