certGroupUtils.cpp [plain text]
#include <Security/cssmtype.h>
#include <Security/cssmapi.h>
#include <Security/x509defs.h>
#include <Security/oidscert.h>
#include <Security/oidsalg.h>
#include <Security/cssmapple.h>
#include "certGroupUtils.h"
#include "cldebugging.h"
#include "tpTime.h"
#include <string.h>
#if 0
void *tpCalloc(CssmAllocator &alloc, uint32 num, uint32 size)
{
void *p = alloc.malloc(num * size);
memset(p, 0, num* size);
return p;
}
#endif
void tpCopyCssmData(
CssmAllocator &alloc,
const CSSM_DATA *src,
CSSM_DATA_PTR dst)
{
dst->Data = (uint8 *)alloc.malloc(src->Length);
dst->Length = src->Length;
memmove(dst->Data, src->Data, src->Length);
}
CSSM_DATA_PTR tpMallocCopyCssmData(
CssmAllocator &alloc,
const CSSM_DATA *src)
{
CSSM_DATA_PTR dst = (CSSM_DATA_PTR)alloc.malloc(sizeof(CSSM_DATA));
tpCopyCssmData(alloc, src, dst);
return dst;
}
void tpFreeCssmData(
CssmAllocator &alloc,
CSSM_DATA_PTR data,
CSSM_BOOL freeStruct)
{
if(data == NULL) {
return;
}
if(data->Length != 0) {
tpFree(alloc, data->Data);
}
if(freeStruct) {
tpFree(alloc, data);
}
else {
data->Length = 0;
data->Data = NULL;
}
}
CSSM_BOOL tpCompareCssmData(
const CSSM_DATA *data1,
const CSSM_DATA *data2)
{
if((data1 == NULL) || (data1->Data == NULL) ||
(data2 == NULL) || (data2->Data == NULL) ||
(data1->Length != data2->Length)) {
return CSSM_FALSE;
}
if(data1->Length != data2->Length) {
return CSSM_FALSE;
}
if(memcmp(data1->Data, data2->Data, data1->Length) == 0) {
return CSSM_TRUE;
}
else {
return CSSM_FALSE;
}
}
CSSM_BOOL tpCompareOids(
const CSSM_OID *oid1,
const CSSM_OID *oid2)
{
return tpCompareCssmData(oid1, oid2);
}
CSSM_DATA_PTR tp_CertGetPublicKey(
TPCertInfo *cert,
CSSM_DATA_PTR *valueToFree) {
CSSM_RETURN crtn;
CSSM_DATA_PTR val;
CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *keyInfo;
*valueToFree = NULL;
crtn = cert->fetchField(&CSSMOID_X509V1SubjectPublicKeyCStruct, &val);
if(crtn) {
errorLog0("Error on CSSM_CL_CertGetFirstFieldValue(PublicKeyCStruct)\n");
return NULL;
}
*valueToFree = val;
keyInfo = (CSSM_X509_SUBJECT_PUBLIC_KEY_INFO *)val->Data;
return &keyInfo->subjectPublicKey;
}
void tp_CertFreePublicKey(
CSSM_CL_HANDLE clHand,
CSSM_DATA_PTR value)
{
CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectPublicKeyCStruct, value);
}
CSSM_X509_ALGORITHM_IDENTIFIER_PTR tp_CertGetAlgId(
TPCertInfo *cert,
CSSM_DATA_PTR *valueToFree) {
CSSM_RETURN crtn;
CSSM_DATA_PTR val;
*valueToFree = NULL;
crtn = cert->fetchField(&CSSMOID_X509V1SignatureAlgorithm, &val);
if(crtn) {
errorLog0("Error on fetchField(CSSMOID_X509V1SignatureAlgorithm)\n");
return NULL;
}
*valueToFree = val;
return (CSSM_X509_ALGORITHM_IDENTIFIER_PTR)val->Data;
}
void tp_CertFreeAlgId(
CSSM_CL_HANDLE clHand,
CSSM_DATA_PTR value)
{
CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SignatureAlgorithm, value);
}
CSSM_BOOL tpIsSameName(
const CSSM_DATA *name1,
const CSSM_DATA *name2)
{
return tpCompareCssmData(name1, name2);
}
CSSM_RETURN tp_VerifyCert(
CSSM_CL_HANDLE clHand,
CSSM_CSP_HANDLE cspHand,
TPCertInfo *subjectCert,
TPCertInfo *issuerCert,
CSSM_BOOL checkIssuerCurrent,
CSSM_BOOL allowExpired)
{
CSSM_RETURN crtn;
crtn = CSSM_CL_CertVerify(clHand,
CSSM_INVALID_HANDLE,
subjectCert->certData(),
issuerCert->certData(),
NULL, 0); if(crtn == CSSM_OK) {
if(checkIssuerCurrent) {
crtn = issuerCert->isCurrent(allowExpired);
}
}
else {
crtn = CSSMERR_TP_VERIFICATION_FAILURE;
}
return crtn;
}
CSSM_BOOL tp_CompareCerts(
const CSSM_DATA *cert1,
const CSSM_DATA *cert2)
{
return tpCompareCssmData(cert1, cert2);
}
#if TP_DL_ENABLE
static CSSM_DB_UNIQUE_RECORD_PTR tpCertLookup(
CSSM_TP_HANDLE tpHand,
CSSM_DL_DB_HANDLE dlDb,
const CSSM_DATA_PTR subjectName, CSSM_HANDLE_PTR resultHand,
CSSM_DATA_PTR cert) {
CSSM_QUERY query;
CSSM_SELECTION_PREDICATE predicate;
CSSM_BOOL EndOfDataStore;
CSSM_DB_UNIQUE_RECORD_PTR record;
cert->Data = NULL;
cert->Length = 0;
predicate.DbOperator = CSSM_DB_EQUAL;
predicate.Attribute.Info.AttributeNameFormat =
CSSM_DB_ATTRIBUTE_NAME_AS_NUMBER; predicate.Attribute.Info.Attr.AttributeNumber = kSubjectKCItemAttr;
predicate.Attribute.Value = *subjectName;
query.RecordType = CSSM_DL_DB_RECORD_CERT;
query.NumSelectionPredicates = 1;
query.Conjunctive = CSSM_DB_NONE;
query.SelectionPredicate = &predicate;
record = CSSM_DL_DataGetFirst(dlDb,
&query,
resultHand,
&EndOfDataStore,
NULL, cert);
return record;
}
CSSM_DATA_PTR tpFindIssuer(
CSSM_TP_HANDLE tpHand,
CSSM_CL_HANDLE clHand,
CSSM_CSP_HANDLE cspHand,
const CSSM_DATA_PTR subjectCert,
const CSSM_DATA_PTR issuerName, const CSSM_DB_LIST_PTR dbList,
CSSM_RETURN *issuerExpired) {
uint32 dbDex;
CSSM_HANDLE resultHand;
CSSM_DATA_PTR cert; CSSM_DL_DB_HANDLE dlDb;
CSSM_DB_UNIQUE_RECORD_PTR record;
*subjectExpired = CSSM_OK;
if(dbList == NULL) {
return NULL;
}
cert = (CSSM_DATA_PTR)tpMalloc(tpHand, sizeof(CSSM_DATA));
cert->Data = NULL;
cert->Length = 0;
for(dbDex=0; dbDex<dbList->NumHandles; dbDex++) {
dlDb = dbList->DLDBHandle[dbDex];
record = tpCertLookup(tpHand,
dlDb,
issuerName,
&resultHand,
cert);
if(record != NULL) {
if(!tp_VerifyCert(tpHand,
clHand,
cspHand,
subjectCert,
cert,
issuerExpired)) {
if((*issuerExpired) != CSSM_OK) {
CSSM_DL_AbortQuery(dlDb, resultHand);
goto abort;
}
for(;;) {
CSSM_BOOL eod;
tpFreeCssmData(tpHand, cert, CSSM_FALSE);
record = CSSM_DL_DataGetNext(dlDb,
resultHand,
&eod,
NULL, cert);
if(record == NULL) {
break;
}
if(tp_VerifyCert(tpHand,
clHand,
cspHand,
subjectCert,
cert,
issuerExpired)) {
break;
}
else if((*issuerExpired) != CSSM_OK) {
CSSM_DL_AbortQuery(dlDb, resultHand);
goto abort;
}
}
}
if(record != NULL) {
CSSM_DL_AbortQuery(dlDb, resultHand);
return cert;
}
}
CSSM_DL_AbortQuery(dlDb, resultHand);
}
abort:
tpFreeCssmData(tpHand, cert, CSSM_TRUE);
return NULL;
}
#endif
CSSM_ALGORITHMS tpOidToAldId(
const CSSM_OID *oid,
CSSM_ALGORITHMS *keyAlg) {
*keyAlg = CSSM_ALGID_RSA; if(tpCompareOids(oid, &CSSMOID_MD2WithRSA)) {
return CSSM_ALGID_MD2WithRSA;
}
else if(tpCompareOids(oid, &CSSMOID_MD5WithRSA)) {
return CSSM_ALGID_MD5WithRSA;
}
else if(tpCompareOids(oid, &CSSMOID_SHA1WithRSA)) {
return CSSM_ALGID_SHA1WithRSA;
}
else if(tpCompareOids(oid, &CSSMOID_SHA1WithDSA)) {
*keyAlg = CSSM_ALGID_DSA;
return CSSM_ALGID_SHA1WithDSA;
}
else if(tpCompareOids(oid, &CSSMOID_APPLE_FEE_MD5)) {
*keyAlg = CSSM_ALGID_FEE;
return CSSM_ALGID_FEE_MD5;
}
else if(tpCompareOids(oid, &CSSMOID_APPLE_FEE_SHA1)) {
*keyAlg = CSSM_ALGID_FEE;
return CSSM_ALGID_FEE_SHA1;
}
else if(tpCompareOids(oid, &CSSMOID_APPLE_ECDSA)) {
*keyAlg = CSSM_ALGID_FEE;
return CSSM_ALGID_SHA1WithECDSA;
}
else {
*keyAlg = CSSM_ALGID_NONE;
return CSSM_ALGID_NONE;
}
}