#include "AppleX509CLSession.h"
#include "DecodedCert.h"
#include "DecodedCrl.h"
#include "CLCachedEntry.h"
#include "cldebugging.h"
#include <Security/oidscert.h>
void
AppleX509CLSession::CertDescribeFormat(
uint32 &NumberOfFields,
CSSM_OID_PTR &OidList)
{
DecodedCert::describeFormat(*this, NumberOfFields, OidList);
}
void
AppleX509CLSession::CertGetAllFields(
const CssmData &Cert,
uint32 &NumberOfFields,
CSSM_FIELD_PTR &CertFields)
{
DecodedCert decodedCert(*this, Cert);
decodedCert.getAllParsedCertFields(NumberOfFields, CertFields);
}
CSSM_HANDLE
AppleX509CLSession::CertGetFirstFieldValue(
const CssmData &EncodedCert,
const CssmData &CertField,
uint32 &NumberOfMatchedFields,
CSSM_DATA_PTR &Value)
{
NumberOfMatchedFields = 0;
Value = NULL;
CssmAutoData aData(*this);
DecodedCert *decodedCert = new DecodedCert(*this, EncodedCert);
uint32 numMatches;
bool brtn;
try {
brtn = decodedCert->getCertFieldData(CertField,
0, numMatches,
aData);
}
catch (...) {
delete decodedCert;
throw;
}
if(!brtn) {
delete decodedCert;
return CSSM_INVALID_HANDLE;
}
CLCachedCert *cachedCert = new CLCachedCert(*decodedCert);
cacheMap.addEntry(*cachedCert, cachedCert->handle());
CLQuery *query = new CLQuery(
CLQ_Cert,
CertField,
numMatches,
false, cachedCert->handle());
queryMap.addEntry(*query, query->handle());
Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
*Value = aData.release();
NumberOfMatchedFields = numMatches;
return query->handle();
}
bool
AppleX509CLSession::CertGetNextFieldValue(
CSSM_HANDLE ResultsHandle,
CSSM_DATA_PTR &Value)
{
CLQuery *query = queryMap.lookupEntry(ResultsHandle);
if(query == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
}
if(query->queryType() != CLQ_Cert) {
clErrorLog("CertGetNextFieldValue: bad queryType (%d)", (int)query->queryType());
CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
}
if(query->nextIndex() >= query->numFields()) {
return false;
}
CLCachedCert *cachedCert = lookupCachedCert(query->cachedObject());
uint32 dummy;
CssmAutoData aData(*this);
if(!cachedCert->cert().getCertFieldData(query->fieldId(),
query->nextIndex(),
dummy,
aData)) {
return false;
}
Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
*Value = aData.release();
query->incrementIndex();
return true;
}
void
AppleX509CLSession::CertCache(
const CssmData &EncodedCert,
CSSM_HANDLE &CertHandle)
{
DecodedCert *decodedCert = new DecodedCert(*this, EncodedCert);
CLCachedCert *cachedCert = new CLCachedCert(*decodedCert);
cacheMap.addEntry(*cachedCert, cachedCert->handle());
CertHandle = cachedCert->handle();
}
CSSM_HANDLE
AppleX509CLSession::CertGetFirstCachedFieldValue(
CSSM_HANDLE CertHandle,
const CssmData &CertField,
uint32 &NumberOfMatchedFields,
CSSM_DATA_PTR &Value)
{
CLCachedCert *cachedCert = lookupCachedCert(CertHandle);
if(cachedCert == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
}
CssmAutoData aData(*this);
uint32 numMatches;
if(!cachedCert->cert().getCertFieldData(CertField,
0, numMatches,
aData)) {
return CSSM_INVALID_HANDLE;
}
CLQuery *query = new CLQuery(
CLQ_Cert,
CertField,
numMatches,
true, cachedCert->handle());
queryMap.addEntry(*query, query->handle());
Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
*Value = aData.release();
NumberOfMatchedFields = numMatches;
return query->handle();
}
bool
AppleX509CLSession::CertGetNextCachedFieldValue(
CSSM_HANDLE ResultsHandle,
CSSM_DATA_PTR &Value)
{
return CertGetNextFieldValue(ResultsHandle, Value);
}
void
AppleX509CLSession::CertAbortCache(
CSSM_HANDLE CertHandle)
{
CLCachedCert *cachedCert = lookupCachedCert(CertHandle);
if(cachedCert == NULL) {
clErrorLog("CertAbortCache: cachedCert not found");
CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
}
cacheMap.removeEntry(cachedCert->handle());
delete cachedCert;
}
void
AppleX509CLSession::CertAbortQuery(
CSSM_HANDLE ResultsHandle)
{
CLQuery *query = queryMap.lookupEntry(ResultsHandle);
if(query == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
}
if(query->queryType() != CLQ_Cert) {
clErrorLog("CertAbortQuery: bad queryType (%d)", (int)query->queryType());
CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
}
if(!query->fromCache()) {
CLCachedCert *cachedCert = lookupCachedCert(query->cachedObject());
if(cachedCert == NULL) {
clErrorLog("CertAbortQuery: cachedCert not found");
CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
}
cacheMap.removeEntry(cachedCert->handle());
delete cachedCert;
}
queryMap.removeEntry(query->handle());
delete query;
}
void
AppleX509CLSession::CertCreateTemplate(
uint32 NumberOfFields,
const CSSM_FIELD CertFields[],
CssmData &CertTemplate)
{
DecodedCert cert(*this);
for(uint32 dex=0; dex<NumberOfFields; dex++) {
cert.setCertField(
CssmOid::overlay(CertFields[dex].FieldOid),
CssmData::overlay(CertFields[dex].FieldValue));
}
CertTemplate.Data = NULL;
CertTemplate.Length = 0;
CssmRemoteData rData(*this, CertTemplate);
cert.encodeTbs(rData);
rData.release();
}
void
AppleX509CLSession::CertGetAllTemplateFields(
const CssmData &CertTemplate,
uint32 &NumberOfFields,
CSSM_FIELD_PTR &CertFields)
{
DecodedCert cert(*this); cert.decodeTbs(CertTemplate);
cert.getAllParsedCertFields(NumberOfFields, CertFields);
}
void
AppleX509CLSession::FreeFields(
uint32 NumberOfFields,
CSSM_FIELD_PTR &FieldArray)
{
unsigned i;
CSSM_FIELD_PTR thisField;
CSSM_OID_PTR thisOid;
for(i=0; i<NumberOfFields; i++) {
thisField = &FieldArray[i];
thisOid = &thisField->FieldOid;
CssmData &cData = CssmData::overlay(thisField->FieldValue);
CssmRemoteData rData(*this, cData);
try {
DecodedCert::freeCertFieldData(CssmOid::overlay(*thisOid), rData);
}
catch(...) {
DecodedCrl::freeCrlFieldData(CssmOid::overlay(*thisOid), rData);
}
free(thisOid->Data);
thisOid->Data = NULL;
thisOid->Length = 0;
}
free(FieldArray);
}
void
AppleX509CLSession::FreeFieldValue(
const CssmData &CertOrCrlOid,
CssmData &Value)
{
CssmRemoteData cd(*this, Value);
try {
DecodedCert::freeCertFieldData(CertOrCrlOid, cd);
}
catch(...) {
DecodedCrl::freeCrlFieldData(CertOrCrlOid, cd);
}
free(&Value);
}
void
AppleX509CLSession::CertGroupFromVerifiedBundle(
CSSM_CC_HANDLE CCHandle,
const CSSM_CERT_BUNDLE &CertBundle,
const CssmData *SignerCert,
CSSM_CERTGROUP_PTR &CertGroup)
{
unimplemented();
}
void
AppleX509CLSession::CertGroupToSignedBundle(
CSSM_CC_HANDLE CCHandle,
const CSSM_CERTGROUP &CertGroupToBundle,
const CSSM_CERT_BUNDLE_HEADER *BundleInfo,
CssmData &SignedBundle)
{
unimplemented();
}
void
AppleX509CLSession::PassThrough(
CSSM_CC_HANDLE CCHandle,
uint32 PassThroughId,
const void *InputParams,
void **OutputParams)
{
switch(PassThroughId) {
case CSSM_APPLEX509CL_OBTAIN_CSR:
{
if(InputParams == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_INPUT_POINTER);
}
if(OutputParams == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_OUTPUT_POINTER);
}
CSSM_APPLE_CL_CSR_REQUEST *csrReq =
(CSSM_APPLE_CL_CSR_REQUEST *)InputParams;
if((csrReq->subjectNameX509 == NULL) ||
(csrReq->signatureOid.Data == NULL) ||
(csrReq->subjectPublicKey == NULL) ||
(csrReq->subjectPrivateKey == NULL)) {
CssmError::throwMe(CSSMERR_CL_INVALID_INPUT_POINTER);
}
CSSM_DATA_PTR csrPtr = NULL;
generateCsr(CCHandle, csrReq, csrPtr);
*OutputParams = csrPtr;
break;
}
case CSSM_APPLEX509CL_VERIFY_CSR:
{
if(InputParams == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_INPUT_POINTER);
}
const CSSM_DATA *csrPtr = (const CSSM_DATA *)InputParams;
verifyCsr(csrPtr);
break;
}
default:
CssmError::throwMe(CSSMERR_CL_INVALID_PASSTHROUGH_ID);
}
}