/* * FUNCTION: pkix_pl_OcspResponse_Destroy * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) */ static PKIX_Error * pkix_pl_OcspResponse_Destroy( PKIX_PL_Object *object, void *plContext) { PKIX_PL_OcspResponse *ocspRsp = NULL; const SEC_HttpClientFcn *httpClient = NULL; const SEC_HttpClientFcnV1 *hcv1 = NULL; PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Destroy"); PKIX_NULLCHECK_ONE(object); PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE, plContext), PKIX_OBJECTNOTANOCSPRESPONSE); ocspRsp = (PKIX_PL_OcspResponse *)object; if (ocspRsp->nssOCSPResponse != NULL) { CERT_DestroyOCSPResponse(ocspRsp->nssOCSPResponse); ocspRsp->nssOCSPResponse = NULL; } if (ocspRsp->signerCert != NULL) { CERT_DestroyCertificate(ocspRsp->signerCert); ocspRsp->signerCert = NULL; } httpClient = (const SEC_HttpClientFcn *)(ocspRsp->httpClient); if (httpClient && (httpClient->version == 1)) { hcv1 = &(httpClient->fcnTable.ftable1); if (ocspRsp->sessionRequest != NULL) { (*hcv1->freeFcn)(ocspRsp->sessionRequest); ocspRsp->sessionRequest = NULL; } if (ocspRsp->serverSession != NULL) { (*hcv1->freeSessionFcn)(ocspRsp->serverSession); ocspRsp->serverSession = NULL; } } if (ocspRsp->arena != NULL) { PORT_FreeArena(ocspRsp->arena, PR_FALSE); ocspRsp->arena = NULL; } PKIX_DECREF(ocspRsp->producedAtDate); PKIX_DECREF(ocspRsp->pkixSignerCert); PKIX_DECREF(ocspRsp->request); cleanup: PKIX_RETURN(OCSPRESPONSE); }
/* * Decode the DER/BER-encoded item "data" as an OCSP response * and pretty-print the subfields. */ static SECStatus print_response (FILE *out_file, SECItem *data, CERTCertDBHandle *handle) { CERTOCSPResponse *response; int level = 0; PORT_Assert (out_file != NULL); PORT_Assert (data != NULL); if (out_file == NULL || data == NULL) { PORT_SetError (SEC_ERROR_INVALID_ARGS); return SECFailure; } response = CERT_DecodeOCSPResponse (data); if (response == NULL) return SECFailure; if (response->statusValue >= ocspResponse_min && response->statusValue <= ocspResponse_max) { fprintf (out_file, "Response Status: %s\n", responseStatusNames[response->statusValue]); } else { fprintf (out_file, "Response Status: other (Status value %d out of defined range)\n", (int)response->statusValue); } if (response->statusValue == ocspResponse_successful) { ocspResponseBytes *responseBytes = response->responseBytes; SECStatus sigStatus; CERTCertificate *signerCert = NULL; PORT_Assert (responseBytes != NULL); level++; fprintf (out_file, "Response Bytes:\n"); SECU_PrintObjectID (out_file, &(responseBytes->responseType), "Response Type", level); switch (response->responseBytes->responseTypeTag) { case SEC_OID_PKIX_OCSP_BASIC_RESPONSE: print_basic_response (out_file, responseBytes->decodedResponse.basic, level); break; default: SECU_Indent (out_file, level); fprintf (out_file, "Unknown response syntax\n"); break; } sigStatus = CERT_VerifyOCSPResponseSignature (response, handle, NULL, &signerCert, NULL); SECU_Indent (out_file, level); fprintf (out_file, "Signature verification "); if (sigStatus != SECSuccess) { fprintf (out_file, "failed: %s\n", SECU_Strerror (PORT_GetError())); } else { fprintf (out_file, "succeeded.\n"); if (signerCert != NULL) { SECU_PrintName (out_file, &signerCert->subject, "Signer", level); CERT_DestroyCertificate (signerCert); } else { SECU_Indent (out_file, level); fprintf (out_file, "No signer cert returned?\n"); } } } else { SECU_Indent (out_file, level); fprintf (out_file, "Unsuccessful response, no more information.\n"); } CERT_DestroyOCSPResponse (response); return SECSuccess; }
int main(int argc, char **argv) { SECStatus rv; int retval = -1; CERTCertDBHandle *certHandle = NULL; CERTCertificate *caCert = NULL, *cert = NULL; CERTOCSPCertID *cid = NULL; PLArenaPool *arena = NULL; PRTime now = PR_Now(); SECItem *encoded = NULL; CERTOCSPResponse *decoded = NULL; SECStatus statusDecoded; SECItem *encodedRev = NULL; CERTOCSPResponse *decodedRev = NULL; SECStatus statusDecodedRev; SECItem *encodedFail = NULL; CERTOCSPResponse *decodedFail = NULL; SECStatus statusDecodedFail; CERTCertificate *obtainedSignerCert = NULL; if (argc != 4 && argc != 6) { return Usage(); } if (argc == 6) { if (!strcmp(argv[4], "-p")) { pwdata.source = PW_PLAINTEXT; pwdata.data = PORT_Strdup(argv[5]); } else if (!strcmp(argv[4], "-f")) { pwdata.source = PW_FROMFILE; pwdata.data = PORT_Strdup(argv[5]); } else return Usage(); } PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); /*rv = NSS_Init(SECU_ConfigDirectory(NULL));*/ rv = NSS_Init(argv[1]); if (rv != SECSuccess) { SECU_PrintPRandOSError(argv[0]); goto loser; } PK11_SetPasswordFunc(SECU_GetModulePassword); certHandle = CERT_GetDefaultCertDB(); if (!certHandle) goto loser; if (!getCaAndSubjectCert(certHandle, argv[2], argv[3], &caCert, &cert)) goto loser; cid = CERT_CreateOCSPCertID(cert, now); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); encoded = encode(arena, cid, caCert); PORT_Assert(encoded); decoded = CERT_DecodeOCSPResponse(encoded); statusDecoded = CERT_GetOCSPResponseStatus(decoded); PORT_Assert(statusDecoded == SECSuccess); statusDecoded = CERT_VerifyOCSPResponseSignature(decoded, certHandle, &pwdata, &obtainedSignerCert, caCert); PORT_Assert(statusDecoded == SECSuccess); statusDecoded = CERT_GetOCSPStatusForCertID(certHandle, decoded, cid, obtainedSignerCert, now); PORT_Assert(statusDecoded == SECSuccess); CERT_DestroyCertificate(obtainedSignerCert); encodedRev = encodeRevoked(arena, cid, caCert); PORT_Assert(encodedRev); decodedRev = CERT_DecodeOCSPResponse(encodedRev); statusDecodedRev = CERT_GetOCSPResponseStatus(decodedRev); PORT_Assert(statusDecodedRev == SECSuccess); statusDecodedRev = CERT_VerifyOCSPResponseSignature(decodedRev, certHandle, &pwdata, &obtainedSignerCert, caCert); PORT_Assert(statusDecodedRev == SECSuccess); statusDecodedRev = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid, obtainedSignerCert, now); PORT_Assert(statusDecodedRev == SECFailure); PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE); CERT_DestroyCertificate(obtainedSignerCert); encodedFail = CERT_CreateEncodedOCSPErrorResponse( arena, SEC_ERROR_OCSP_TRY_SERVER_LATER); PORT_Assert(encodedFail); decodedFail = CERT_DecodeOCSPResponse(encodedFail); statusDecodedFail = CERT_GetOCSPResponseStatus(decodedFail); PORT_Assert(statusDecodedFail == SECFailure); PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER); retval = 0; loser: if (retval != 0) SECU_PrintError(argv[0], "tests failed"); if (cid) CERT_DestroyOCSPCertID(cid); if (cert) CERT_DestroyCertificate(cert); if (caCert) CERT_DestroyCertificate(caCert); if (arena) PORT_FreeArena(arena, PR_FALSE); if (decoded) CERT_DestroyOCSPResponse(decoded); if (decodedRev) CERT_DestroyOCSPResponse(decodedRev); if (decodedFail) CERT_DestroyOCSPResponse(decodedFail); if (pwdata.data) { PORT_Free(pwdata.data); } if (NSS_Shutdown() != SECSuccess) { SECU_PrintError(argv[0], "NSS shutdown:"); if (retval == 0) retval = -2; } return retval; }