]> git.saurik.com Git - apple/security.git/blobdiff - OSX/include/security_pkcs12/pkcs12Decode.cpp
Security-57336.10.29.tar.gz
[apple/security.git] / OSX / include / security_pkcs12 / pkcs12Decode.cpp
diff --git a/OSX/include/security_pkcs12/pkcs12Decode.cpp b/OSX/include/security_pkcs12/pkcs12Decode.cpp
deleted file mode 100644 (file)
index 9e426c1..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (c) 2003-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@
- */
-/*
- * pkcs12Decode.h - P12Coder decoding engine.
- */
-#include "pkcs12Coder.h"
-#include "pkcs12Templates.h"
-#include "pkcs12Utils.h"
-#include "pkcs12Debug.h"
-#include "pkcs12Crypto.h"
-#include <security_cdsa_utilities/cssmerrors.h>
-#include <security_asn1/nssUtils.h>
-
-/* top-level PKCS12 PFX decoder */
-void P12Coder::decode(
-       CFDataRef                               cdpfx)
-{
-       SecNssCoder localCdr;
-       NSS_P12_DecodedPFX pfx;
-
-       p12DecodeLog("decode");
-       memset(&pfx, 0, sizeof(pfx));
-       const CSSM_DATA rawBlob = {CFDataGetLength(cdpfx),
-               (uint8 *)CFDataGetBytePtr(cdpfx)};
-               
-       if(localCdr.decodeItem(rawBlob, NSS_P12_DecodedPFXTemplate, &pfx)) {
-               p12ErrorLog("Error on top-level decode of NSS_P12_DecodedPFX\n");
-               P12_THROW_DECODE;
-       }
-       NSS_P7_DecodedContentInfo &dci = pfx.authSafe;
-       if(dci.type != CT_Data) {
-               /* no other types supported yet */
-               p12ErrorLog("bad top-level contentType\n");
-               P12_THROW_DECODE;
-       }
-       mIntegrityMode = kSecPkcs12ModePassword;
-
-       if(pfx.macData == NULL) {
-               /* not present is an error in kSecPkcs12ModePassword */
-               p12ErrorLog("no MAC in PFX\n");
-               P12_THROW_DECODE;
-       }
-       macParse(*pfx.macData, localCdr);
-
-       const CSSM_DATA *macPhrase = getMacPassPhrase();
-       const CSSM_KEY *macPassKey = getMacPassKey();
-       if((macPhrase == NULL) && (macPassKey == NULL)) {
-               p12ErrorLog("no passphrase set\n");
-               CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_PASSPHRASE);
-       }
-       CSSM_RETURN crtn = p12VerifyMac(pfx, mCspHand, macPhrase, 
-               macPassKey, localCdr);
-       if(crtn) {
-               p12LogCssmError("p12VerifyMac", crtn);
-               CssmError::throwMe(errSecPkcs12VerifyFailure);
-       }
-       
-       authSafeParse(*dci.content.data, localCdr);
-
-       /*
-        * On success, if we have a keychain, store certs and CRLs there
-        */
-       if(mKeychain != NULL) {
-               storeDecodeResults();
-       }
-}
-
-/*
- * Decrypt the contents of a NSS_P7_EncryptedData
- */
-void P12Coder::encryptedDataDecrypt(
-       const NSS_P7_EncryptedData &edata,
-       SecNssCoder &localCdr,
-       NSS_P12_PBE_Params *pbep,       // preparsed
-       CSSM_DATA &ptext)                       // result goes here in localCdr space
-{
-       p12DecodeLog("encryptedDataDecrypt");
-
-       /* see if we can grok the encr alg */
-       CSSM_ALGORITHMS         keyAlg;                 // e.g., CSSM_ALGID_DES
-       CSSM_ALGORITHMS         encrAlg;                // e.g., CSSM_ALGID_3DES_3KEY_EDE
-       CSSM_ALGORITHMS         pbeHashAlg;             // SHA1 or MD5
-       uint32                          keySizeInBits;
-       uint32                          blockSizeInBytes;       // for IV, optional
-       CSSM_PADDING            padding;                // CSSM_PADDING_PKCS7, etc.
-       CSSM_ENCRYPT_MODE       mode;                   // CSSM_ALGMODE_CBCPadIV8, etc.
-       PKCS_Which                      pkcs;
-       
-       bool found = pkcsOidToParams(&edata.contentInfo.encrAlg.algorithm,
-               keyAlg, encrAlg, pbeHashAlg, keySizeInBits, blockSizeInBytes,
-               padding, mode, pkcs);
-       if(!found || (pkcs != PW_PKCS12)) {
-               p12ErrorLog("EncryptedData encrAlg not understood\n");
-               CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
-       }
-               
-       uint32 iterCount;
-       if(!p12DataToInt(pbep->iterations, iterCount)) {
-               p12ErrorLog("encryptedDataDecrypt: badly formed iterCount\n");
-               P12_THROW_DECODE;
-       }
-       const CSSM_DATA *pwd = getEncrPassPhrase();
-       const CSSM_KEY *passKey = getEncrPassKey();
-       if((pwd == NULL) && (passKey == NULL)) {
-               p12ErrorLog("no passphrase set\n");
-               CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_PASSPHRASE);
-       }
-       
-       /* go */
-       CSSM_RETURN crtn = p12Decrypt(mCspHand,
-               edata.contentInfo.encrContent,
-               keyAlg, encrAlg, pbeHashAlg,
-               keySizeInBits, blockSizeInBytes,
-               padding, mode,
-               iterCount, pbep->salt,
-               pwd,
-               passKey, 
-               localCdr, 
-               ptext);
-       if(crtn) {
-               CssmError::throwMe(crtn);
-       }
-}
-
-
-/*
- * Parse an CSSM_X509_ALGORITHM_IDENTIFIER specific to P12.
- * Decode the alg params as a NSS_P12_PBE_Params and parse and 
- * return the result if the pbeParams is non-NULL.
- */
-void P12Coder::algIdParse(
-       const CSSM_X509_ALGORITHM_IDENTIFIER &algId,
-       NSS_P12_PBE_Params *pbeParams,          // optional
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("algIdParse");
-
-       const CSSM_DATA &param = algId.parameters;
-       if(pbeParams == NULL) {
-               /* alg params are uninterpreted */
-               return;
-       }
-       
-       if(param.Length == 0) {
-               p12ErrorLog("algIdParse: no alg parameters\n");
-               P12_THROW_DECODE;
-       }
-       
-       memset(pbeParams, 0, sizeof(*pbeParams));
-       if(localCdr.decodeItem(param, 
-                       NSS_P12_PBE_ParamsTemplate, pbeParams)) {
-               p12ErrorLog("Error decoding NSS_P12_PBE_Params\n");
-               P12_THROW_DECODE;
-       }
-}
-
-/*
- * Parse a NSS_P7_EncryptedData - specifically in the context
- * of a P12 in password privacy mode. (The latter assumption is
- * to enable us to infer CSSM_X509_ALGORITHM_IDENTIFIER.parameters
- * format). 
- */
-void P12Coder::encryptedDataParse(
-       const NSS_P7_EncryptedData &edata,
-       SecNssCoder &localCdr,
-       NSS_P12_PBE_Params *pbep)               // optional, RETURNED
-{
-       p12DecodeLog("encryptedDataParse");
-
-       /*
-        * Parse the alg ID, save PBE params for when we do the decrypt
-        * key unwrap
-        */
-       const NSS_P7_EncrContentInfo &ci = edata.contentInfo;
-       const CSSM_X509_ALGORITHM_IDENTIFIER &algId = ci.encrAlg;
-       algIdParse(algId, pbep, localCdr);
-}
-
-/*
- * ShroudedKeyBag parser w/decrypt
- */
-void P12Coder::shroudedKeyBagParse(
-       const NSS_P12_SafeBag &safeBag,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("Found shrouded key bag");
-       if(mPrivKeyImportState == PKIS_NoMore) {
-               CssmError::throwMe(errSecMultiplePrivKeys);     
-       }
-
-       const NSS_P12_ShroudedKeyBag *keyBag = safeBag.bagValue.shroudedKeyBag;
-       const CSSM_X509_ALGORITHM_IDENTIFIER &algId = keyBag->algorithm;
-       NSS_P12_PBE_Params pbep;
-       algIdParse(algId, &pbep, localCdr);
-
-       /*
-        * Prepare for decryption
-        */
-       CSSM_ALGORITHMS         keyAlg;                 // e.g., CSSM_ALGID_DES
-       CSSM_ALGORITHMS         encrAlg;                // e.g., CSSM_ALGID_3DES_3KEY_EDE
-       CSSM_ALGORITHMS         pbeHashAlg;             // SHA1 or MD5
-       uint32                          keySizeInBits;
-       uint32                          blockSizeInBytes;       // for IV, optional
-       CSSM_PADDING            padding;                // CSSM_PADDING_PKCS7, etc.
-       CSSM_ENCRYPT_MODE       mode;                   // CSSM_ALGMODE_CBCPadIV8, etc.
-       PKCS_Which                      pkcs;
-       
-       bool found = pkcsOidToParams(&algId.algorithm,
-               keyAlg, encrAlg, pbeHashAlg, keySizeInBits, blockSizeInBytes,
-               padding, mode, pkcs);
-       if(!found || (pkcs != PW_PKCS12)) {
-               p12ErrorLog("ShroudedKeyBag encrAlg not understood\n");
-               CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
-       }
-
-       uint32 iterCount;
-       if(!p12DataToInt(pbep.iterations, iterCount)) {
-               p12ErrorLog("ShroudedKeyBag: badly formed iterCount\n");
-               P12_THROW_DECODE;
-       }
-       const CSSM_DATA *encrPhrase = getEncrPassPhrase();
-       const CSSM_KEY *passKey = getEncrPassKey();
-       if((encrPhrase == NULL) && (passKey == NULL)) {
-               p12ErrorLog("no passphrase set\n");
-               CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_PASSPHRASE);
-       }
-       
-       /* We'll own the actual CSSM_KEY memory */
-       CSSM_KEY_PTR privKey = (CSSM_KEY_PTR)mCoder.malloc(sizeof(CSSM_KEY));
-       memset(privKey, 0, sizeof(CSSM_KEY));
-       
-       CSSM_DATA labelData;
-       p12GenLabel(labelData, localCdr);       
-       
-       CSSM_RETURN crtn = p12UnwrapKey(mCspHand,
-               mDlDbHand.DLHandle ? &mDlDbHand : NULL,
-               mImportFlags & kSecImportKeys,
-               keyBag->encryptedData,
-               keyAlg, encrAlg, pbeHashAlg,
-               keySizeInBits, blockSizeInBytes,
-               padding, mode,
-               iterCount, pbep.salt,
-               encrPhrase,
-               passKey,
-               localCdr, 
-               labelData,
-               mAccess,
-               mNoAcl,
-               mKeyUsage,
-               mKeyAttrs,
-               privKey);
-       if(crtn) {
-               p12ErrorLog("Error unwrapping private key\n");
-               CssmError::throwMe(crtn);
-       }
-       p12DecodeLog("unwrapped shrouded key bag");
-
-       P12KeyBag *p12bag = new P12KeyBag(privKey, mCspHand,
-               safeBag.bagAttrs, labelData, mCoder);
-       addKey(p12bag);
-       
-       if(mPrivKeyImportState == PKIS_AllowOne) {
-               mPrivKeyImportState = PKIS_NoMore;      
-       }
-}
-
-/*
- * (unshrouded) KeyBag parser
- */
-void P12Coder::keyBagParse(
-       const NSS_P12_SafeBag &safeBag,
-       SecNssCoder &localCdr)
-{
-       if(mPrivKeyImportState == PKIS_NoMore) {
-               CssmError::throwMe(errSecMultiplePrivKeys);     
-       }
-       
-       /* FIXME - should be able to parse and handle this.... */
-       p12DecodeLog("found keyBag");
-       NSS_P12_KeyBag *keyBag = safeBag.bagValue.keyBag;
-       P12OpaqueBag *p12Bag = new P12OpaqueBag(safeBag.bagId, 
-               /* this breaks when NSS_P12_KeyBag is not a CSSM_DATA */
-               *keyBag,                        
-               safeBag.bagAttrs,
-               mCoder);
-       addOpaque(p12Bag);
-}
-
-/*
- * CertBag parser
- */
-void P12Coder::certBagParse(
-       const NSS_P12_SafeBag &safeBag,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("found certBag");
-       NSS_P12_CertBag *certBag = safeBag.bagValue.certBag;
-       switch(certBag->type) {
-               case CT_X509:
-               case CT_SDSI:
-                       break;
-               default:
-                       p12ErrorLog("certBagParse: unknown cert type\n");
-                       P12_THROW_DECODE;
-       }
-       P12CertBag *p12Bag = new P12CertBag(certBag->type, 
-               certBag->certValue,
-               safeBag.bagAttrs,
-               mCoder);
-       addCert(p12Bag);
-}
-
-/*
- * CrlBag parser
- */
-void P12Coder::crlBagParse(
-       const NSS_P12_SafeBag &safeBag,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("found crlBag");
-       NSS_P12_CrlBag *crlBag = safeBag.bagValue.crlBag;
-       switch(crlBag->type) {
-               case CRT_X509:
-                       break;
-               default:
-                       p12ErrorLog("crlBagParse: unknown CRL type\n");
-                       P12_THROW_DECODE;
-       }
-       P12CrlBag *p12Bag = new P12CrlBag(crlBag->type, 
-               crlBag->crlValue,
-               safeBag.bagAttrs,
-               mCoder);
-       addCrl(p12Bag);
-}
-
-/*
- * SecretBag parser
- */
-void P12Coder::secretBagParse(
-       const NSS_P12_SafeBag &safeBag,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("found secretBag");
-       NSS_P12_SecretBag *secretBag = safeBag.bagValue.secretBag;
-       P12OpaqueBag *p12Bag = new P12OpaqueBag(safeBag.bagId, 
-               /* this breaks when NSS_P12_SecretBag is not a CSSM_DATA */
-               *secretBag,                     
-               safeBag.bagAttrs,
-               mCoder);
-       addOpaque(p12Bag);
-}
-
-/*
- * SafeContentsBag parser
- */
-void P12Coder::safeContentsBagParse(
-       const NSS_P12_SafeBag &safeBag,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("found SafeContents safe bag");
-       NSS_P12_SafeContentsBag *scBag = safeBag.bagValue.safeContentsBag;
-       P12OpaqueBag *p12Bag = new P12OpaqueBag(safeBag.bagId, 
-               /* this breaks when NSS_P12_SafeContentsBag is not a CSSM_DATA */
-               *scBag,                 
-               safeBag.bagAttrs,
-               mCoder);
-       addOpaque(p12Bag);
-}
-
-/*
- * Parse an encoded NSS_P12_SafeContents. This could be either 
- * present as plaintext in an AuthSafe or decrypted. 
- */
-void P12Coder::safeContentsParse(
-       const CSSM_DATA &contentsBlob,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("safeContentsParse");
-
-       NSS_P12_SafeContents sc;
-       memset(&sc, 0, sizeof(sc));
-       if(localCdr.decodeItem(contentsBlob, NSS_P12_SafeContentsTemplate,
-                       &sc)) {
-               p12ErrorLog("Error decoding SafeContents\n");
-               P12_THROW_DECODE;
-       }
-       unsigned numBags = nssArraySize((const void **)sc.bags);
-       for(unsigned dex=0; dex<numBags; dex++) {
-               NSS_P12_SafeBag *bag = sc.bags[dex];
-               assert(bag != NULL);
-               
-               /* ensure that *something* is there */
-               if(bag->bagValue.keyBag == NULL) {
-                       p12ErrorLog("safeContentsParse: Empty SafeBag\n");
-                       P12_THROW_DECODE;
-               }
-               
-               /*
-                * Break out to individual bag type
-                */
-               switch(bag->type) {
-                       case BT_KeyBag:
-                               keyBagParse(*bag, localCdr);
-                               break;
-                       case BT_ShroudedKeyBag:
-                               shroudedKeyBagParse(*bag, localCdr);
-                               break;
-                       case BT_CertBag:
-                               certBagParse(*bag, localCdr);
-                               break;
-                       case BT_CrlBag:
-                               crlBagParse(*bag, localCdr);
-                               break;
-                       case BT_SecretBag:
-                               secretBagParse(*bag ,localCdr);
-                               break;
-                       case BT_SafeContentsBag:
-                               safeContentsBagParse(*bag, localCdr);
-                               break;
-                       default:
-                               p12ErrorLog("unknown  p12 BagType (%u)\n",
-                                       (unsigned)bag->type);
-                               P12_THROW_DECODE;
-               }
-       }
-}
-
-/*
- * Parse a ContentInfo in the context of (i.e., as an element of)
- * an AuthenticatedSafe.
- */
-void P12Coder::authSafeElementParse(
-       const NSS_P7_DecodedContentInfo *info,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("authSafeElementParse");
-       switch(info->type) {
-               case CT_Data:
-                       /* unencrypted SafeContents */
-                       safeContentsParse(*info->content.data, localCdr);
-                       break;
-                       
-               case CT_EncryptedData:
-               {
-                       NSS_P12_PBE_Params pbep;
-                       encryptedDataParse(*info->content.encryptData, localCdr, &pbep);
-
-                       /* 
-                        * Decrypt contents to get a SafeContents and
-                        * then parse that.
-                        */
-                       CSSM_DATA ptext = {0, NULL};
-                       encryptedDataDecrypt(*info->content.encryptData,
-                               localCdr, &pbep, ptext);
-                       safeContentsParse(ptext, localCdr);
-                       break;
-               }       
-               default:
-                       p12ErrorLog("authSafeElementParse: unknown sage type (%u)\n",
-                               (unsigned)info->type);
-                               
-                       /* well, save it as an opaque bag for now */
-                       P12OpaqueBag *opaque = new P12OpaqueBag(
-                               info->contentType, *info->content.data,
-                               NULL,   // no attrs
-                               localCdr);
-                       addOpaque(opaque);
-                       break;
-       }
-}
-
-/*
- * Parse an encoded NSS_P12_AuthenticatedSafe
- */
-void P12Coder::authSafeParse(
-       const CSSM_DATA &authSafeBlob,
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("authSafeParse");
-
-       NSS_P12_AuthenticatedSafe authSafe;
-       
-       memset(&authSafe, 0, sizeof(authSafe));
-       if(localCdr.decodeItem(authSafeBlob,
-                       NSS_P12_AuthenticatedSafeTemplate,
-                       &authSafe)) {
-               p12ErrorLog("Error decoding authSafe\n");
-               P12_THROW_DECODE;
-       }
-       unsigned numInfos = nssArraySize((const void **)authSafe.info);
-       for(unsigned dex=0; dex<numInfos; dex++) {
-               NSS_P7_DecodedContentInfo *info = authSafe.info[dex];
-               authSafeElementParse(info, localCdr);
-       }
-}
-
-void P12Coder::macParse(
-       const NSS_P12_MacData &macData, 
-       SecNssCoder &localCdr)
-{
-       p12DecodeLog("macParse");
-       algIdParse(macData.mac.digestAlgorithm, NULL, localCdr);
-       const CSSM_DATA &iter = macData.iterations;
-       if(iter.Length > 4) {
-               p12ErrorLog("malformed iteration length (%u)\n",
-                               (unsigned)iter.Length);
-               P12_THROW_DECODE;
-       }
-}
-