//
#include "AppleX509CLSession.h"
+#include "clNssUtils.h"
+#include "clNameUtils.h"
void
AppleX509CLSession::CrlDescribeFormat(
uint32 &NumberOfFields,
CSSM_OID_PTR &OidList)
{
- unimplemented();
+ DecodedCrl::describeFormat(*this, NumberOfFields, OidList);
}
uint32 &NumberOfCrlFields,
CSSM_FIELD_PTR &CrlFields)
{
- unimplemented();
+ class DecodedCrl decodedCrl(*this, Crl);
+ decodedCrl.getAllParsedCrlFields(NumberOfCrlFields, CrlFields);
}
uint32 &NumberOfMatchedFields,
CSSM_DATA_PTR &Value)
{
- unimplemented();
- return CSSM_INVALID_HANDLE;
+ NumberOfMatchedFields = 0;
+ Value = NULL;
+ CssmAutoData aData(*this);
+
+ DecodedCrl *decodedCrl = new DecodedCrl(*this, Crl);
+ uint32 numMatches;
+
+ /* this returns false if field not there, throws on bad OID */
+ bool brtn;
+ try {
+ brtn = decodedCrl->getCrlFieldData(CrlField,
+ 0, // index
+ numMatches,
+ aData);
+ }
+ catch (...) {
+ delete decodedCrl;
+ throw;
+ }
+ if(!brtn) {
+ delete decodedCrl;
+ return CSSM_INVALID_HANDLE;
+ }
+
+ /* cook up a CLCachedCRL, stash it in cache */
+ CLCachedCRL *cachedCrl = new CLCachedCRL(*decodedCrl);
+ cacheMap.addEntry(*cachedCrl, cachedCrl->handle());
+
+ /* cook up a CLQuery, stash it */
+ CLQuery *query = new CLQuery(
+ CLQ_CRL,
+ CrlField,
+ numMatches,
+ false, // isFromCache
+ cachedCrl->handle());
+ queryMap.addEntry(*query, query->handle());
+
+ /* success - copy field data to outgoing Value */
+ Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
+ *Value = aData.release();
+ NumberOfMatchedFields = numMatches;
+ return query->handle();
}
CSSM_HANDLE ResultsHandle,
CSSM_DATA_PTR &Value)
{
- unimplemented();
- return false;
+ /* fetch & validate the query */
+ 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;
+ }
+
+ /* fetch the associated cached CRL */
+ CLCachedCRL *cachedCrl = lookupCachedCRL(query->cachedObject());
+ uint32 dummy;
+ CssmAutoData aData(*this);
+ if(!cachedCrl->crl().getCrlFieldData(query->fieldId(),
+ query->nextIndex(),
+ dummy,
+ aData)) {
+ return false;
+ }
+
+ /* success - copy field data to outgoing Value */
+ Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
+ *Value = aData.release();
+ query->incrementIndex();
+ return true;
}
const CssmData &Crl,
CSSM_BOOL &CertFound)
{
- unimplemented();
-}
-
+ /*
+ * Decode the two entities. Note that doing it this way incurs
+ * the unnecessary (for our purposes) overhead of decoding
+ * extensions, but doing it this way is so spiffy that I can't
+ * resist.
+ */
+ DecodedCert decodedCert(*this, Cert);
+ DecodedCrl decodedCrl(*this, Crl);
+
+ NSS_TBSCertificate &tbsCert = decodedCert.mCert.tbs;
+ NSS_TBSCrl &tbsCrl = decodedCrl.mCrl.tbs;
+
+ /* trivial case - empty CRL */
+ unsigned numCrlEntries =
+ clNssArraySize((const void **)tbsCrl.revokedCerts);
+ if(numCrlEntries == 0) {
+ clFieldLog("IsCertInCrl: empty CRL");
+ CertFound = CSSM_FALSE;
+ return;
+ }
+ /*
+ * Get normalized and encoded versions of issuer names.
+ * Since the decoded entities are local, we can normalize in place.
+ */
+ CssmAutoData encCertIssuer(*this);
+ CssmAutoData encCrlIssuer(*this);
+ try {
+ /* snag a handy temp allocator */
+ SecNssCoder &coder = decodedCert.coder();
+ CL_normalizeX509NameNSS(tbsCert.issuer, coder);
+ PRErrorCode prtn = SecNssEncodeItemOdata(&tbsCert.issuer,
+ NSS_NameTemplate, encCertIssuer);
+ if(prtn) {
+ CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
+ }
+
+ CL_normalizeX509NameNSS(tbsCrl.issuer, coder);
+ prtn = SecNssEncodeItemOdata(&tbsCrl.issuer,
+ NSS_NameTemplate, encCrlIssuer);
+ if(prtn) {
+ CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
+ }
+ }
+ catch(...) {
+ clFieldLog("IsCertInCrl: normalize failure");
+ throw;
+ }
-#if __MWERKS__
-#pragma mark Cached
-#endif
+ /* issuer names match? */
+ CertFound = CSSM_FALSE;
+ if(encCertIssuer.get() != encCrlIssuer.get()) {
+ clFieldLog("IsCertInCrl: issuer name mismatch");
+ return;
+ }
+
+ /* is this cert's serial number in the CRL? */
+ 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)) {
+ /* success */
+ CertFound = CSSM_TRUE;
+ break;
+ }
+ }
+}
+
+#pragma mark --- Cached ---
void
AppleX509CLSession::CrlCache(
const CssmData &Crl,
CSSM_HANDLE &CrlHandle)
{
- unimplemented();
+ DecodedCrl *decodedCrl = new DecodedCrl(*this, Crl);
+
+ /* cook up a CLCachedCRL, stash it in cache */
+ CLCachedCRL *cachedCrl = new CLCachedCRL(*decodedCrl);
+ cacheMap.addEntry(*cachedCrl, cachedCrl->handle());
+ CrlHandle = cachedCrl->handle();
}
-
+/*
+ * FIXME - CrlRecordIndex not supported, it'll require mods to
+ * the DecodedCrl::getCrlFieldData mechanism
+ */
CSSM_HANDLE
AppleX509CLSession::CrlGetFirstCachedFieldValue(
CSSM_HANDLE CrlHandle,
uint32 &NumberOfMatchedFields,
CSSM_DATA_PTR &Value)
{
- unimplemented();
- return CSSM_INVALID_HANDLE;
+ if(CrlRecordIndex != NULL) {
+ /* not yet */
+ CssmError::throwMe(CSSMERR_CL_INVALID_CRL_INDEX);
+ }
+
+ /* fetch the associated cached CRL */
+ CLCachedCRL *cachedCrl = lookupCachedCRL(CrlHandle);
+ if(cachedCrl == NULL) {
+ CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
+ }
+
+ CssmAutoData aData(*this);
+ uint32 numMatches;
+
+ /* this returns false if field not there, throws on bad OID */
+ if(!cachedCrl->crl().getCrlFieldData(CrlField,
+ 0, // index
+ numMatches,
+ aData)) {
+ return CSSM_INVALID_HANDLE;
+ }
+
+ /* cook up a CLQuery, stash it */
+ CLQuery *query = new CLQuery(
+ CLQ_CRL,
+ CrlField,
+ numMatches,
+ true, // isFromCache
+ cachedCrl->handle());
+ queryMap.addEntry(*query, query->handle());
+
+ /* success - copy field data to outgoing Value */
+ Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
+ *Value = aData.release();
+ NumberOfMatchedFields = numMatches;
+ return query->handle();
}
CSSM_HANDLE ResultsHandle,
CSSM_DATA_PTR &Value)
{
- unimplemented();
- return false;
+ /* Identical to, so just call... */
+ return CrlGetNextFieldValue(ResultsHandle, Value);
}
AppleX509CLSession::CrlAbortCache(
CSSM_HANDLE CrlHandle)
{
- unimplemented();
+ /* fetch the associated cached CRL, remove from map, delete it */
+ CLCachedCRL *cachedCrl = lookupCachedCRL(CrlHandle);
+ if(cachedCrl == NULL) {
+ CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
+ }
+ cacheMap.removeEntry(cachedCrl->handle());
+ delete cachedCrl;
}
AppleX509CLSession::CrlAbortQuery(
CSSM_HANDLE ResultsHandle)
{
- unimplemented();
+ /* fetch & validate the query */
+ 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()) {
+ /* the associated cached CRL was created just for this query; dispose */
+ CLCachedCRL *cachedCrl = lookupCachedCRL(query->cachedObject());
+ if(cachedCrl == NULL) {
+ /* should never happen */
+ CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
+ }
+ cacheMap.removeEntry(cachedCrl->handle());
+ delete cachedCrl;
+ }
+ queryMap.removeEntry(query->handle());
+ delete query;
}
-
-
-#if __MWERKS__
-#pragma mark Template
-#endif
+#pragma mark --- Template ---
void
AppleX509CLSession::CrlCreateTemplate(
unimplemented();
}
+/*
+ * These are functionally identical to the corresponding
+ * Cert functions.
+ */
void
AppleX509CLSession::CrlVerifyWithKey(
CSSM_CC_HANDLE CCHandle,
const CssmData &CrlToBeVerified)
{
- unimplemented();
+ CertVerifyWithKey(CCHandle, CrlToBeVerified);
}
AppleX509CLSession::CrlVerify(
CSSM_CC_HANDLE CCHandle,
const CssmData &CrlToBeVerified,
- const CssmData &SignerCert,
+ const CssmData *SignerCert,
const CSSM_FIELD *VerifyScope,
uint32 ScopeSize)
{
- unimplemented();
+ CertVerify(CCHandle, CrlToBeVerified, SignerCert, VerifyScope,
+ ScopeSize);
}
void