void RSABinaryKey::generateKeyBlob(
	Allocator			&allocator,
	CssmData			&blob,
	CSSM_KEYBLOB_FORMAT	&format,	/* IN/OUT */
	AppleCSPSession		&session,
	const CssmKey		*paramKey,	/* optional, unused here */
	CSSM_KEYATTR_FLAGS	&attrFlags)	/* IN/OUT */
{
	bool			isPub;
	CSSM_RETURN		crtn;
	
	/* FIXME get label from context here for OAEP */
	
	/* 
	 * Here, the incoming default of CSSM_KEYBLOB_RAW_FORMAT_NONE
	 * is translated to our AppleCSP-custom defaults. App can override.
	 */
	switch(mKeyHeader.KeyClass) {
		case CSSM_KEYCLASS_PUBLIC_KEY:
			isPub = true;
			switch(format) {
				case CSSM_KEYBLOB_RAW_FORMAT_NONE:
					format = RSA_PUB_KEY_FORMAT;	// default
					break;
				case CSSM_KEYBLOB_RAW_FORMAT_DIGEST:
					if(mOaep) {
						/* have to take digest of the whole thing including label */
						format = CSSM_KEYBLOB_RAW_FORMAT_X509;
					}
					else {
						/* calculate digest on PKCS1 blob */
						format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;	
					}
					break;
				case CSSM_KEYBLOB_RAW_FORMAT_PKCS1:
				case CSSM_KEYBLOB_RAW_FORMAT_X509:
				case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH:
				case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2:
					break;
				default:
					CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT);
			}
			break;
		case CSSM_KEYCLASS_PRIVATE_KEY:
			isPub = false;
			switch(format) {
				case CSSM_KEYBLOB_RAW_FORMAT_NONE:	// default
					format = RSA_PRIV_KEY_FORMAT;	
					break;
				case CSSM_KEYBLOB_RAW_FORMAT_DIGEST:
					if(mOaep) {
						/* have to take digest of the whole thing including label */
						format = CSSM_KEYBLOB_RAW_FORMAT_X509;
					}
					else {
						/* calculate digest on PKCS1 blob */
						format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;	
					}
					isPub = true;
					break;
				case CSSM_KEYBLOB_RAW_FORMAT_PKCS1:
				case CSSM_KEYBLOB_RAW_FORMAT_PKCS8:
				case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH:
					break;
				default:
					CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT);
			}
			break;
		default:
			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
	}

	CssmAutoData encodedKey(allocator);
	if(mOaep) {
		CSSM_DATA label = mLabel;
		if(isPub) {
			crtn = RSAOAEPPublicKeyEncode(mRsaKey, &label, encodedKey);
		}
		else {
			crtn = RSAOAEPPrivateKeyEncode(mRsaKey, &label, encodedKey);
		}
	}
	else {
		if(isPub) {
			crtn = RSAPublicKeyEncode(mRsaKey, format, descData(), encodedKey);
		}
		else {
			crtn = RSAPrivateKeyEncode(mRsaKey, format, descData(), encodedKey);
		}
	}
	if(crtn) {
		CssmError::throwMe(crtn);
	}
	blob = encodedKey.release();
}
Esempio n. 2
0
 std::string DictImpl::descData( void const *data ) const
 {
   return descData( data, 16 );
 }
void DSABinaryKey::generateKeyBlob(
	Allocator 		&allocator,
	CssmData			&blob,
	CSSM_KEYBLOB_FORMAT	&format,
	AppleCSPSession		&session,
	const CssmKey		*paramKey,	/* optional */
	CSSM_KEYATTR_FLAGS	&attrFlags)	/* IN/OUT */
{
	bool			isPub;
	CSSM_RETURN		crtn;
	
	/* 
	 * Here, the incoming default of CSSM_KEYBLOB_RAW_FORMAT_NONE
	 * is translated to our AppleCSP-custom defaults. App can override.
	 */
	switch(mKeyHeader.KeyClass) {
		case CSSM_KEYCLASS_PUBLIC_KEY:
			isPub = true;
			switch(format) {
				case CSSM_KEYBLOB_RAW_FORMAT_NONE:
					format = DSA_PUB_KEY_FORMAT;	// default
					break;
				case CSSM_KEYBLOB_RAW_FORMAT_FIPS186:
				case CSSM_KEYBLOB_RAW_FORMAT_X509:
				case CSSM_KEYBLOB_RAW_FORMAT_DIGEST:
				case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2:
					break;
				default:
					CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT);
			}
			break;
		case CSSM_KEYCLASS_PRIVATE_KEY:
			isPub = false;
			switch(format) {
				case CSSM_KEYBLOB_RAW_FORMAT_NONE:
					format = DSA_PRIV_KEY_FORMAT;	// default
					break;
				case CSSM_KEYBLOB_RAW_FORMAT_DIGEST:
					/*
					 * This is calculated on the public key, which 
					 * is not always part of a DSA private key's encoding...
					 * so first calculate the public key. 
					 */
					dsaKeyPrivToPub(mDsaKey);
					isPub = true;
					break;
				case CSSM_KEYBLOB_RAW_FORMAT_FIPS186:
				case CSSM_KEYBLOB_RAW_FORMAT_PKCS8:
				case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL:
					break;
				default:
					CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT);
			}
			break;
		default:
			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
	}

	/* possible conversion from partial binary key to fully 
	 * formed blob */
	DSA *dsaToEncode = mDsaKey;
	DSA *dsaUpgrade = NULL;
	if(isPub &&
	   (mDsaKey->p == NULL) &&
	   (paramKey != NULL)) {
		/*
		 * Don't modify BinaryKey; make a copy.
		 */
		dsaUpgrade = DSA_new();
		if(dsaUpgrade == NULL) {
			CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);	
		}
		dsaUpgrade->pub_key = BN_dup(mDsaKey->pub_key);
		crtn = dsaGetParamsFromKey(dsaUpgrade, *paramKey, session);
		if(crtn) {
			DSA_free(dsaUpgrade);
			CssmError::throwMe(crtn);
		}
		
		/* success - switch keys and inform caller of attr change */
		dsaToEncode = dsaUpgrade;
		attrFlags &= ~CSSM_KEYATTR_PARTIAL;
	}

	/*
	 * DSA private keys originating from BSAFE form - e.g., DSA private
	 * keys wrapped in a keychain (which have format FIPS186 by default)
	 * have no public key component. Generate the public key if we don't 
	 * have one.
	 */
	if(!isPub && (dsaToEncode->pub_key == NULL)) {
		dsaKeyPrivToPub(dsaToEncode);
	}
	
	CssmAutoData 	encodedKey(allocator);
	if(isPub) {
		crtn = DSAPublicKeyEncode(dsaToEncode, format, descData(), encodedKey);
	}
	else {
		crtn = DSAPrivateKeyEncode(dsaToEncode, format, descData(), encodedKey);
	}
	if(dsaUpgrade != NULL) {
		/* temp key, get rid of it */
		DSA_free(dsaUpgrade);
	}
	if(crtn) {
		CssmError::throwMe(crtn);
	}
	blob = encodedKey.release();
}