void UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec, CssmKey &unwrappedKey, CssmData *descriptiveData) { check(CSSM_UnwrapKey(handle(), NULL, &keyToBeUnwrapped, spec.usage, spec.attributes, spec.label, &compositeRcc(), &unwrappedKey, descriptiveData)); }
void UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec, CssmKey &unwrappedKey) { CssmData data(reinterpret_cast<uint8 *>(1), 0); check(CSSM_UnwrapKey(handle(), NULL, &keyToBeUnwrapped, spec.usage, spec.attributes, spec.label, &compositeRcc(), &unwrappedKey, &data)); }
Key UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec) { CssmData data(reinterpret_cast<uint8 *>(1), 0); Key unwrappedKey; check(CSSM_UnwrapKey(handle(), NULL, &keyToBeUnwrapped, spec.usage, spec.attributes, spec.label, &compositeRcc(), unwrappedKey.makeNewKey(attachment()), &data)); unwrappedKey->activate(); return unwrappedKey; }
Key UnwrapKey::operator () (const CssmKey &keyToBeUnwrapped, const KeySpec &spec, CssmData *descriptiveData) { Key unwrappedKey; check(CSSM_UnwrapKey(handle(), NULL, &keyToBeUnwrapped, spec.usage, spec.attributes, spec.label, &compositeRcc(), unwrappedKey.makeNewKey(attachment()), descriptiveData)); unwrappedKey->activate(); return unwrappedKey; }
/* * Unwrap a shrouded key. */ CSSM_RETURN p12UnwrapKey( CSSM_CSP_HANDLE cspHand, CSSM_DL_DB_HANDLE_PTR dlDbHand, // optional int keyIsPermanent, // nonzero - store in DB const CSSM_DATA &shroudedKeyBits, CSSM_ALGORITHMS keyAlg, // of the unwrapping key CSSM_ALGORITHMS encrAlg, CSSM_ALGORITHMS pbeHashAlg, // SHA1, MD5 only uint32 keySizeInBits, uint32 blockSizeInBytes, // for IV CSSM_PADDING padding, // CSSM_PADDING_PKCS7, etc. CSSM_ENCRYPT_MODE mode, // CSSM_ALGMODE_CBCPadIV8, etc. uint32 iterCount, const CSSM_DATA &salt, const CSSM_DATA *pwd, // unicode external representation const CSSM_KEY *passKey, SecNssCoder &coder, // for mallocing privKey const CSSM_DATA &labelData, SecAccessRef access, // optional bool noAcl, CSSM_KEYUSE keyUsage, CSSM_KEYATTR_FLAGS keyAttrs, /* * Result: a private key, reference format, optionaly stored * in dlDbHand */ CSSM_KEY_PTR &privKey) { CSSM_RETURN crtn; CSSM_KEY ckey; CSSM_CC_HANDLE ccHand = 0; CSSM_KEY wrappedKey; CSSM_KEY unwrappedKey; CSSM_KEYHEADER &hdr = wrappedKey.KeyHeader; CSSM_DATA descrData = {0, NULL}; // not used for PKCS8 wrap CSSM_KEYATTR_FLAGS reqAttr = keyAttrs; ResourceControlContext rcc; ResourceControlContext *rccPtr = NULL; Security::KeychainCore::Access::Maker maker; /* P12 style IV derivation, optional */ CSSM_DATA iv = {0, NULL}; CSSM_DATA_PTR ivPtr = NULL; if(blockSizeInBytes) { coder.allocItem(iv, blockSizeInBytes); ivPtr = &iv; } /* P12 style key derivation */ crtn = p12KeyGen(cspHand, ckey, true, keyAlg, pbeHashAlg, keySizeInBits, iterCount, salt, pwd, passKey, iv); if(crtn) { return crtn; } /* subsequent errors to errOut: */ /* CSSM context */ crtn = CSSM_CSP_CreateSymmetricContext(cspHand, encrAlg, mode, NULL, // access cred &ckey, ivPtr, // InitVector, optional padding, NULL, // Params &ccHand); if(crtn) { p12LogCssmError("CSSM_CSP_CreateSymmetricContext", crtn); goto errOut; } if(dlDbHand) { crtn = p12AddContextAttribute(ccHand, CSSM_ATTRIBUTE_DL_DB_HANDLE, sizeof(CSSM_ATTRIBUTE_DL_DB_HANDLE), dlDbHand); if(crtn) { p12LogCssmError("AddContextAttribute", crtn); goto errOut; } } /* * Cook up minimal WrappedKey header fields */ memset(&wrappedKey, 0, sizeof(CSSM_KEY)); memset(&unwrappedKey, 0, sizeof(CSSM_KEY)); hdr.HeaderVersion = CSSM_KEYHEADER_VERSION; hdr.BlobType = CSSM_KEYBLOB_WRAPPED; hdr.Format = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8; /* * This one we do not know. The CSP will figure out the format * of the unwrapped key after it decrypts the raw key material. */ hdr.AlgorithmId = CSSM_ALGID_NONE; hdr.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; /* also inferred by CSP */ hdr.LogicalKeySizeInBits = 0; hdr.KeyAttr = CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_EXTRACTABLE; hdr.KeyUsage = CSSM_KEYUSE_ANY; hdr.WrapAlgorithmId = encrAlg; hdr.WrapMode = mode; if(dlDbHand && keyIsPermanent) { reqAttr |= CSSM_KEYATTR_PERMANENT; } wrappedKey.KeyData = shroudedKeyBits; if(!noAcl) { // Create a Access::Maker for the initial owner of the private key. memset(&rcc, 0, sizeof(rcc)); maker.initialOwner(rcc); rccPtr = &rcc; } crtn = CSSM_UnwrapKey(ccHand, NULL, // PublicKey &wrappedKey, keyUsage, reqAttr, &labelData, rccPtr, // CredAndAclEntry privKey, &descrData); // required if(crtn) { p12LogCssmError("CSSM_UnwrapKey", crtn); if(crtn == CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA) { /* report in a keychain-friendly way */ crtn = errSecDuplicateItem; } } // Finally fix the acl and owner of the private key to the // specified access control settings. if((crtn == CSSM_OK) && !noAcl) { try { CssmClient::KeyAclBearer bearer( cspHand, *privKey, Allocator::standard()); SecPointer<KeychainCore::Access> initialAccess(access ? KeychainCore::Access::required(access) : /* caller-supplied */ new KeychainCore::Access("privateKey")); /* default */ initialAccess->setAccess(bearer, maker); } catch (const CssmError &e) { /* not implemented means we're talking to the CSP which does * not implement ACLs */ if(e.error != CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED) { crtn = e.error; } } catch(...) { p12ErrorLog("p12 exception on setAccess\n"); crtn = errSecAuthFailed; /* ??? */ } } errOut: if(ccHand) { CSSM_DeleteContext(ccHand); } CSSM_FreeKey(cspHand, NULL, &ckey, CSSM_FALSE); return crtn; }
/* unwrap key function. */ static CSSM_RETURN unwrapKey(CSSM_CSP_HANDLE cspHand, const CSSM_KEY_PTR wrappedKey, const CSSM_KEY_PTR unwrappingKey, CSSM_ALGORITHMS unwrapAlg, CSSM_ENCRYPT_MODE unwrapMode, CSSM_PADDING unwrapPad, CSSM_KEY_PTR unwrappedKey, // RETURNED const unsigned char *keyLabel, unsigned keyLabelLen) { CSSM_CC_HANDLE ccHand; CSSM_RETURN crtn; CSSM_RETURN crtn2; CSSM_DATA labelData; uint32 keyAttr; CSSM_DATA descData = { 0, NULL }; CSSM_ACCESS_CREDENTIALS creds; memset(unwrappedKey, 0, sizeof(CSSM_KEY)); memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); if((unwrappingKey == NULL) || (unwrappingKey->KeyHeader.KeyClass == CSSM_KEYCLASS_SESSION_KEY)) { crtn = CSSM_CSP_CreateSymmetricContext(cspHand, unwrapAlg, unwrapMode, &creds, // accessCreds unwrappingKey, &initVector, unwrapPad, // Padding 0, // Reserved &ccHand); if(crtn) { printError("cspUnwrapKey/CreateContext", crtn); return CSSM_ERRCODE_INTERNAL_ERROR; } } else { crtn = CSSM_CSP_CreateAsymmetricContext(cspHand, unwrapAlg, &creds, // passPhrase, unwrappingKey, unwrapPad, // Padding &ccHand); if(crtn) { printError("cspUnwrapKey/CreateContext", crtn); return CSSM_ERRCODE_INTERNAL_ERROR; } /* CMS requires 8-byte IV */ crtn = AddContextAttribute(ccHand, CSSM_ATTRIBUTE_INIT_VECTOR, sizeof(CSSM_DATA), CAT_Ptr, &initVector, 0); if(crtn) { printError("CSSM_UpdateContextAttributes", crtn); return crtn; } } labelData.Data = (uint8 *)keyLabel; labelData.Length = keyLabelLen; /* * New keyAttr - clear some old bits, make sure we ask for ref key */ keyAttr = wrappedKey->KeyHeader.KeyAttr; keyAttr &= ~(CSSM_KEYATTR_ALWAYS_SENSITIVE | CSSM_KEYATTR_NEVER_EXTRACTABLE); keyAttr |= CSSM_KEYATTR_RETURN_REF; crtn = CSSM_UnwrapKey(ccHand, NULL, // PublicKey wrappedKey, CSSM_KEYUSE_ANY, // FIXME keyAttr, &labelData, NULL, // CredAndAclEntry unwrappedKey, &descData); // required if(crtn != CSSM_OK) { printError("CSSM_UnwrapKey", crtn); } if((crtn2 = CSSM_DeleteContext(ccHand))) { printError("CSSM_DeleteContext", crtn2); } return crtn; }