#include "DH_utils.h"
#include "DH_keys.h"
#include <opensslUtils/openRsaSnacc.h>
#include <Security/logging.h>
#include <Security/debugging.h>
#include <open_ssl/opensslUtils/opensslUtils.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#define dhMiscDebug(args...) debug("dhMisc", ## args)
DH *contextToDhKey(
const Context &context,
AppleCSPSession &session,
CSSM_KEYUSE usage, bool &mallocdKey) {
CssmKey &cssmKey =
context.get<CssmKey>(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY);
const CSSM_KEYHEADER &hdr = cssmKey.KeyHeader;
if(hdr.AlgorithmId != CSSM_ALGID_DH) {
CssmError::throwMe(CSSMERR_CSP_ALGID_MISMATCH);
}
if(hdr.KeyClass != CSSM_KEYCLASS_PRIVATE_KEY) {
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
}
cspValidateIntendedKeyUsage(&hdr, usage);
return cssmKeyToDh(cssmKey, session, mallocdKey);
}
DH *cssmKeyToDh(
const CssmKey &cssmKey,
AppleCSPSession &session,
bool &allocdKey) {
DH *dhKey = NULL;
allocdKey = false;
const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
if(hdr->AlgorithmId != CSSM_ALGID_DH) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
}
assert(hdr->KeyClass == CSSM_KEYCLASS_PRIVATE_KEY);
switch(hdr->BlobType) {
case CSSM_KEYBLOB_RAW:
dhKey = rawCssmKeyToDh(cssmKey);
allocdKey = true;
break;
case CSSM_KEYBLOB_REFERENCE:
{
BinaryKey &binKey = session.lookupRefKey(cssmKey);
DHBinaryKey *dhBinKey = dynamic_cast<DHBinaryKey *>(&binKey);
if(dhBinKey == NULL) {
dhMiscDebug("cssmKeyToDh: wrong BinaryKey subclass\n");
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
}
assert(dhBinKey->mDhKey != NULL);
dhKey = dhBinKey->mDhKey;
break;
}
default:
CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
}
return dhKey;
}
DH *rawCssmKeyToDh(
const CssmKey &cssmKey)
{
const CSSM_KEYHEADER *hdr = &cssmKey.KeyHeader;
if(hdr->AlgorithmId != CSSM_ALGID_DH) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
}
assert(hdr->BlobType == CSSM_KEYBLOB_RAW);
assert(hdr->KeyClass == CSSM_KEYCLASS_PRIVATE_KEY);
if(hdr->Format != DH_PRIV_KEY_FORMAT) {
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT);
}
DH *dhKey = DH_new();
if(dhKey == NULL) {
CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
}
CSSM_RETURN crtn;
crtn = DHPrivateKeyDecode(dhKey,
cssmKey.KeyData.Data,
cssmKey.KeyData.Length);
if(crtn) {
CssmError::throwMe(crtn);
}
return dhKey;
}