#include "AppleTPSession.h"
#include "certGroupUtils.h"
#include "tpdebugging.h"
#include "tpTime.h"
#include <Security/oidsalg.h>
#include <Security/oidsattr.h>
#include <Security/oidscert.h>
#include <Security/cssmapple.h>
#include <security_utilities/debugging.h>
#include <Security/cssmapple.h>
#include <assert.h>
#define tpCredDebug(args...) secdebug("tpCred", ## args)
CSSM_X509_NAME * AppleTPSession::buildX509Name(
const CSSM_APPLE_TP_NAME_OID *nameArray,
unsigned numNames)
{
CSSM_X509_NAME *top = (CSSM_X509_NAME *)malloc(sizeof(CSSM_X509_NAME));
top->numberOfRDNs = numNames;
if(numNames == 0) {
top->RelativeDistinguishedName = NULL;
return top;
}
top->RelativeDistinguishedName =
(CSSM_X509_RDN_PTR)malloc(sizeof(CSSM_X509_RDN) * numNames);
CSSM_X509_RDN_PTR rdn;
const CSSM_APPLE_TP_NAME_OID *nameOid;
unsigned nameDex;
for(nameDex=0; nameDex<numNames; nameDex++) {
rdn = &top->RelativeDistinguishedName[nameDex];
nameOid = &nameArray[nameDex];
rdn->numberOfPairs = 1;
rdn->AttributeTypeAndValue = (CSSM_X509_TYPE_VALUE_PAIR_PTR)
malloc(sizeof(CSSM_X509_TYPE_VALUE_PAIR));
CSSM_X509_TYPE_VALUE_PAIR_PTR atvp = rdn->AttributeTypeAndValue;
tpCopyCssmData(*this, nameOid->oid, &atvp->type);
atvp->value.Length = strlen(nameOid->string);
if(tpCompareOids(&CSSMOID_CountryName, nameOid->oid)) {
if(atvp->value.Length > 2) {
CssmError::throwMe(CSSMERR_TP_INVALID_DATA);
}
for(unsigned dex=0; dex<atvp->value.Length; dex++) {
int c = nameOid->string[dex];
if(!isprint(c) || (c == EOF)) {
CssmError::throwMe(CSSMERR_TP_INVALID_DATA);
}
}
atvp->valueType = BER_TAG_PRINTABLE_STRING;
}
else if(tpCompareOids(&CSSMOID_DNQualifier, nameOid->oid)) {
atvp->valueType = BER_TAG_PRINTABLE_STRING;
}
else if(tpCompareOids(&CSSMOID_SerialNumber, nameOid->oid)) {
atvp->valueType = BER_TAG_PRINTABLE_STRING;
}
else if(tpCompareOids(&CSSMOID_EmailAddress, nameOid->oid)) {
atvp->valueType = BER_TAG_IA5_STRING;
}
else {
atvp->valueType = BER_TAG_PKIX_UTF8_STRING;
}
atvp->value.Data = (uint8 *)malloc(atvp->value.Length);
memmove(atvp->value.Data, nameOid->string, atvp->value.Length);
}
return top;
}
void AppleTPSession::freeX509Name(
CSSM_X509_NAME *top)
{
if(top == NULL) {
return;
}
unsigned nameDex;
CSSM_X509_RDN_PTR rdn;
for(nameDex=0; nameDex<top->numberOfRDNs; nameDex++) {
rdn = &top->RelativeDistinguishedName[nameDex];
if(rdn->AttributeTypeAndValue) {
for(unsigned aDex=0; aDex<rdn->numberOfPairs; aDex++) {
CSSM_X509_TYPE_VALUE_PAIR_PTR atvp =
&rdn->AttributeTypeAndValue[aDex];
free(atvp->type.Data);
free(atvp->value.Data);
}
free(rdn->AttributeTypeAndValue);
}
}
free(top->RelativeDistinguishedName);
free(top);
}
#define TP_FOUR_DIGIT_YEAR 0
#if TP_FOUR_DIGIT_YEAR
#define TP_TIME_FORMAT TIME_GEN
#define TP_TIME_TAG BER_TAG_GENERALIZED_TIME
#else
#define TP_TIME_FORMAT TIME_UTC
#define TP_TIME_TAG BER_TAG_UTC_TIME
#endif
CSSM_X509_TIME * AppleTPSession::buildX509Time(
unsigned secondsFromNow)
{
CSSM_X509_TIME *xtime = (CSSM_X509_TIME *)malloc(sizeof(CSSM_X509_TIME));
xtime->timeType = TP_TIME_TAG;
char *ts = (char *)malloc(GENERALIZED_TIME_STRLEN + 1);
{
StLock<Mutex> _(tpTimeLock());
timeAtNowPlus(secondsFromNow, TP_TIME_FORMAT, ts);
}
xtime->time.Data = (uint8 *)ts;
xtime->time.Length = strlen(ts);
return xtime;
}
void AppleTPSession::freeX509Time(
CSSM_X509_TIME *xtime)
{
if(xtime == NULL) {
return;
}
free((char *)xtime->time.Data);
free(xtime);
}
static void intToDER(
CSSM_INTPTR theInt,
CSSM_DATA &DER_Data,
Allocator &alloc)
{
DER_Data.Length = 1;
uintptr_t unsignedInt = (uintptr_t)theInt;
while(unsignedInt > 0xff) {
DER_Data.Length++;
unsignedInt >>= 8;
}
if(unsignedInt & 0x80) {
DER_Data.Length++;
}
DER_Data.Data = (uint8 *)alloc.malloc(DER_Data.Length);
uint8 *dst = DER_Data.Data + DER_Data.Length - 1;
unsignedInt = (uintptr_t)theInt;
for(unsigned dex=0; dex<DER_Data.Length; dex++) {
*dst-- = unsignedInt & 0xff;
unsignedInt >>= 8;
}
}
static CSSM_INTPTR DERToInt(
const CSSM_DATA &DER_Data)
{
CSSM_INTPTR rtn = 0;
uint8 *bp = DER_Data.Data;
for(unsigned dex=0; dex<DER_Data.Length; dex++) {
rtn <<= 8;
rtn |= *bp++;
}
return rtn;
}
void AppleTPSession::refKeyToRaw(
CSSM_CSP_HANDLE cspHand,
const CSSM_KEY *refKey,
CSSM_KEY_PTR rawKey) {
CSSM_CC_HANDLE ccHand;
CSSM_RETURN crtn;
CSSM_ACCESS_CREDENTIALS creds;
memset(rawKey, 0, sizeof(CSSM_KEY));
memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
CSSM_ALGID_NONE,
CSSM_ALGMODE_NONE,
&creds, NULL, NULL, CSSM_PADDING_NONE, 0, &ccHand);
if(crtn) {
tpCredDebug("AppleTPSession::refKeyToRaw: context err");
CssmError::throwMe(crtn);
}
crtn = CSSM_WrapKey(ccHand,
&creds,
refKey,
NULL, rawKey);
if(crtn != CSSM_OK) {
tpCredDebug("AppleTPSession::refKeyToRaw: wrapKey err");
CssmError::throwMe(crtn);
}
CSSM_DeleteContext(ccHand);
}
void AppleTPSession::makeCertTemplate(
CSSM_CL_HANDLE clHand,
CSSM_CSP_HANDLE cspHand, uint32 serialNumber,
const CSSM_X509_NAME *issuerName,
const CSSM_X509_NAME *subjectName,
const CSSM_X509_TIME *notBefore,
const CSSM_X509_TIME *notAfter,
const CSSM_KEY *subjectPubKey,
const CSSM_OID &sigOid,
const CSSM_DATA *subjectUniqueId,
const CSSM_DATA *issuerUniqueId,
CSSM_X509_EXTENSION *extensions,
unsigned numExtensions,
CSSM_DATA_PTR &rawCert)
{
CSSM_FIELD *certTemp;
unsigned fieldDex = 0; CSSM_DATA serialDER = {0, NULL}; CSSM_DATA versionDER = {0, NULL};
unsigned extNum;
CSSM_X509_ALGORITHM_IDENTIFIER algId;
const CSSM_KEY *actPubKey;
CSSM_KEY rawPubKey;
CSSM_BOOL freeRawKey = CSSM_FALSE;
rawCert = NULL;
algId.algorithm = sigOid;
CSSM_ALGORITHMS algorithmType = 0;
cssmOidToAlg(&sigOid, &algorithmType);
switch(algorithmType) {
case CSSM_ALGID_SHA1WithECDSA:
case CSSM_ALGID_SHA224WithECDSA:
case CSSM_ALGID_SHA256WithECDSA:
case CSSM_ALGID_SHA384WithECDSA:
case CSSM_ALGID_SHA512WithECDSA:
case CSSM_ALGID_ECDSA_SPECIFIED:
algId.parameters.Data = NULL;
algId.parameters.Length = 0;
break;
default:
static const uint8 encNull[2] = { SEC_ASN1_NULL, 0 };
CSSM_DATA encNullData;
encNullData.Data = (uint8 *)encNull;
encNullData.Length = 2;
algId.parameters = encNullData;
break;
}
switch(subjectPubKey->KeyHeader.BlobType) {
case CSSM_KEYBLOB_RAW:
actPubKey = subjectPubKey;
break;
case CSSM_KEYBLOB_REFERENCE:
refKeyToRaw(cspHand, subjectPubKey, &rawPubKey);
actPubKey = &rawPubKey;
freeRawKey = CSSM_TRUE;
break;
default:
tpCredDebug("CSSM_CL_CertCreateTemplate: bad key blob type (%u)",
(unsigned)subjectPubKey->KeyHeader.BlobType);
CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
}
unsigned numFields = 8 + numExtensions;
if(subjectUniqueId) {
numFields++;
}
if(issuerUniqueId) {
numFields++;
}
certTemp = (CSSM_FIELD *)malloc(sizeof(CSSM_FIELD) * numFields);
intToDER(2, versionDER, *this);
certTemp[fieldDex].FieldOid = CSSMOID_X509V1Version;
certTemp[fieldDex++].FieldValue = versionDER;
intToDER(serialNumber, serialDER, *this);
certTemp[fieldDex].FieldOid = CSSMOID_X509V1SerialNumber;
certTemp[fieldDex++].FieldValue = serialDER;
certTemp[fieldDex].FieldOid = CSSMOID_X509V1IssuerNameCStruct;
certTemp[fieldDex].FieldValue.Data = (uint8 *)issuerName;
certTemp[fieldDex++].FieldValue.Length = sizeof(CSSM_X509_NAME);
certTemp[fieldDex].FieldOid = CSSMOID_X509V1SubjectNameCStruct;
certTemp[fieldDex].FieldValue.Data = (uint8 *)subjectName;
certTemp[fieldDex++].FieldValue.Length = sizeof(CSSM_X509_NAME);
certTemp[fieldDex].FieldOid = CSSMOID_X509V1ValidityNotBefore;
certTemp[fieldDex].FieldValue.Data = (uint8 *)notBefore;
certTemp[fieldDex++].FieldValue.Length = sizeof(CSSM_X509_TIME);
certTemp[fieldDex].FieldOid = CSSMOID_X509V1ValidityNotAfter;
certTemp[fieldDex].FieldValue.Data = (uint8 *)notAfter;
certTemp[fieldDex++].FieldValue.Length = sizeof(CSSM_X509_TIME);
certTemp[fieldDex].FieldOid = CSSMOID_CSSMKeyStruct;
certTemp[fieldDex].FieldValue.Data = (uint8 *)actPubKey;
certTemp[fieldDex++].FieldValue.Length = sizeof(CSSM_KEY);
certTemp[fieldDex].FieldOid = CSSMOID_X509V1SignatureAlgorithmTBS;
certTemp[fieldDex].FieldValue.Data = (uint8 *)&algId;
certTemp[fieldDex++].FieldValue.Length = sizeof(CSSM_X509_ALGORITHM_IDENTIFIER);
if(subjectUniqueId != 0) {
certTemp[fieldDex].FieldOid = CSSMOID_X509V1CertificateSubjectUniqueId;
certTemp[fieldDex++].FieldValue = *subjectUniqueId;
}
if(issuerUniqueId != 0) {
certTemp[fieldDex].FieldOid = CSSMOID_X509V1CertificateIssuerUniqueId;
certTemp[fieldDex++].FieldValue = *issuerUniqueId;
}
for(extNum=0; extNum<numExtensions; extNum++) {
CSSM_X509_EXTENSION_PTR ext = &extensions[extNum];
if(ext->format == CSSM_X509_DATAFORMAT_PARSED) {
certTemp[fieldDex].FieldOid = ext->extnId;
}
else {
certTemp[fieldDex].FieldOid = CSSMOID_X509V3CertificateExtensionCStruct;
}
certTemp[fieldDex].FieldValue.Data = (uint8 *)ext;
certTemp[fieldDex++].FieldValue.Length = sizeof(CSSM_X509_EXTENSION);
}
assert(fieldDex == numFields);
rawCert = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
rawCert->Data = NULL;
rawCert->Length = 0;
CSSM_RETURN crtn = CSSM_CL_CertCreateTemplate(clHand,
fieldDex,
certTemp,
rawCert);
if(crtn) {
tpCredDebug("CSSM_CL_CertCreateTemplate returned %ld", (long)crtn);
free(rawCert->Data);
free(rawCert);
rawCert = NULL;
}
free(serialDER.Data);
free(versionDER.Data);
free(certTemp);
if(freeRawKey) {
tpFreeCssmData(*this, &rawPubKey.KeyData, CSSM_FALSE);
}
if(crtn) {
CssmError::throwMe(crtn);
}
}
void AppleTPSession::addCertToMap(
const CSSM_DATA *cert,
CSSM_DATA_PTR refId)
{
StLock<Mutex> _(tpCredMapLock);
TpCredHandle hand = reinterpret_cast<TpCredHandle>(cert);
intToDER(hand, *refId, *this);
tpCredMap[hand] = cert;
}
CSSM_DATA_PTR AppleTPSession::getCertFromMap(
const CSSM_DATA *refId)
{
StLock<Mutex> _(tpCredMapLock);
CSSM_DATA_PTR rtn = NULL;
if((refId == NULL) || (refId->Data == NULL)) {
return NULL;
}
TpCredHandle hand = DERToInt(*refId);
credMap::iterator it = tpCredMap.find(hand);
if(it == tpCredMap.end()) {
return NULL;
}
rtn = const_cast<CSSM_DATA *>(it->second);
tpCredMap.erase(hand);
return rtn;
}
void AppleTPSession::SubmitCsrRequest(
const CSSM_TP_REQUEST_SET &RequestInput,
const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthContext,
sint32 &EstimatedTime, CssmData &ReferenceIdentifier) {
CSSM_DATA_PTR csrPtr = NULL;
CSSM_CC_HANDLE sigHand = 0;
CSSM_APPLE_CL_CSR_REQUEST csrReq;
memset(&csrReq, 0, sizeof(csrReq));
CSSM_APPLE_TP_CERT_REQUEST *certReq =
(CSSM_APPLE_TP_CERT_REQUEST *)RequestInput.Requests;
if((certReq->cspHand == 0) ||
(certReq->clHand == 0) ||
(certReq->certPublicKey == NULL) ||
(certReq->issuerPrivateKey == NULL) ||
(certReq->signatureOid.Data == NULL)) {
CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
}
const CSSM_KEY *subjectPubKey = certReq->certPublicKey;
const CSSM_KEY *actPubKey = NULL;
CSSM_BOOL freeRawKey = CSSM_FALSE;
CSSM_KEY rawPubKey;
switch(subjectPubKey->KeyHeader.BlobType) {
case CSSM_KEYBLOB_RAW:
actPubKey = subjectPubKey;
break;
case CSSM_KEYBLOB_REFERENCE:
refKeyToRaw(certReq->cspHand, subjectPubKey, &rawPubKey);
actPubKey = &rawPubKey;
freeRawKey = CSSM_TRUE;
break;
default:
tpCredDebug("SubmitCsrRequest: bad key blob type (%u)",
(unsigned)subjectPubKey->KeyHeader.BlobType);
CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
}
csrReq.subjectNameX509 = buildX509Name(certReq->subjectNames,
certReq->numSubjectNames);
csrReq.signatureAlg = certReq->signatureAlg;
csrReq.signatureOid = certReq->signatureOid;
csrReq.cspHand = certReq->cspHand;
csrReq.subjectPublicKey = actPubKey;
csrReq.subjectPrivateKey = certReq->issuerPrivateKey;
csrReq.challengeString = certReq->challengeString;
CSSM_RETURN crtn;
crtn = CSSM_CSP_CreateSignatureContext(certReq->cspHand,
certReq->signatureAlg,
(CallerAuthContext ? CallerAuthContext->CallerCredentials : NULL),
certReq->issuerPrivateKey,
&sigHand);
if(crtn) {
tpCredDebug("CSSM_CSP_CreateSignatureContext returned %ld", (long)crtn);
goto abort;
}
crtn = CSSM_CL_PassThrough(certReq->clHand,
sigHand,
CSSM_APPLEX509CL_OBTAIN_CSR,
&csrReq,
(void **)&csrPtr);
if(crtn) {
tpCredDebug("CSSM_CL_PassThrough returned %ld", (long)crtn);
goto abort;
}
addCertToMap(csrPtr, &ReferenceIdentifier);
EstimatedTime = 0;
abort:
if(csrReq.subjectNameX509) {
freeX509Name(csrReq.subjectNameX509);
}
if(sigHand) {
CSSM_DeleteContext(sigHand);
}
if(freeRawKey) {
tpFreeCssmData(*this, &rawPubKey.KeyData, CSSM_FALSE);
}
if(crtn) {
CssmError::throwMe(crtn);
}
}
void AppleTPSession::SubmitCredRequest(
const CSSM_TP_AUTHORITY_ID *PreferredAuthority,
CSSM_TP_AUTHORITY_REQUEST_TYPE RequestType,
const CSSM_TP_REQUEST_SET &RequestInput,
const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthContext,
sint32 &EstimatedTime,
CssmData &ReferenceIdentifier)
{
CSSM_DATA_PTR certTemplate = NULL;
CSSM_X509_TIME_PTR notBeforeX509 = NULL;
CSSM_X509_TIME_PTR notAfterX509 = NULL;
CSSM_X509_NAME_PTR subjectX509 = NULL;
CSSM_X509_NAME_PTR issuerX509 = NULL;
CSSM_X509_EXTENSION_PTR extens509 = NULL;
CSSM_CC_HANDLE sigContext = 0;
CSSM_DATA_PTR signedCert = NULL;
if(PreferredAuthority != NULL) {
CssmError::throwMe(CSSMERR_TP_INVALID_AUTHORITY);
}
if(RequestType != CSSM_TP_AUTHORITY_REQUEST_CERTISSUE) {
CssmError::throwMe(CSSMERR_TP_UNSUPPORTED_SERVICE);
}
if(CallerAuthContext == NULL) {
CssmError::throwMe(CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER);
}
if((RequestInput.NumberOfRequests != 1) ||
(RequestInput.Requests == NULL)) {
CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
}
const CSSM_TP_POLICYINFO *tpPolicy = &CallerAuthContext->Policy;
if((tpPolicy->NumberOfPolicyIds != 1) ||
(tpPolicy->PolicyIds == NULL)) {
CssmError::throwMe(CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER);
}
if(tpCompareCssmData(&tpPolicy->PolicyIds->FieldOid,
&CSSMOID_APPLE_TP_CSR_GEN)) {
SubmitCsrRequest(RequestInput, CallerAuthContext, EstimatedTime, ReferenceIdentifier);
return;
}
else if(!tpCompareCssmData(&tpPolicy->PolicyIds->FieldOid,
&CSSMOID_APPLE_TP_LOCAL_CERT_GEN)) {
CssmError::throwMe(CSSMERR_TP_INVALID_POLICY_IDENTIFIERS);
}
CSSM_APPLE_TP_CERT_REQUEST *certReq =
(CSSM_APPLE_TP_CERT_REQUEST *)RequestInput.Requests;
if((certReq->cspHand == 0) ||
(certReq->clHand == 0) ||
(certReq->certPublicKey == NULL) ||
(certReq->issuerPrivateKey == NULL)) {
CssmError::throwMe(CSSMERR_TP_INVALID_REQUEST_INPUTS);
}
if((certReq->numExtensions != 0) & (certReq->extensions == NULL)) {
CssmError::throwMe(CSSMERR_TP_INVALID_POINTER);
}
CSSM_RETURN ourRtn = CSSM_OK;
try {
subjectX509 = buildX509Name(certReq->subjectNames, certReq->numSubjectNames);
if(certReq->issuerNames != NULL) {
issuerX509 = buildX509Name(certReq->issuerNames, certReq->numIssuerNames);
}
else if(certReq->issuerNameX509) {
issuerX509 = certReq->issuerNameX509;
}
else {
issuerX509 = subjectX509;
}
notBeforeX509 = buildX509Time(certReq->notBefore);
notAfterX509 = buildX509Time(certReq->notAfter);
if(certReq->numExtensions != 0) {
extens509 = (CSSM_X509_EXTENSION *)malloc(sizeof(CSSM_X509_EXTENSION) *
certReq->numExtensions);
memset(extens509, 0, sizeof(CSSM_X509_EXTENSION) *
certReq->numExtensions);
for(unsigned dex=0; dex<certReq->numExtensions; dex++) {
CSSM_X509_EXTENSION *extn = &extens509[dex];
CE_DataAndType *cdt = &certReq->extensions[dex];
void *parsedValue;
CSSM_OID extnId;
switch(cdt->type) {
case DT_AuthorityKeyID:
parsedValue = &cdt->extension.authorityKeyID;
extnId = CSSMOID_AuthorityKeyIdentifier;
break;
case DT_SubjectKeyID:
parsedValue = &cdt->extension.subjectKeyID;
extnId = CSSMOID_SubjectKeyIdentifier;
break;
case DT_KeyUsage:
parsedValue = &cdt->extension.keyUsage;
extnId = CSSMOID_KeyUsage;
break;
case DT_SubjectAltName:
parsedValue = &cdt->extension.subjectAltName;
extnId = CSSMOID_SubjectAltName;
break;
case DT_IssuerAltName:
parsedValue = &cdt->extension.issuerAltName;
extnId = CSSMOID_IssuerAltName;
break;
case DT_ExtendedKeyUsage:
parsedValue = &cdt->extension.extendedKeyUsage;
extnId = CSSMOID_ExtendedKeyUsage;
break;
case DT_BasicConstraints:
parsedValue = &cdt->extension.basicConstraints;
extnId = CSSMOID_BasicConstraints;
break;
case DT_CertPolicies:
parsedValue = &cdt->extension.certPolicies;
extnId = CSSMOID_CertificatePolicies;
break;
case DT_NetscapeCertType:
parsedValue = &cdt->extension.netscapeCertType;
extnId = CSSMOID_NetscapeCertType;
break;
case DT_CrlDistributionPoints:
parsedValue = &cdt->extension.crlDistPoints;
extnId = CSSMOID_CrlDistributionPoints;
break;
case DT_AuthorityInfoAccess:
parsedValue = &cdt->extension.authorityInfoAccess;
extnId = CSSMOID_AuthorityInfoAccess;
break;
case DT_Other:
default:
tpCredDebug("SubmitCredRequest: DT_Other not supported");
CssmError::throwMe(CSSMERR_TP_UNKNOWN_TAG);
}
extn->extnId = extnId;
extn->critical = cdt->critical;
extn->format = CSSM_X509_DATAFORMAT_PARSED;
extn->value.parsedValue = parsedValue;
extn->BERvalue.Data = NULL;
extn->BERvalue.Length = 0;
}
}
makeCertTemplate(certReq->clHand,
certReq->cspHand,
certReq->serialNumber,
issuerX509,
subjectX509,
notBeforeX509,
notAfterX509,
certReq->certPublicKey,
certReq->signatureOid,
NULL, NULL, extens509,
certReq->numExtensions,
certTemplate);
ourRtn = CSSM_CSP_CreateSignatureContext(certReq->cspHand,
certReq->signatureAlg,
(CallerAuthContext ? CallerAuthContext->CallerCredentials : NULL),
certReq->issuerPrivateKey,
&sigContext);
if(ourRtn) {
tpCredDebug("CSSM_CSP_CreateSignatureContext returned %ld", (long)ourRtn);
CssmError::throwMe(ourRtn);
}
signedCert = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
signedCert->Data = NULL;
signedCert->Length = 0;
ourRtn = CSSM_CL_CertSign(certReq->clHand,
sigContext,
certTemplate, NULL, 0, signedCert);
if(ourRtn) {
tpCredDebug("CSSM_CL_CertSign returned %ld", (long)ourRtn);
CssmError::throwMe(ourRtn);
}
addCertToMap(signedCert, &ReferenceIdentifier);
EstimatedTime = 0;
}
catch (const CssmError &cerr) {
tpCredDebug("SubmitCredRequest: CSSM error %ld", (long)cerr.error);
ourRtn = cerr.error;
}
catch(...) {
tpCredDebug("SubmitCredRequest: unknown exception");
ourRtn = CSSMERR_TP_INTERNAL_ERROR; }
tpFreeCssmData(*this, certTemplate, CSSM_TRUE);
freeX509Name(subjectX509);
if(certReq->issuerNames) {
freeX509Name(issuerX509);
}
freeX509Time(notBeforeX509);
freeX509Time(notAfterX509);
if(extens509) {
free(extens509);
}
if(sigContext != 0) {
CSSM_DeleteContext(sigContext);
}
if(ourRtn) {
CssmError::throwMe(ourRtn);
}
}
void AppleTPSession::RetrieveCredResult(
const CssmData &ReferenceIdentifier,
const CSSM_TP_CALLERAUTH_CONTEXT *CallerAuthCredentials,
sint32 &EstimatedTime,
CSSM_BOOL &ConfirmationRequired,
CSSM_TP_RESULT_SET_PTR &RetrieveOutput)
{
CSSM_DATA *cert = getCertFromMap(&ReferenceIdentifier);
if(cert == NULL) {
tpCredDebug("RetrieveCredResult: refId not found");
CssmError::throwMe(CSSMERR_TP_INVALID_IDENTIFIER);
}
CSSM_ENCODED_CERT *encCert = (CSSM_ENCODED_CERT *)malloc(sizeof(CSSM_ENCODED_CERT));
encCert->CertType = CSSM_CERT_X_509v3;
encCert->CertEncoding = CSSM_CERT_ENCODING_DER;
encCert->CertBlob = *cert;
RetrieveOutput = (CSSM_TP_RESULT_SET_PTR)malloc(
sizeof(CSSM_TP_RESULT_SET));
RetrieveOutput->Results = encCert;
RetrieveOutput->NumberOfResults = 1;
ConfirmationRequired = CSSM_FALSE;
free(cert);
EstimatedTime = 0;
}