static void showPeerCerts( CFArrayRef peerCerts, CSSM_BOOL verbose) { CFIndex numCerts; SecCertificateRef certRef; OSStatus ortn; CSSM_DATA certData; CFIndex i; if(peerCerts == NULL) { return; } numCerts = CFArrayGetCount(peerCerts); for(i=0; i<numCerts; i++) { certRef = (SecCertificateRef)CFArrayGetValueAtIndex(peerCerts, i); ortn = SecCertificateGetData(certRef, &certData); if(ortn) { printf("***SecCertificateGetData returned %d\n", ortn); continue; } printf("\n================== Peer Cert %d ===================\n\n", i); printCert(certData.Data, certData.Length, verbose); printf("\n=============== End of Peer Cert %d ===============\n", i); } }
int p12ParseTop( CSSM_DATA &rawBlob, CSSM_CSP_HANDLE cspHand, CFStringRef pwd, bool verbose) { SecNssCoder coder; OidParser parser; P12Parsed parsed(coder); P12ParseInfo pinfo(coder, cspHand, parser, pwd, NULL, // no separate pwd parsed); printf("PKCS12 PFX:\n"); int rtn = p12Parse(rawBlob, pinfo, 3); /* find anything? */ if(verbose) { P12KnownBlobs &certs = pinfo.mParsed.mCerts; if(certs.mNumBlobs) { printf("\n\n"); for(unsigned dex=0; dex<certs.mNumBlobs; dex++) { printf("Cert %u:\n", dex); printCert(certs.mBlobs[dex].Data, certs.mBlobs[dex].Length, CSSM_FALSE); printf("\n"); } } P12KnownBlobs &crls = pinfo.mParsed.mCrls; if(crls.mNumBlobs) { printf("\n\n"); for(unsigned dex=0; dex<crls.mNumBlobs; dex++) { printf("CRL %u:\n", dex); printCrl(crls.mBlobs[dex].Data, crls.mBlobs[dex].Length, CSSM_FALSE); } } } return rtn; }
/* * Search DB for all records of type CRL or cert, calling appropriate * parse/print routine for each record. */ CSSM_RETURN cuDumpCrlsCerts( CSSM_DL_DB_HANDLE dlDbHand, CSSM_CL_HANDLE clHand, CSSM_BOOL isCert, unsigned &numItems, // returned CSSM_BOOL verbose) { CSSM_QUERY query; CSSM_DB_UNIQUE_RECORD_PTR record = NULL; CSSM_HANDLE resultHand; CSSM_RETURN crtn; CSSM_DATA certCrl; const char *itemStr; numItems = 0; itemStr = isCert ? "Certificate" : "CRL"; /* just search by recordType, no predicates, no attributes */ if(isCert) { query.RecordType = CSSM_DL_DB_RECORD_X509_CERTIFICATE; } else { query.RecordType = CSSM_DL_DB_RECORD_X509_CRL; } query.Conjunctive = CSSM_DB_NONE; query.NumSelectionPredicates = 0; query.SelectionPredicate = NULL; query.QueryLimits.TimeLimit = 0; // FIXME - meaningful? query.QueryLimits.SizeLimit = 1; // FIXME - meaningful? query.QueryFlags = 0; // CSSM_QUERY_RETURN_DATA...FIXME - used? certCrl.Data = NULL; certCrl.Length = 0; crtn = CSSM_DL_DataGetFirst(dlDbHand, &query, &resultHand, NULL, // no attrs &certCrl, &record); switch(crtn) { case CSSM_OK: break; // proceed case CSSMERR_DL_ENDOFDATA: /* no data, otherwise OK */ return CSSM_OK; case CSSMERR_DL_INVALID_RECORDTYPE: /* invalid record type just means "this hasn't been set up * for certs yet". */ return crtn; default: cuPrintError("DataGetFirst", crtn); return crtn; } /* got one; print it */ dprintf("%s %u:\n", itemStr, numItems); if(isCert) { printCert(certCrl.Data, (unsigned)certCrl.Length, verbose); } else { printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose); } CSSM_DL_FreeUniqueRecord(dlDbHand, record); APP_FREE(certCrl.Data); certCrl.Data = NULL; certCrl.Length = 0; numItems++; /* get the rest */ for(;;) { crtn = CSSM_DL_DataGetNext(dlDbHand, resultHand, NULL, &certCrl, &record); switch(crtn) { case CSSM_OK: dprintf("%s %u:\n", itemStr, numItems); if(isCert) { printCert(certCrl.Data, (unsigned)certCrl.Length, verbose); } else { printCrl(certCrl.Data, (unsigned)certCrl.Length, verbose); } CSSM_DL_FreeUniqueRecord(dlDbHand, record); APP_FREE(certCrl.Data); certCrl.Data = NULL; certCrl.Length = 0; numItems++; break; // and go again case CSSMERR_DL_ENDOFDATA: /* normal termination */ return CSSM_OK; default: cuPrintError("DataGetNext", crtn); return crtn; } } /* NOT REACHED */ }
static int parseOcspResp( CSSM_CL_HANDLE clHand, unsigned char *inFile, unsigned inFileLen, bool verbose) { SecAsn1OCSPResponse topResp; SecAsn1CoderRef coder; OSStatus ortn; int indent = 0; const char *str; SecAsn1OCSPBasicResponse basicResp; unsigned numCerts = 0; SecAsn1CoderCreate(&coder); memset(&topResp, 0, sizeof(topResp)); ortn = SecAsn1Decode(coder, inFile, inFileLen, kSecAsn1OCSPResponseTemplate, &topResp); if(ortn) { printf("***Error decoding SecAsn1OCSPResponse\n"); goto errOut; } printf("OCSPResponse:\n"); indent += 2; doIndent(indent); printf("responseStatus: "); if(topResp.responseStatus.Length == 0) { printf("**MALFORMED**\n"); } else { switch(topResp.responseStatus.Data[0]) { case RS_Success: str = "RS_Success"; break; case RS_MalformedRequest: str = "RS_MalformedRequest"; break; case RS_InternalError: str = "RS_InternalError"; break; case RS_TryLater: str = "RS_TryLater"; break; case RS_Unused: str = "RS_Unused"; break; case RS_SigRequired: str = "RS_SigRequired"; break; case RS_Unauthorized: str = "RS_Unauthorized"; break; default: str = "MALFORMED (unknown enum)\n"; break; } printf("%s (%u(d))\n", str, topResp.responseStatus.Data[0]); } doIndent(indent); printf("ResponseBytes: "); if(topResp.responseBytes == NULL) { printf("empty\n"); goto errOut; } printf("\n"); indent += 2; doIndent(indent); printf("responseType: "); if(appCompareCssmData(&topResp.responseBytes->responseType, &CSSMOID_PKIX_OCSP_BASIC)) { str = "ocsp-basic"; } else { str = "Unknown type\n"; } printf("%s\n", str); /* decode the BasicOCSPResponse */ memset(&basicResp, 0, sizeof(basicResp)); ortn = SecAsn1DecodeData(coder, &topResp.responseBytes->response, kSecAsn1OCSPBasicResponseTemplate, &basicResp); if(ortn) { printf("***Error decoding BasicOCSPResponse\n"); goto errOut; } doIndent(indent); printf("BasicOCSPResponse:\n"); indent += 2; doIndent(indent); printf("ResponseData:\n"); parseResponseData(coder, indent + 2, basicResp.tbsResponseData); doIndent(indent); printf("sig: "); printDataAsHex(&basicResp.sig, 8); numCerts = ocspdArraySize((const void **)basicResp.certs); doIndent(indent); printf("Num Certs: %u\n", numCerts); if(verbose) { for(unsigned dex=0; dex<numCerts; dex++) { printf("+++++++++++++++++++++++++ Cert %u +++++++++++++++++++++++++\n", dex); printCert(basicResp.certs[dex]->Data, basicResp.certs[dex]->Length, CSSM_FALSE); printf("+++++++++++++++++++++++ End Cert %u +++++++++++++++++++++++\n", dex); } } indent -= 2; // end of BasicOCSPResponse indent -= 2; // end of ResponseBytes indent -= 2; // end of OCSPResponse errOut: SecAsn1CoderRelease(coder); return ortn; }
int main(int argc, char **argv) { if(argc < 2) { usage(argv); } bool print_cert = false; bool allCerts = false; const char *emailAddress = NULL; bool addToKC = false; extern int optind; optind = 1; if(argv[1][0] != '-') { /* normal case, email address specified */ emailAddress = argv[1]; optind++; } extern char *optarg; int arg; while ((arg = getopt(argc, argv, "aphA")) != -1) { switch (arg) { case 'p': print_cert = true; break; case 'a': allCerts = true; break; case 'A': addToKC = true; break; case 'h': default: usage(argv); } } if(optind != argc) { usage(argv); } if(!allCerts && (emailAddress == NULL)) { printf("***You must specify either an email address or the -a option.\n"); exit(1); } OSStatus ortn; SecKeychainSearchRef srch; SecKeychainAttributeList attrList; SecKeychainAttribute attr; unsigned numCerts = 0; if(emailAddress) { attr.tag = kSecAlias; // i.e., email address attr.length = strlen(emailAddress); attr.data = (void *)emailAddress; attrList.count = 1; attrList.attr = &attr; } else { attrList.count = 0; attrList.attr = NULL; } ortn = SecKeychainSearchCreateFromAttributes(NULL, // default search list kSecCertificateItemClass, &attrList, &srch); if(ortn) { cssmPerror("SecKeychainSearchCreateFromAttributes", ortn); exit(1); } do { SecCertificateRef certRef = NULL; CSSM_DATA certData; ortn = SecKeychainSearchCopyNext(srch, (SecKeychainItemRef *)&certRef); if(ortn) { break; } ortn = SecCertificateGetData(certRef, &certData); if(ortn) { cssmPerror("SecCertificateGetData", ortn); continue; } printf("=== Cert %u ===\n", numCerts); printCertName(certData.Data, certData.Length, NameBoth); if(print_cert) { printCert(certData.Data, certData.Length, CSSM_FALSE); } if(addToKC) { /* * Can't call SecCertificateAddToKeychain directly since this * cert already has a keychain. */ SecCertificateRef newCertRef = NULL; ortn = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &newCertRef); if(ortn) { cssmPerror("SecCertificateCreateFromData", ortn); printf("***Error adding this cert to default keychain.\n"); } else { ortn = SecCertificateAddToKeychain(newCertRef, NULL); if(ortn) { cssmPerror("SecCertificateAddToKeychain", ortn); printf("***Error adding this cert to default keychain.\n"); } else { printf("...cert added to default keychain.\n"); } CFRelease(newCertRef); } } CFRelease(certRef); numCerts++; } while(ortn == noErr); printf("...%u certs found matching email address \'%s\'\n", numCerts, emailAddress ? emailAddress : "<any>"); CFRelease(srch); return 0; }