static int checkOneField( CSSM_CL_HANDLE clHand, CSSM_HANDLE cacheHand1, CSSM_HANDLE cacheHand2, const CSSM_OID *fieldOid) { CSSM_DATA_PTR fieldData1 = NULL; CSSM_DATA_PTR fieldData2 = NULL; CSSM_RETURN crtn; CSSM_HANDLE resultHand1 = 0; CSSM_HANDLE resultHand2 = 0; uint32 numFields = 0; int rtn; crtn = CSSM_CL_CertGetFirstCachedFieldValue( clHand, cacheHand1, fieldOid, &resultHand1, &numFields, &fieldData1); if(crtn) { return crtn; } if(numFields != 1) { printf("Fiedl not present; try another cert\n"); return 1; } crtn = CSSM_CL_CertGetFirstCachedFieldValue( clHand, cacheHand2, fieldOid, &resultHand2, &numFields, &fieldData2); if(crtn) { return crtn; } rtn = compareFields(fieldOid, fieldData1, fieldData2); CSSM_CL_CertAbortQuery(clHand, resultHand1); CSSM_CL_CertAbortQuery(clHand, resultHand2); CSSM_CL_FreeFieldValue(clHand, fieldOid, fieldData1); CSSM_CL_FreeFieldValue(clHand, fieldOid, fieldData2); return rtn; }
static void printOneCertName( CSSM_CL_HANDLE clHand, CSSM_HANDLE cacheHand, const char *title, const CSSM_OID *oid) { CSSM_HANDLE resultHand = 0; CSSM_DATA_PTR field = NULL; uint32 numFields; CSSM_RETURN crtn; crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand, oid, &resultHand, &numFields, &field); if(crtn) { printf("***Error parsing cert\n"); cssmPerror("CSSM_CL_CertGetFirstCachedFieldValue", crtn); return; } printName(title, field->Data, field->Length); CSSM_CL_FreeFieldValue(clHand, oid, field); }
int main(int argc, char **argv) { CSSM_CL_HANDLE clHand; // CL handle CSSM_DATA rawCert = {0, NULL}; uint32 numFields; CSSM_HANDLE ResultsHandle = 0; char baseName[255]; char blobName[255]; char *cp; int rtn; int nameLen; CSSM_RETURN crtn; CSSM_DATA_PTR value; CSSM_KEY_PTR key; uint32 keySize; NSS_Certificate signedCert; SecAsn1CoderRef coder; if(argc != 2) { printf("usage: %s certFile\n", argv[0]); exit(1); } /* connect to CL */ clHand = clStartup(); if(clHand == 0) { printf("clStartup failure; aborting\n"); return 0; } /* subsequent errors to abort: */ /* read a in raw cert */ unsigned len; rtn = readFile(argv[1], &rawCert.Data, &len); if(rtn) { printf("Error %s reading file %s\n", strerror(rtn), argv[1]); exit(1); } rawCert.Length = len; /* C string of file name, terminating at '.' or space */ nameLen = strlen(argv[1]); memmove(baseName, argv[1], nameLen); baseName[nameLen] = '\0'; cp = strchr(baseName, '.'); if(cp) { *cp = '\0'; } cp = strchr(baseName, ' '); if(cp) { *cp = '\0'; } /* print filename and parsed subject name as comment */ crtn = CSSM_CL_CertGetFirstFieldValue( clHand, &rawCert, &CSSMOID_X509V1SubjectNameCStruct, &ResultsHandle, &numFields, &value); if(crtn) { printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_X509V1SubjectNameCStruct)", crtn); goto abort; } CSSM_CL_CertAbortQuery(clHand, ResultsHandle); if(value == NULL) { printf("Error extracting subject name\n"); goto abort; } printHeader(argv[1], value); CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectNameCStruct, value); /* print normalized & encoded subject name as C data */ crtn = CSSM_CL_CertGetFirstFieldValue( clHand, &rawCert, &SUBJECT_NAME_OID, &ResultsHandle, &numFields, &value); if(crtn) { printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_X509V1SubjectName)", crtn); goto abort; } CSSM_CL_CertAbortQuery(clHand, ResultsHandle); if(value == NULL) { printf("Error extracting subject name\n"); goto abort; } sprintf(blobName, "%s_subject", baseName); dumpDataBlob(blobName, value); #if WRITE_NAME_FILE writeFile(blobName, value->Data, (unsigned)value->Length); #endif CSSM_CL_FreeFieldValue(clHand, &SUBJECT_NAME_OID, value); /* print key blob as data */ crtn = CSSM_CL_CertGetFirstFieldValue( clHand, &rawCert, &CSSMOID_CSSMKeyStruct, &ResultsHandle, &numFields, &value); if(crtn) { printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_CSSMKeyStruct)", crtn); goto abort; } CSSM_CL_CertAbortQuery(clHand, ResultsHandle ); if(value == NULL) { printf("Error extracting public key\n"); goto abort; } if(value->Length != sizeof(CSSM_KEY)) { printf("CSSMOID_CSSMKeyStruct length error\n"); goto abort; } key = (CSSM_KEY_PTR)value->Data; sprintf(blobName, "%s_pubKey", baseName); dumpDataBlob(blobName, &key->KeyData); keySize = key->KeyHeader.LogicalKeySizeInBits; CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CSSMKeyStruct, value); /* unnormalized DER-encoded issuer */ SecAsn1CoderCreate(&coder); memset(&signedCert, 0, sizeof(signedCert)); if(SecAsn1DecodeData(coder, &rawCert, kSecAsn1SignedCertTemplate, &signedCert)) { printf("***Error NSS-decoding certificate\n"); } else { sprintf(blobName, "%s_derIssuer", baseName); dumpDataBlob(blobName, &signedCert.tbs.derIssuer); } /* now the the struct containing all three */ printf("\n { &%s_subject, &%s_pubKey, %u },\n", baseName, baseName, (unsigned)keySize); abort: free(rawCert.Data); if(clHand != 0) { CSSM_ModuleDetach(clHand); } SecAsn1CoderRelease(coder); return 0; }
/* Free the field via CL */ CP_FetchedField::~CP_FetchedField() { CSSM_CL_FreeFieldValue(mClHand, &mFieldOid, mFieldData); }
CSSM_RETURN cuAddCrlToDb( CSSM_DL_DB_HANDLE dlDbHand, CSSM_CL_HANDLE clHand, const CSSM_DATA *crl, const CSSM_DATA *URI) // optional { CSSM_DB_ATTRIBUTE_DATA attrs[MAX_CRL_ATTRS]; CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs; CSSM_DB_ATTRIBUTE_DATA_PTR attr = &attrs[0]; CSSM_DATA crlTypeData; CSSM_DATA crlEncData; CSSM_DATA printNameData; CSSM_RETURN crtn; CSSM_DB_UNIQUE_RECORD_PTR recordPtr; CSSM_DATA_PTR issuer = NULL; // mallocd by CL CSSM_DATA_PTR crlValue = NULL; // ditto uint32 numFields; CSSM_HANDLE result; CSSM_CRL_ENCODING crlEnc = CSSM_CRL_ENCODING_DER; const CSSM_X509_SIGNED_CRL *signedCrl; const CSSM_X509_TBS_CERTLIST *tbsCrl; CSSM_CRL_TYPE crlType; CSSM_DATA thisUpdateData = {0, NULL}; CSSM_DATA nextUpdateData = {0, NULL}; char *thisUpdate = NULL; char *nextUpdate = NULL; unsigned timeLen; uint32 crlNumber; uint32 deltaCrlNumber; CSSM_DATA crlNumberData; CSSM_DATA deltaCrlNumberData; bool crlNumberPresent = false; bool deltaCrlPresent = false; CSSM_DATA attrUri; /* get normalized issuer name as Issuer attr */ crtn = CSSM_CL_CrlGetFirstFieldValue(clHand, crl, &CSSMOID_X509V1IssuerName, &result, &numFields, &issuer); if(crtn) { cuPrintError("CSSM_CL_CrlGetFirstFieldValue(Issuer)", crtn); return crtn; } CSSM_CL_CrlAbortQuery(clHand, result); /* get parsed CRL from the CL */ crtn = CSSM_CL_CrlGetFirstFieldValue(clHand, crl, &CSSMOID_X509V2CRLSignedCrlCStruct, &result, &numFields, &crlValue); if(crtn) { cuPrintError("CSSM_CL_CrlGetFirstFieldValue(Issuer)", crtn); goto errOut; } CSSM_CL_CrlAbortQuery(clHand, result); if(crlValue == NULL) { dprintf("***CSSM_CL_CrlGetFirstFieldValue: value error (1)\n"); crtn = CSSMERR_CL_INVALID_CRL_POINTER; goto errOut; } if((crlValue->Data == NULL) || (crlValue->Length != sizeof(CSSM_X509_SIGNED_CRL))) { dprintf("***CSSM_CL_CrlGetFirstFieldValue: value error (2)\n"); crtn = CSSMERR_CL_INVALID_CRL_POINTER; goto errOut; } signedCrl = (const CSSM_X509_SIGNED_CRL *)crlValue->Data; tbsCrl = &signedCrl->tbsCertList; /* CrlType inferred from version */ if(tbsCrl->version.Length == 0) { /* should never happen... */ crlType = CSSM_CRL_TYPE_X_509v1; } else { uint8 vers = tbsCrl->version.Data[tbsCrl->version.Length - 1]; switch(vers) { case 0: crlType = CSSM_CRL_TYPE_X_509v1; break; case 1: crlType = CSSM_CRL_TYPE_X_509v2; break; default: dprintf("***Unknown version in CRL (%u)\n", vers); crlType = CSSM_CRL_TYPE_X_509v1; break; } } crlTypeData.Data = (uint8 *)&crlType; crlTypeData.Length = sizeof(CSSM_CRL_TYPE); /* encoding more-or-less assumed here */ crlEncData.Data = (uint8 *)&crlEnc; crlEncData.Length = sizeof(CSSM_CRL_ENCODING); /* printName inferred from issuer */ cuInferCrlLabel(&tbsCrl->issuer, &printNameData); /* cook up CSSM_TIMESTRING versions of this/next update */ thisUpdate = cuX509TimeToCssmTimestring(&tbsCrl->thisUpdate, &timeLen); if(thisUpdate == NULL) { dprintf("***Badly formatted thisUpdate\n"); } else { thisUpdateData.Data = (uint8 *)thisUpdate; thisUpdateData.Length = timeLen; } if(tbsCrl->nextUpdate.time.Data != NULL) { nextUpdate = cuX509TimeToCssmTimestring(&tbsCrl->nextUpdate, &timeLen); if(nextUpdate == NULL) { dprintf("***Badly formatted nextUpdate\n"); } else { nextUpdateData.Data = (uint8 *)nextUpdate; nextUpdateData.Length = timeLen; } } else { /* * NextUpdate not present; fake it by using "virtual end of time" */ CSSM_X509_TIME tempTime = { 0, // timeType, not used { strlen(CSSM_APPLE_CRL_END_OF_TIME), (uint8 *)CSSM_APPLE_CRL_END_OF_TIME} }; nextUpdate = cuX509TimeToCssmTimestring(&tempTime, &timeLen); nextUpdateData.Data = (uint8 *)nextUpdate; nextUpdateData.Length = CSSM_TIME_STRLEN; } /* optional CrlNumber and DeltaCrlNumber */ if(cuSearchNumericExtension(&tbsCrl->extensions, &CSSMOID_CrlNumber, &crlNumber)) { crlNumberData.Data = (uint8 *)&crlNumber; crlNumberData.Length = sizeof(uint32); crlNumberPresent = true; } if(cuSearchNumericExtension(&tbsCrl->extensions, &CSSMOID_DeltaCrlIndicator, &deltaCrlNumber)) { deltaCrlNumberData.Data = (uint8 *)&deltaCrlNumber; deltaCrlNumberData.Length = sizeof(uint32); deltaCrlPresent = true; } attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "CrlType"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; attr->NumberOfValues = 1; attr->Value = &crlTypeData; attr++; attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "CrlEncoding"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; attr->NumberOfValues = 1; attr->Value = &crlEncData; attr++; attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "PrintName"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; attr->NumberOfValues = 1; attr->Value = &printNameData; attr++; attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "Issuer"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; attr->NumberOfValues = 1; attr->Value = issuer; attr++; attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "ThisUpdate"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; attr->NumberOfValues = 1; attr->Value = &thisUpdateData; attr++; attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "NextUpdate"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; attr->NumberOfValues = 1; attr->Value = &nextUpdateData; attr++; /* now the optional attributes */ if(crlNumberPresent) { attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "CrlNumber"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; attr->NumberOfValues = 1; attr->Value = &crlNumberData; attr++; } if(deltaCrlPresent) { attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "DeltaCrlNumber"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_UINT32; attr->NumberOfValues = 1; attr->Value = &deltaCrlNumberData; attr++; } if(URI) { /* ensure URI string does not contain NULL */ attrUri = *URI; if((attrUri.Length != 0) && (attrUri.Data[attrUri.Length - 1] == 0)) { attrUri.Length--; } attr->Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr->Info.Label.AttributeName = (char*) "URI"; attr->Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; attr->NumberOfValues = 1; attr->Value = &attrUri; attr++; } recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_X509_CRL; recordAttrs.SemanticInformation = 0; recordAttrs.NumberOfAttributes = (uint32)(attr - attrs); recordAttrs.AttributeData = attrs; crtn = CSSM_DL_DataInsert(dlDbHand, CSSM_DL_DB_RECORD_X509_CRL, &recordAttrs, crl, &recordPtr); if(crtn == CSSMERR_DL_INVALID_RECORDTYPE) { /* gross hack of inserting this "new" schema that Keychain didn't specify */ crtn = cuAddCrlSchema(dlDbHand); if(crtn == CSSM_OK) { /* Retry with a fully capable DLDB */ crtn = CSSM_DL_DataInsert(dlDbHand, CSSM_DL_DB_RECORD_X509_CRL, &recordAttrs, crl, &recordPtr); } } if(crtn == CSSM_OK) { CSSM_DL_FreeUniqueRecord(dlDbHand, recordPtr); } errOut: /* free all the stuff we allocated to get here */ if(issuer) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1IssuerName, issuer); } if(crlValue) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V2CRLSignedCrlCStruct, crlValue); } if(thisUpdate) { free(thisUpdate); } if(nextUpdate) { free(nextUpdate); } return crtn; }
// Extract the issuer and serial number from a certificate SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef cert) { OSStatus status; SecCmsIssuerAndSN *certIssuerAndSN; CSSM_CL_HANDLE clHandle; CSSM_DATA_PTR serialNumber = 0; CSSM_DATA_PTR issuer = 0; CSSM_DATA certData = {}; CSSM_HANDLE resultsHandle = 0; uint32 numberOfFields = 0; CSSM_RETURN result; void *mark; mark = PORT_ArenaMark(pl); status = SecCertificateGetCLHandle(cert, &clHandle); if (status) goto loser; status = SecCertificateGetData(cert, &certData); if (status) goto loser; /* Get the issuer from the cert. */ result = CSSM_CL_CertGetFirstFieldValue(clHandle, &certData, &OID_X509V1IssuerNameStd, &resultsHandle, &numberOfFields, &issuer); if (result || numberOfFields < 1) goto loser; result = CSSM_CL_CertAbortQuery(clHandle, resultsHandle); if (result) goto loser; /* Get the serialNumber from the cert. */ result = CSSM_CL_CertGetFirstFieldValue(clHandle, &certData, &CSSMOID_X509V1SerialNumber, &resultsHandle, &numberOfFields, &serialNumber); if (result || numberOfFields < 1) goto loser; result = CSSM_CL_CertAbortQuery(clHandle, resultsHandle); if (result) goto loser; /* Allocate the SecCmsIssuerAndSN struct. */ certIssuerAndSN = (SecCmsIssuerAndSN *)PORT_ArenaZAlloc (pl, sizeof(SecCmsIssuerAndSN)); if (certIssuerAndSN == NULL) goto loser; /* Copy the issuer. */ certIssuerAndSN->derIssuer.Data = (uint8 *) PORT_ArenaAlloc(pl, issuer->Length); if (!certIssuerAndSN->derIssuer.Data) goto loser; PORT_Memcpy(certIssuerAndSN->derIssuer.Data, issuer->Data, issuer->Length); certIssuerAndSN->derIssuer.Length = issuer->Length; /* Copy the serialNumber. */ certIssuerAndSN->serialNumber.Data = (uint8 *) PORT_ArenaAlloc(pl, serialNumber->Length); if (!certIssuerAndSN->serialNumber.Data) goto loser; PORT_Memcpy(certIssuerAndSN->serialNumber.Data, serialNumber->Data, serialNumber->Length); certIssuerAndSN->serialNumber.Length = serialNumber->Length; PORT_ArenaUnmark(pl, mark); CSSM_CL_FreeFieldValue(clHandle, &CSSMOID_X509V1SerialNumber, serialNumber); CSSM_CL_FreeFieldValue(clHandle, &OID_X509V1IssuerNameStd, issuer); return certIssuerAndSN; loser: PORT_ArenaRelease(pl, mark); if (serialNumber) CSSM_CL_FreeFieldValue(clHandle, &CSSMOID_X509V1SerialNumber, serialNumber); if (issuer) CSSM_CL_FreeFieldValue(clHandle, &OID_X509V1IssuerNameStd, issuer); PORT_SetError(SEC_INTERNAL_ONLY); return NULL; }
/* * Given a DER encoded certificate, obtain the associated IssuerAndSerialNumber. */ krb5_error_code krb5int_pkinit_get_issuer_serial( const krb5_data *cert, krb5_data *issuer_and_serial) { CSSM_HANDLE cacheHand = 0; CSSM_RETURN crtn = CSSM_OK; CSSM_DATA certData = { cert->length, (uint8 *)cert->data }; CSSM_HANDLE resultHand = 0; CSSM_DATA_PTR derIssuer = NULL; CSSM_DATA_PTR serial; krb5_data krb_serial; krb5_data krb_issuer; uint32 numFields; krb5_error_code ourRtn = 0; CSSM_CL_HANDLE clHand = pkiClStartup(); if(clHand == 0) { return CSSMERR_CSSM_ADDIN_LOAD_FAILED; } /* subsequent errors to errOut: */ crtn = CSSM_CL_CertCache(clHand, &certData, &cacheHand); if(crtn) { pkiCssmErr("CSSM_CL_CertCache", crtn); ourRtn = ASN1_PARSE_ERROR; goto errOut; } /* obtain the two fields; issuer is DER encoded */ crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand, &CSSMOID_X509V1IssuerNameStd, &resultHand, &numFields, &derIssuer); if(crtn) { pkiCssmErr("CSSM_CL_CertGetFirstCachedFieldValue(issuer)", crtn); ourRtn = ASN1_PARSE_ERROR; goto errOut; } crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand, &CSSMOID_X509V1SerialNumber, &resultHand, &numFields, &serial); if(crtn) { pkiCssmErr("CSSM_CL_CertGetFirstCachedFieldValue(serial)", crtn); ourRtn = ASN1_PARSE_ERROR; goto errOut; } PKI_CSSM_TO_KRB_DATA(derIssuer, &krb_issuer); PKI_CSSM_TO_KRB_DATA(serial, &krb_serial); ourRtn = krb5int_pkinit_issuer_serial_encode(&krb_issuer, &krb_serial, issuer_and_serial); errOut: if(derIssuer) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1IssuerNameStd, derIssuer); } if(serial) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SerialNumber, serial); } if(cacheHand) { CSSM_CL_CertAbortCache(clHand, cacheHand); } if(clHand) { pkiClDetachUnload(clHand); } return ourRtn; }
void tp_CertFreeAlgId( CSSM_CL_HANDLE clHand, CSSM_DATA_PTR value) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SignatureAlgorithm, value); }
void tp_CertFreePublicKey( CSSM_CL_HANDLE clHand, CSSM_DATA_PTR value) { CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectPublicKeyCStruct, value); }