X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/clxutils/ocspTool/ocspTool.cpp diff --git a/SecurityTests/clxutils/ocspTool/ocspTool.cpp b/SecurityTests/clxutils/ocspTool/ocspTool.cpp deleted file mode 100644 index 153cdaa4..00000000 --- a/SecurityTests/clxutils/ocspTool/ocspTool.cpp +++ /dev/null @@ -1,1254 +0,0 @@ -/* - * ocspTool - simple OCSP request/response generator and parser - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ocspUtils.h" -#include "ocspRequest.h" -#include "ocspNetwork.h" -#include "findOcspUrl.h" - -static void usage(char **argv) -{ - printf("Usage: %s cmd [option...]\n", argv[0]); - printf("cmds:\n"); - printf(" g generate request\n"); - printf(" G parse request\n"); - printf(" r generate reply\n"); - printf(" R parse reply\n"); - printf(" p generate OCSP request, post, get reply (use -p and/or -o)\n"); - printf("Options\n"); - printf(" -c cert_file -- for generating request\n"); - printf(" -C issuer_cert_file -- for generating request\n"); - printf(" -i in_file -- for parsing\n"); - printf(" -o out_file -- for generating\n"); - printf(" -s status -- cert status: g(ood)|r(evoked)|u(nknown)\n"); - printf(" -r crlReason -- integer 0..8\n"); - printf(" -k keychain -- keychain containing signing cert\n"); - printf(" -p -- parse reply from post op\n"); - printf(" -u responderURI -- OCSP responder here, not from cert's AIA extension\n"); - printf(" -v -- verbose; e.g., print certs\n"); - exit(1); -} - -void doIndent(int indent) -{ - for(int dex=0; dexData; - for(i=0; iLength; i++) { - printf("%c", *cp++); - } - printf("\n"); -} - -static void printDataAsHex( - const CSSM_DATA *d, - unsigned maxToPrint = 0) // optional, 0 means print it all -{ - unsigned i; - bool more = false; - uint32 len = d->Length; - uint8 *cp = d->Data; - - if((maxToPrint != 0) && (len > maxToPrint)) { - len = maxToPrint; - more = true; - } - for(i=0; iatvs); - for(unsigned atvDex=0; atvDexatvs[atvDex]; - char buf[OID_PARSER_STRING_SIZE]; - parser.oidParse(atv->type.Data, atv->type.Length, buf); - doIndent(indent); - printf("%s : ", buf); - printTaggedItem(atv->value); - } - } -} - -static uint8 nullParam[2] = {5, 0}; - -/* - * Given the following, create a ResponseData (to be signed by caller). - * - * cert status (CS_{Good,Revoked,Unknown}) - * cert being verified - * issuer cert - * this update time - * next update time (optional) - * nonce (optional) - */ -static int genTbsResp( - SecAsn1CoderRef coder, // result in this coder's address space - CSSM_CL_HANDLE clHand, - SecAsn1OCSPCertStatusTag status, - CE_CrlReason reason, // for CS_Revoked - const CSSM_DATA &subjectCert, - const CSSM_DATA &issuerCert, - unsigned thisUpdate, // required, seconds from now - unsigned nextUpdate, // optional, seconds from now, 0 ==> skip - const CSSM_DATA *nonce, // optional - CSSM_DATA &encodedTbs) // allocated in coder space and RETURNED -{ - char *nextUpdStr = NULL; - CSSM_DATA nextUpdateData; - char *thisUpdStr = NULL; - CSSM_DATA *thisUpdateData; - SecAsn1OCSPResponseData responseData; - OCSPNonce *nonceExt = NULL; - char *producedAt = NULL; - SecAsn1OCSPSingleResponse singleResp; - SecAsn1OCSPSingleResponse *respArray[2] = {&singleResp, NULL}; - SecAsn1OCSPResponderID responderID; - NSS_CertExtension *extenArray[2] = {NULL, NULL}; - - /* SingleResponse */ - memset(&singleResp, 0, sizeof(singleResp)); - - /* SingleResponse.CertID */ - SecAsn1OCSPCertID &certId = singleResp.certID; - CertParser parser(clHand); - CertParser issuerParser(clHand); - CSSM_RETURN crtn = parser.initWithData(subjectCert); - if(crtn) { - cssmPerror("CertParser.initWithData for subject cert", crtn); - return -1; - } - crtn = issuerParser.initWithData(issuerCert); - if(crtn) { - cssmPerror("CertParser.initWithData for issuer", crtn); - return -1; - } - - /* algId refers to the hash we'll perform in issuer name and key */ - certId.algId.algorithm = CSSMOID_SHA1; - certId.algId.parameters.Data = nullParam; - certId.algId.parameters.Length = sizeof(nullParam); - - /* SHA1(issuerName) */ - CSSM_DATA issuerName = {0, NULL}; - issuerName.Data = (uint8 *)parser.fieldForOid(CSSMOID_X509V1IssuerNameStd, - issuerName.Length); - if(issuerName.Data == NULL) { - printf("***Error fetching issuer name. Aborting.\n"); - return 1; - } - uint8 issuerNameHash[CC_SHA1_DIGEST_LENGTH]; - ocspdSha1(issuerName.Data, issuerName.Length, issuerNameHash); - - /* SHA1(issuer public key) */ - CSSM_KEY_PTR pubKey = NULL; - CSSM_SIZE pubKeyLen = sizeof(CSSM_KEY); - pubKey = (CSSM_KEY_PTR)issuerParser.fieldForOid(CSSMOID_CSSMKeyStruct, pubKeyLen); - if(pubKey == NULL) { - printf("***Error fetching public key from issuer cert. Aborting.\n"); - return 1; - } - uint8 pubKeyHash[CC_SHA1_DIGEST_LENGTH]; - ocspdSha1(pubKey->KeyData.Data, pubKey->KeyData.Length, pubKeyHash); - - /* serial number */ - CSSM_DATA serialNum = {0, NULL}; - serialNum.Data = (uint8 *)parser.fieldForOid(CSSMOID_X509V1SerialNumber, - serialNum.Length); - if(serialNum.Data == NULL) { - printf("***Error fetching serial number. Aborting.\n"); - return 1; - } - - /* build the CertID from those components */ - certId.issuerNameHash.Data = issuerNameHash; - certId.issuerNameHash.Length = CC_SHA1_DIGEST_LENGTH; - certId.issuerPubKeyHash.Data = pubKeyHash; - certId.issuerPubKeyHash.Length = CC_SHA1_DIGEST_LENGTH; - certId.serialNumber = serialNum; - - /* SingleResponse.CertStatus - to be encoded on its own */ - SecAsn1OCSPCertStatus certStatus; - memset(&certStatus, 0, sizeof(certStatus)); - SecAsn1OCSPRevokedInfo revokedInfo; - char *revokedAt = NULL; - CSSM_DATA reasonData; - OSStatus ortn; - - if(status == CS_Revoked) { - /* cook up SecAsn1OCSPRevokedInfo */ - certStatus.revokedInfo = &revokedInfo; - revokedAt = appTimeAtNowPlus(-3600, TIME_GEN); - revokedInfo.revocationTime.Data = (uint8 *)revokedAt; - revokedInfo.revocationTime.Length = strlen(revokedAt); - uint8 theReason = reason; - reasonData.Data = &theReason; - reasonData.Length = 1; - revokedInfo.revocationReason = &reasonData; - ortn = SecAsn1EncodeItem(coder, &certStatus, - kSecAsn1OCSPCertStatusRevokedTemplate, - &singleResp.certStatus); - } - else { - ortn = SecAsn1EncodeItem(coder, &certStatus, - kSecAsn1OCSPCertStatusGoodTemplate, - &singleResp.certStatus); - } - if(ortn) { - printf("***Error encoding certStatus\n"); - goto errOut; - } - - /* SingleResponse.thisUpdate */ - thisUpdStr = appTimeAtNowPlus(thisUpdate, TIME_GEN); - thisUpdateData = &singleResp.thisUpdate; - thisUpdateData->Data = (uint8 *)thisUpdStr; - thisUpdateData->Length = strlen(thisUpdStr); - - /* SingleResponse.nextUpdate, optional */ - if(nextUpdate) { - nextUpdStr = appTimeAtNowPlus(nextUpdate, TIME_GEN); - nextUpdateData.Data = (uint8 *)nextUpdStr; - nextUpdateData.Length = strlen(nextUpdStr); - singleResp.nextUpdate = &nextUpdateData; - } - - /* Single Extensions - none for now */ - - /* Now up to ResponseData */ - memset(&responseData, 0, sizeof(responseData)); - - /* skip version */ - - /* - * ResponseData.responderID: KeyHash (of signer); we already got this for CertID. - * WE have to encode this one separately and drop it in as an ASN_ANY. - */ - responderID.byKey = certId.issuerPubKeyHash; - ortn = SecAsn1EncodeItem(coder, &responderID, - kSecAsn1OCSPResponderIDAsKeyTemplate, - &responseData.responderID); - if(ortn) { - printf("***Error encoding responderID\n"); - goto errOut; - } - - /* ResponseData.producedAt = now */ - producedAt = appTimeAtNowPlus(0, TIME_GEN); - responseData.producedAt.Data = (uint8 *)producedAt; - responseData.producedAt.Length = strlen(producedAt); - - /* ResponseData.responses - one of 'em */ - responseData.responses = respArray; - - /* ResponseData.responseExtensions - optionally one, nonce */ - if(nonce) { - nonceExt = new OCSPNonce(coder, false, *nonce); - extenArray[0] = nonceExt->nssExt(); - responseData.responseExtensions = extenArray; - } - else { - responseData.responseExtensions = NULL; - } - - /* encode it */ - encodedTbs.Data = NULL; - encodedTbs.Length = 0; - ortn = SecAsn1EncodeItem(coder, &responseData, - kSecAsn1OCSPResponseDataTemplate, - &encodedTbs); - if(ortn) { - printf("***Error encoding SecAsn1OCSPResponseData\n"); - } -errOut: - /* free resources */ - if(revokedAt) { - CSSM_FREE(revokedAt); - } - if(thisUpdStr) { - CSSM_FREE(thisUpdStr); - } - if(nextUpdStr) { - CSSM_FREE(nextUpdStr); - } - if(nonceExt) { - delete nonceExt; - } - return ortn; -} - -static int genOcspReq( - CSSM_CL_HANDLE clHand, - const unsigned char *certFile, - unsigned certFileLen, - const unsigned char *issuerCertFile, - unsigned issuerCertFileLen, - unsigned char **outFile, // RETURNED - unsigned *outFileLen) // RETURNED -{ - CertParser parser(clHand); - CertParser issuerParser(clHand); - CSSM_DATA certData = {certFileLen, (uint8 *)certFile}; - CSSM_RETURN crtn; - crtn = parser.initWithData(certData); - if(crtn) { - cssmPerror("CertParser.initWithData for subject cert", crtn); - return -1; - } - certData.Data = (uint8 *)issuerCertFile; - certData.Length = issuerCertFileLen; - crtn = issuerParser.initWithData(certData); - if(crtn) { - cssmPerror("CertParser.initWithData for issuer", crtn); - return -1; - } - - /* - * One single request, no extensions - */ - SecAsn1OCSPRequest singleReq; - memset(&singleReq, 0, sizeof(singleReq)); - SecAsn1OCSPCertID &certId = singleReq.reqCert; - - /* algId refers to the hash we'll perform in issuer name and key */ - certId.algId.algorithm = CSSMOID_SHA1; - certId.algId.parameters.Data = nullParam; - certId.algId.parameters.Length = sizeof(nullParam); - - /* SHA1(issuerName) */ - CSSM_DATA issuerName = {0, NULL}; - issuerName.Data = (uint8 *)parser.fieldForOid(CSSMOID_X509V1IssuerNameStd, - issuerName.Length); - if(issuerName.Data == NULL) { - printf("***Error fetching issuer name. Aborting.\n"); - return 1; - } - uint8 issuerNameHash[CC_SHA1_DIGEST_LENGTH]; - ocspdSha1(issuerName.Data, issuerName.Length, issuerNameHash); - - /* SHA1(issuer public key) */ - CSSM_KEY_PTR pubKey = NULL; - CSSM_SIZE pubKeyLen = sizeof(CSSM_KEY); - pubKey = (CSSM_KEY_PTR)issuerParser.fieldForOid(CSSMOID_CSSMKeyStruct, pubKeyLen); - if(pubKey == NULL) { - printf("***Error fetching public key from issuer cert. Aborting.\n"); - return 1; - } - uint8 pubKeyHash[CC_SHA1_DIGEST_LENGTH]; - ocspdSha1(pubKey->KeyData.Data, pubKey->KeyData.Length, pubKeyHash); - - /* serial number */ - CSSM_DATA serialNum = {0, NULL}; - serialNum.Data = (uint8 *)parser.fieldForOid(CSSMOID_X509V1SerialNumber, - serialNum.Length); - if(serialNum.Data == NULL) { - printf("***Error fetching serial number. Aborting.\n"); - return 1; - } - - /* build the CertID from those components */ - certId.issuerNameHash.Data = issuerNameHash; - certId.issuerNameHash.Length = CC_SHA1_DIGEST_LENGTH; - certId.issuerPubKeyHash.Data = pubKeyHash; - certId.issuerPubKeyHash.Length = CC_SHA1_DIGEST_LENGTH; - certId.serialNumber = serialNum; - - /* - * Build top level request with one entry in requestList, no signature, - * one extension (a nonce) - */ - SecAsn1OCSPSignedRequest signedReq; - SecAsn1OCSPRequest *reqArray[2] = { &singleReq, NULL }; - SecAsn1OCSPTbsRequest &tbs = signedReq.tbsRequest; - memset(&signedReq, 0, sizeof(signedReq)); - uint8 version = 0; - CSSM_DATA vers = {1, &version}; - tbs.version = &vers; - tbs.requestList = reqArray; - - /* one extension - the nonce */ - SecAsn1CoderRef coder; - SecAsn1CoderCreate(&coder); - uint8 nonceBytes[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0}; - CSSM_DATA nonceData = {8, nonceBytes}; - OCSPNonce *nonce = new OCSPNonce(coder, false, nonceData); - NSS_CertExtension *extenArray[2] = {nonce->nssExt(), NULL}; - tbs.requestExtensions = extenArray; - - /* Encode */ - OSStatus ortn; - CSSM_DATA encoded = {0, NULL}; - ortn = SecAsn1EncodeItem(coder, &signedReq, kSecAsn1OCSPSignedRequestTemplate, - &encoded); - if(ortn) { - printf("***Error encoding SecAsn1OCSPSignedRequest\n"); - } - else { - *outFile = (unsigned char *)malloc(encoded.Length); - *outFileLen = encoded.Length; - memmove(*outFile, encoded.Data, encoded.Length); - } - SecAsn1CoderRelease(coder); - return (int)ortn; -} - -static void dumpCertID( - SecAsn1OCSPCertID *certID, - int indent) -{ - doIndent(indent); - printf("algId : "); - printDataAsHex(&certID->algId.algorithm); - - doIndent(indent); - printf("issuerNameHash : "); - printDataAsHex(&certID->issuerNameHash); - - doIndent(indent); - printf("issuerPubKeyHash : "); - printDataAsHex(&certID->issuerPubKeyHash); - - doIndent(indent); - printf("serialNumber : "); - printDataAsHex(&certID->serialNumber); -} - -static void printCritical( - int indent, - OCSPExtension *ocspExt) -{ - doIndent(indent); - printf("Critical : %s\n", ocspExt->critical() ? "true" : "false"); -} - -static void printOcspExt( - SecAsn1CoderRef coder, - NSS_CertExtension *nssExt, - int indent) -{ - OCSPExtension *ocspExt = NULL; - try { - ocspExt = OCSPExtension::createFromNSS(coder, *nssExt); - } - catch(...) { - doIndent(indent); - printf("***Error thrown parsing extension\n"); - return; - } - switch(ocspExt->tag()) { - case OET_Unknown: - doIndent(indent); - printf("Extension type: Unknown\n"); - printCritical(indent, ocspExt); - return; - case OET_Nonce: - { - doIndent(indent); - printf("Extension type : Nonce\n"); - printCritical(indent, ocspExt); - doIndent(indent); - OCSPNonce *nonce = dynamic_cast(ocspExt); - if(nonce == NULL) { - printf("***dynamic_cast failure in OCSPNonce!\n"); - return; - } - printf("nonce value : "); - printDataAsHex(&nonce->nonce()); - break; - } - case OET_CrlReference: - doIndent(indent); - printf("Extension type : CrlReference"); - printCritical(indent, ocspExt); - /* TBD */ - return; - case OET_AcceptResponse: - doIndent(indent); - printf("Extension type : AcceptResponse"); - printCritical(indent, ocspExt); - /* TBD */ - return; - case OET_ArchiveCutoff: - doIndent(indent); - printf("Extension type : ArchiveCutoff"); - printCritical(indent, ocspExt); - /* TBD */ - return; - case OET_ServiceLocator: - doIndent(indent); - printf("Extension type : ServiceLocator"); - printCritical(indent, ocspExt); - /* TBD */ - return; - default: - /* this code is out of sync with ocspExtensions.{h,cpp} */ - doIndent(indent); - printf("Extension type : unrecognized - code sync error"); - printCritical(indent, ocspExt); - return; - - } -} - -static int parseOcspReq( - CSSM_CL_HANDLE clHand, - unsigned char *inFile, - unsigned inFileLen, - bool verbose) -{ - SecAsn1CoderRef coder; - SecAsn1OCSPSignedRequest signedReq; - SecAsn1OCSPTbsRequest &tbs = signedReq.tbsRequest; - OSStatus ortn; - int indent; - unsigned numExts; - unsigned numReqs; - - SecAsn1CoderCreate(&coder); - memset(&signedReq, 0, sizeof(signedReq)); - - ortn = SecAsn1Decode(coder, inFile, inFileLen, kSecAsn1OCSPSignedRequestTemplate, - &signedReq); - if(ortn) { - printf("***Error decoding SecAsn1OCSPSignedRequest\n"); - goto errOut; - } - printf("SecAsn1OCSPSignedRequest:\n"); - - printf("SecAsn1OCSPTbsRequest:\n"); - indent = 2; - if(tbs.version) { - doIndent(indent); - printf("Version : "); - printDataAsHex(tbs.version); - } - if(tbs.requestorName) { - doIndent(indent); - printf("NSS_GeneralName found; print it later maybe\n"); - } - numReqs = ocspdArraySize((const void **)tbs.requestList); - for(unsigned dex=0; dexreqCert; - dumpCertID(certID, indent); - indent -= 2; - numExts = ocspdArraySize((const void **)req->extensions); - for(unsigned extDex=0; extDexextensions[dex], indent + 2); - } - indent -= 2; - } - - numExts = ocspdArraySize((const void **)tbs.requestExtensions); - for(unsigned extDex=0; extDexData) { - doIndent(indent); - printf("version: %u\n", respData.version->Data[0]); - } - doIndent(indent); - printf("ResponderID:\n"); - indent += 2; - memset(&responderID, 0, sizeof(responderID)); - if(respData.responderID.Data == NULL) { - doIndent(indent); - printf("***Malformed(empty)***\n"); - return 1; - } - - /* lame-o choice processing */ - tag = respData.responderID.Data[0] & SEC_ASN1_TAGNUM_MASK; - switch(tag) { - case RIT_Name: - templ = kSecAsn1OCSPResponderIDAsNameTemplate; - break; - case RIT_Key: - templ = kSecAsn1OCSPResponderIDAsKeyTemplate; - break; - default: - doIndent(indent); - printf("**Unknown tag for ResponderID (%u)\n", tag); - return 1; - } - ortn = SecAsn1DecodeData(coder, &respData.responderID, templ, &responderID); - if(ortn) { - doIndent(indent); - printf("***Error decoding ResponderID\n"); - return 1; - } - doIndent(indent); - switch(tag) { - case RIT_Name: - printf("byName:\n"); - printName((NSS_Name &)responderID.byName, indent + 2); - break; - case RIT_Key: - printf("byKey : "); - printDataAsHex(&responderID.byKey); - break; - } - indent -= 2; // end of ResponderID - - doIndent(indent); - printf("producedAt: "); - printString(&respData.producedAt); - unsigned numResps = ocspdArraySize((const void **)respData.responses); - doIndent(indent); - printf("Num responses: %u\n", numResps); - for(unsigned dex=0; dexcertID, indent + 2); - - doIndent(indent); - printf("certStatus: "); - /* lame-o choice processing */ - tag = resp->certStatus.Data[0] & SEC_ASN1_TAGNUM_MASK; - switch(tag) { - case CS_Good: - printf("Good\n"); - break; - case CS_Unknown: - printf("Unknown\n"); - break; - default: - printf("**MALFORMED cert status tag (%u)\n", tag); - break; - case CS_Revoked: - { - printf("Revoked\n"); - doIndent(indent); - SecAsn1OCSPCertStatus certStatus; - memset(&certStatus, 0, sizeof(certStatus)); - ortn = SecAsn1DecodeData(coder, &resp->certStatus, - kSecAsn1OCSPCertStatusRevokedTemplate, &certStatus); - if(ortn) { - doIndent(indent); - printf("***error parsing RevokedInfo\n"); - break; - } - if(certStatus.revokedInfo == NULL) { - doIndent(indent); - printf("***GAK! Malformed (empty) revokedInfo\n");break; - } - printf("RevokedIndfo:\n"); - indent += 2; - doIndent(indent); - printf("revocationTime: "); - printString(&certStatus.revokedInfo->revocationTime); - if(certStatus.revokedInfo->revocationReason) { - doIndent(indent); - printf("reason: %u\n", - certStatus.revokedInfo->revocationReason->Data[0]); - } - indent -= 2; // end of RevokedInfo - break; - } - } /* switch cert status tag */ - - doIndent(indent); - printf("thisUpdate: "); - printString(&resp->thisUpdate); - - if(resp->nextUpdate) { - doIndent(indent); - printf("nextUpdate: "); - printString(resp->nextUpdate); - } - - numExts = ocspdArraySize((const void **)resp->singleExtensions); - for(unsigned extDex=0; extDexsingleExtensions[extDex], indent + 2); - } - - indent -= 2; // end of resp[dex] - } - - numExts = ocspdArraySize((const void **)respData.responseExtensions); - for(unsigned extDex=0; extDexresponseType, - &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; dexData, 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; -} - -static int postOcspReq( - CSSM_CL_HANDLE clHand, - const unsigned char *certFile, - unsigned certFileLen, - const unsigned char *issuerCertFile, - unsigned issuerCertFileLen, - const char *responderURI, - bool doParse, - bool verbose, - unsigned char **outFile, // RETURNED - unsigned *outFileLen) // RETURNED -{ - auto_ptr subject; - auto_ptr issuer; - CSSM_DATA uriData = {0, NULL}; - CSSM_DATA *url = NULL; - - try { - CSSM_DATA cdata = {certFileLen, (uint8 *)certFile}; - subject.reset(new CertParser(clHand, cdata)); - } - catch(...) { - printf("***Error parsing subject cert. Aborting.\n"); - return -1; - } - try { - CSSM_DATA cdata = {issuerCertFileLen, (uint8 *)issuerCertFile}; - issuer.reset(new CertParser(clHand, cdata)); - } - catch(...) { - printf("***Error parsing issuer cert. Aborting.\n"); - return -1; - } - - SecAsn1CoderRef coder; - SecAsn1CoderCreate(&coder); - /* subsequent errors to errOut: */ - int ourRtn = 0; - const CSSM_DATA *derReq = NULL; - auto_ptr ocspReq; - - if(responderURI != NULL) { - uriData.Data = (uint8 *)responderURI; - uriData.Length = strlen(responderURI); - url = &uriData; - } - else { - /* get OCSP URL from subject cert */ - url = ocspUrlFromCert(*subject, coder); - if(url == NULL) { - printf("Sorry, no can do.\n"); - ourRtn = -1; - goto errOut; - } - } - - /* create DER-encoded OCSP request for subject */ - try { - ocspReq.reset(new OCSPRequest(*subject, *issuer, false)); - derReq = ocspReq->encode(); - } - catch(...) { - printf("***Error creating OCSP request. Aborting.\n"); - ourRtn = -1; - goto errOut; - } - - /* do it */ - CSSM_DATA ocspResp; - CSSM_RETURN crtn; - crtn = ocspdHttpPost(coder, *url, *derReq, ocspResp); - if(crtn) { - printf("***Error fetching OCSP response***\n"); - cssmPerror("ocspdHttpPost", crtn); - ourRtn = -1; - goto errOut; - } - *outFile = ocspResp.Data; - *outFileLen = ocspResp.Length; - if(doParse) { - parseOcspResp(clHand, ocspResp.Data, ocspResp.Length, verbose); - } - /* copy out */ - *outFile = (unsigned char *)malloc(ocspResp.Length); - *outFileLen = ocspResp.Length; - memmove(*outFile, ocspResp.Data, ocspResp.Length); - -errOut: - SecAsn1CoderRelease(coder); - return ourRtn; -} - -typedef enum { - op_genReq, - op_parseReq, - op_genReply, - op_parseResp, - op_post -} ocspOp; - -int main(int argc, char **argv) -{ - if(argc < 2) { - usage(argv); - } - ocspOp op; - switch(argv[1][0]) { - case 'g': op = op_genReq; break; - case 'G': op = op_parseReq; break; - case 'r': op = op_genReply; break; - case 'R': op = op_parseResp; break; - case 'p': op = op_post; break; - default: usage(argv); - } - - /* user defined vars */ - char *inFile = NULL; - char *outFile = NULL; - char *inCertName = NULL; - char *issuerCertName = NULL; - SecAsn1OCSPCertStatusTag certStatus = CS_Good; - CE_CrlReason crlReason = CE_CR_Unspecified; - char *kcName = NULL; - bool verbose = false; - bool doParse = false; - const char *responderURI = NULL; - - extern int optind; - optind = 2; - extern char *optarg; - int arg; - while ((arg = getopt(argc, argv, "c:C:i:o:s:r:k:phvu:")) != -1) { - switch (arg) { - case 'c': - inCertName = optarg; - break; - case 'C': - issuerCertName = optarg; - break; - case 'i': - inFile = optarg; - break; - case 'o': - outFile = optarg; - break; - case 's': - switch(optarg[0]) { - case 'g': - certStatus = CS_Good; - break; - case 'r': - certStatus = CS_Revoked; - break; - case 'u': - certStatus = CS_Unknown; - break; - default: - printf("***Unrecognized certStatus***\n"); - usage(argv); - } - break; - case 'r': - crlReason = atoi(optarg); - break; - case 'k': - kcName = optarg; - break; - case 'v': - verbose = 1; - break; - case 'p': - doParse = true; - break; - case 'u': - responderURI = optarg; - break; - default: - case '?': - usage(argv); - } - } - if(optind != argc) { - /* this happens if you give getopt() an arg which doesn't start with '-' */ - usage(argv); - } - - unsigned char *certData = NULL; - unsigned certDataLen = 0; - unsigned char *issuerCertData = NULL; - unsigned issuerCertDataLen = 0; - unsigned char *inData = NULL; - unsigned inDataLen = 0; - unsigned char *outData = NULL; - unsigned outDataLen = 0; - SecKeychainRef kcRef = NULL; - OSStatus ortn; - - if(inCertName) { - if(readFile(inCertName, &certData, &certDataLen)) { - printf("***Error reading cert file %s. Aborting.\n", inCertName); - exit(1); - } - } - if(issuerCertName) { - if(readFile(issuerCertName, &issuerCertData, &issuerCertDataLen)) { - printf("***Error reading cert file %s. Aborting.\n", issuerCertName); - exit(1); - } - } - if(inFile) { - if(readFile(inFile, &inData, &inDataLen)) { - printf("***Error reading input file %s. Aborting.\n", inFile); - exit(1); - } - } - if(kcName) { - ortn = SecKeychainOpen(kcName, &kcRef); - if(ortn) { - cssmPerror("SecKeychainOpen", ortn); - return ortn; - } - } - CSSM_CL_HANDLE clHand = cuClStartup(); - - switch(op) { - case op_genReq: - ortn = genOcspReq(clHand, certData, certDataLen, - issuerCertData, issuerCertDataLen, - &outData, &outDataLen); - break; - case op_parseReq: - ortn = parseOcspReq(clHand, inData, inDataLen, verbose); - break; - case op_genReply: - { - SecIdentityRef idRef = NULL; - ortn = sslSimpleIdentPicker(kcRef, &idRef); - if(ortn) { - printf("***Error choosing identity. Aborting.\n"); - exit(1); - } - ortn = genOcspResp(clHand, certStatus, crlReason, - certData, certDataLen, issuerCertData, issuerCertDataLen, - idRef, &outData, &outDataLen); - CFRelease(idRef); - break; - } - case op_parseResp: - ortn = parseOcspResp(clHand, inData, inDataLen, verbose); - break; - case op_post: - ortn = postOcspReq(clHand, certData, certDataLen, - issuerCertData, issuerCertDataLen, responderURI, - doParse, verbose, - &outData, &outDataLen); - break; - default: - printf("Op %s is not yet implemented.\n", argv[1]); - exit(1); - } - - if(ortn == 0) { - if(outData != NULL) { - if(outFile== NULL) { - printf("...generated %u bytes but no place to write it.\n", outDataLen); - } - else { - ortn = writeFile(outFile, outData, outDataLen); - if(ortn) { - printf("***Error writing output to %s.\n", outFile); - } - else { - printf("...wrote %u bytes to %s\n", outDataLen, outFile); - } - } - } - } - return ortn; -}