#include "AppleX509CLSession.h"
#include "DecodedCert.h"
#include "SnaccUtils.h"
#include "cldebugging.h"
#include "CSPAttacher.h"
#include "CertBuilder.h"
#include <Security/oidscert.h>
#include <Security/cssmapple.h>
#include <Security/cssmerrno.h>
#include <Security/cdsaUtils.h>
#include <Security/pkcs10.h>
void AppleX509CLSession::generateCsr(
CSSM_CC_HANDLE CCHandle,
const CSSM_APPLE_CL_CSR_REQUEST *csrReq,
CSSM_DATA_PTR &csrPtr)
{
CertificationRequest certReq;
CertificationRequestInfo *reqInfo = new CertificationRequestInfo;
certReq.certificationRequestInfo = reqInfo;
reqInfo->version.Set(0);
NameBuilder *subject = new NameBuilder;
reqInfo->subject = subject;
subject->addX509Name(csrReq->subjectNameX509);
SubjectPublicKeyInfo *snaccKeyInfo = new SubjectPublicKeyInfo;
reqInfo->subjectPublicKeyInfo = snaccKeyInfo;
AlgorithmIdentifier *snaccAlgId = new AlgorithmIdentifier;
snaccKeyInfo->algorithm = snaccAlgId;
CL_cssmAlgToSnaccOid(csrReq->subjectPublicKey->KeyHeader.AlgorithmId,
snaccAlgId->algorithm);
CL_nullAlgParams(*snaccAlgId);
snaccKeyInfo->subjectPublicKey.Set(reinterpret_cast<char *>
(csrReq->subjectPublicKey->KeyData.Data),
csrReq->subjectPublicKey->KeyData.Length * 8);
if(csrReq->challengeString) {
Attribute *attr = reqInfo->attributes.Append();
attr->type.Set(challengePassword_arc);
PrintableString snaccStr(csrReq->challengeString);
CssmAutoData encChallenge(*this);
SC_encodeAsnObj(snaccStr, encChallenge,
strlen(csrReq->challengeString) + 32);
AttributeValue *av = attr->values.Append();
CSM_Buffer *cbuf = new CSM_Buffer((char *)encChallenge.data(),
encChallenge.length());
av->value = cbuf;
}
CssmAutoData encReqInfo(*this);
SC_encodeAsnObj(*reqInfo, encReqInfo, 8 * 1024);
CssmAutoData sig(*this);
signData(CCHandle, encReqInfo, sig);
certReq.signatureAlgorithm = new SignatureAlgorithmIdentifier;
certReq.signatureAlgorithm->algorithm.Set(reinterpret_cast<char *>(
csrReq->signatureOid.Data), csrReq->signatureOid.Length);
CL_nullAlgParams(*certReq.signatureAlgorithm);
certReq.signature.Set((char *)sig.data(), sig.length() * 8);
CssmAutoData encCsr(*this);
SC_encodeAsnObj(certReq, encCsr,
encReqInfo.length() + sig.length() + 100);
csrPtr = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
csrPtr->Data = (uint8 *)malloc(encCsr.length());
csrPtr->Length = encCsr.length();
memmove(csrPtr->Data, encCsr.data(), encCsr.length());
}
void AppleX509CLSession::verifyCsr(
const CSSM_DATA *csrPtr)
{
CertificationRequest certReq;
const CssmData &csrEnc = CssmData::overlay(*csrPtr);
SC_decodeAsnObj(csrEnc, certReq);
CertificationRequestInfo *certReqInfo = certReq.certificationRequestInfo;
if(certReqInfo == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_DATA);
}
CSSM_KEY_PTR cssmKey = CL_extractCSSMKey(*certReqInfo->subjectPublicKeyInfo,
*this, NULL);
SignatureAlgorithmIdentifier *snaccAlgId = certReq.signatureAlgorithm;
if(snaccAlgId == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_DATA);
}
CSSM_ALGORITHMS vfyAlg = CL_snaccOidToCssmAlg(snaccAlgId->algorithm);
CertificationRequestSigned certReqSigned;
SC_decodeAsnObj(csrEnc, certReqSigned);
CSM_Buffer *cbuf = certReqSigned.certificationRequestInfo.value;
char *cbufData = const_cast<char *>(cbuf->Access());
CssmData toVerify(cbufData, cbuf->Length());
AsnBits sigBits = certReqSigned.signature;
size_t sigBytes = (sigBits.BitLen() + 7) / 8;
CssmData sig(const_cast<char *>(sigBits.BitOcts()), sigBytes);
CSSM_CSP_HANDLE cspHand = getGlobalCspHand(true);
CSSM_RETURN crtn;
CSSM_CC_HANDLE ccHand;
crtn = CSSM_CSP_CreateSignatureContext(cspHand,
vfyAlg,
NULL, cssmKey,
&ccHand);
if(crtn) {
CssmError::throwMe(crtn);
}
verifyData(ccHand, toVerify, sig);
CL_freeCSSMKey(cssmKey, *this);
}