Esempio n. 1
0
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));
}
Esempio n. 2
0
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));
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}