#include "AppleX509CLSession.h"
#include "clNssUtils.h"
#include "clNameUtils.h"
void
AppleX509CLSession::CrlDescribeFormat(
uint32 &NumberOfFields,
CSSM_OID_PTR &OidList)
{
DecodedCrl::describeFormat(*this, NumberOfFields, OidList);
}
void
AppleX509CLSession::CrlGetAllFields(
const CssmData &Crl,
uint32 &NumberOfCrlFields,
CSSM_FIELD_PTR &CrlFields)
{
class DecodedCrl decodedCrl(*this, Crl);
decodedCrl.getAllParsedCrlFields(NumberOfCrlFields, CrlFields);
}
CSSM_HANDLE
AppleX509CLSession::CrlGetFirstFieldValue(
const CssmData &Crl,
const CssmData &CrlField,
uint32 &NumberOfMatchedFields,
CSSM_DATA_PTR &Value)
{
NumberOfMatchedFields = 0;
Value = NULL;
CssmAutoData aData(*this);
DecodedCrl *decodedCrl = new DecodedCrl(*this, Crl);
uint32 numMatches;
bool brtn;
try {
brtn = decodedCrl->getCrlFieldData(CrlField,
0, numMatches,
aData);
}
catch (...) {
delete decodedCrl;
throw;
}
if(!brtn) {
delete decodedCrl;
return CSSM_INVALID_HANDLE;
}
CLCachedCRL *cachedCrl = new CLCachedCRL(*decodedCrl);
cacheMap.addEntry(*cachedCrl, cachedCrl->handle());
CLQuery *query = new CLQuery(
CLQ_CRL,
CrlField,
numMatches,
false, cachedCrl->handle());
queryMap.addEntry(*query, query->handle());
Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
*Value = aData.release();
NumberOfMatchedFields = numMatches;
return query->handle();
}
bool
AppleX509CLSession::CrlGetNextFieldValue(
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_CRL) {
clErrorLog("CrlGetNextFieldValue: bad queryType (%d)",
(int)query->queryType());
CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
}
if(query->nextIndex() >= query->numFields()) {
return false;
}
CLCachedCRL *cachedCrl = lookupCachedCRL(query->cachedObject());
uint32 dummy;
CssmAutoData aData(*this);
if(!cachedCrl->crl().getCrlFieldData(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::IsCertInCrl(
const CssmData &Cert,
const CssmData &Crl,
CSSM_BOOL &CertFound)
{
DecodedCert decodedCert(*this, Cert);
DecodedCrl decodedCrl(*this, Crl);
NSS_TBSCertificate &tbsCert = decodedCert.mCert.tbs;
NSS_TBSCrl &tbsCrl = decodedCrl.mCrl.tbs;
unsigned numCrlEntries =
clNssArraySize((const void **)tbsCrl.revokedCerts);
if(numCrlEntries == 0) {
clFieldLog("IsCertInCrl: empty CRL");
CertFound = CSSM_FALSE;
return;
}
CssmAutoData encCertIssuer(*this);
CssmAutoData encCrlIssuer(*this);
try {
SecNssCoder &coder = decodedCert.coder();
CL_normalizeX509NameNSS(tbsCert.issuer, coder);
PRErrorCode prtn = SecNssEncodeItemOdata(&tbsCert.issuer,
kSecAsn1NameTemplate, encCertIssuer);
if(prtn) {
CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
}
CL_normalizeX509NameNSS(tbsCrl.issuer, coder);
prtn = SecNssEncodeItemOdata(&tbsCrl.issuer,
kSecAsn1NameTemplate, encCrlIssuer);
if(prtn) {
CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
}
}
catch(...) {
clFieldLog("IsCertInCrl: normalize failure");
throw;
}
CertFound = CSSM_FALSE;
if(encCertIssuer.get() != encCrlIssuer.get()) {
clFieldLog("IsCertInCrl: issuer name mismatch");
return;
}
CSSM_DATA &certSerial = tbsCert.serialNumber;
for(unsigned dex=0; dex<numCrlEntries; dex++) {
NSS_RevokedCert *revokedCert = tbsCrl.revokedCerts[dex];
assert(revokedCert != NULL);
CSSM_DATA &revokedSerial = revokedCert->userCertificate;
if(clCompareCssmData(&certSerial, &revokedSerial)) {
CertFound = CSSM_TRUE;
break;
}
}
}
#pragma mark --- Cached ---
void
AppleX509CLSession::CrlCache(
const CssmData &Crl,
CSSM_HANDLE &CrlHandle)
{
DecodedCrl *decodedCrl = new DecodedCrl(*this, Crl);
CLCachedCRL *cachedCrl = new CLCachedCRL(*decodedCrl);
cacheMap.addEntry(*cachedCrl, cachedCrl->handle());
CrlHandle = cachedCrl->handle();
}
CSSM_HANDLE
AppleX509CLSession::CrlGetFirstCachedFieldValue(
CSSM_HANDLE CrlHandle,
const CssmData *CrlRecordIndex,
const CssmData &CrlField,
uint32 &NumberOfMatchedFields,
CSSM_DATA_PTR &Value)
{
if(CrlRecordIndex != NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_CRL_INDEX);
}
CLCachedCRL *cachedCrl = lookupCachedCRL(CrlHandle);
if(cachedCrl == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
}
CssmAutoData aData(*this);
uint32 numMatches;
if(!cachedCrl->crl().getCrlFieldData(CrlField,
0, numMatches,
aData)) {
return CSSM_INVALID_HANDLE;
}
CLQuery *query = new CLQuery(
CLQ_CRL,
CrlField,
numMatches,
true, cachedCrl->handle());
queryMap.addEntry(*query, query->handle());
Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
*Value = aData.release();
NumberOfMatchedFields = numMatches;
return query->handle();
}
bool
AppleX509CLSession::CrlGetNextCachedFieldValue(
CSSM_HANDLE ResultsHandle,
CSSM_DATA_PTR &Value)
{
return CrlGetNextFieldValue(ResultsHandle, Value);
}
void
AppleX509CLSession::IsCertInCachedCrl(
const CssmData &Cert,
CSSM_HANDLE CrlHandle,
CSSM_BOOL &CertFound,
CssmData &CrlRecordIndex)
{
unimplemented();
}
void
AppleX509CLSession::CrlAbortCache(
CSSM_HANDLE CrlHandle)
{
CLCachedCRL *cachedCrl = lookupCachedCRL(CrlHandle);
if(cachedCrl == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
}
cacheMap.removeEntry(cachedCrl->handle());
delete cachedCrl;
}
void
AppleX509CLSession::CrlAbortQuery(
CSSM_HANDLE ResultsHandle)
{
CLQuery *query = queryMap.lookupEntry(ResultsHandle);
if(query == NULL) {
CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
}
if(query->queryType() != CLQ_CRL) {
clErrorLog("CrlAbortQuery: bad queryType (%d)", (int)query->queryType());
CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
}
if(!query->fromCache()) {
CLCachedCRL *cachedCrl = lookupCachedCRL(query->cachedObject());
if(cachedCrl == NULL) {
CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
}
cacheMap.removeEntry(cachedCrl->handle());
delete cachedCrl;
}
queryMap.removeEntry(query->handle());
delete query;
}
#pragma mark --- Template ---
void
AppleX509CLSession::CrlCreateTemplate(
uint32 NumberOfFields,
const CSSM_FIELD *CrlTemplate,
CssmData &NewCrl)
{
unimplemented();
}
void
AppleX509CLSession::CrlSetFields(
uint32 NumberOfFields,
const CSSM_FIELD *CrlTemplate,
const CssmData &OldCrl,
CssmData &ModifiedCrl)
{
unimplemented();
}
void
AppleX509CLSession::CrlAddCert(
CSSM_CC_HANDLE CCHandle,
const CssmData &Cert,
uint32 NumberOfFields,
const CSSM_FIELD CrlEntryFields[],
const CssmData &OldCrl,
CssmData &NewCrl)
{
unimplemented();
}
void
AppleX509CLSession::CrlRemoveCert(
const CssmData &Cert,
const CssmData &OldCrl,
CssmData &NewCrl)
{
unimplemented();
}
void
AppleX509CLSession::CrlGetAllCachedRecordFields(
CSSM_HANDLE CrlHandle,
const CssmData &CrlRecordIndex,
uint32 &NumberOfFields,
CSSM_FIELD_PTR &CrlFields)
{
unimplemented();
}
void
AppleX509CLSession::CrlVerifyWithKey(
CSSM_CC_HANDLE CCHandle,
const CssmData &CrlToBeVerified)
{
CertVerifyWithKey(CCHandle, CrlToBeVerified);
}
void
AppleX509CLSession::CrlVerify(
CSSM_CC_HANDLE CCHandle,
const CssmData &CrlToBeVerified,
const CssmData *SignerCert,
const CSSM_FIELD *VerifyScope,
uint32 ScopeSize)
{
CertVerify(CCHandle, CrlToBeVerified, SignerCert, VerifyScope,
ScopeSize);
}
void
AppleX509CLSession::CrlSign(
CSSM_CC_HANDLE CCHandle,
const CssmData &UnsignedCrl,
const CSSM_FIELD *SignScope,
uint32 ScopeSize,
CssmData &SignedCrl)
{
unimplemented();
}