PKIX_Error * pkix_pl_OcspResponse_Decode( PKIX_PL_OcspResponse *response, PKIX_Boolean *pPassed, SECErrorCodes *pReturnCode, void *plContext) { PKIX_ENTER(OCSPRESPONSE, "PKIX_PL_OcspResponse_Decode"); PKIX_NULLCHECK_TWO(response, response->encodedResponse); response->nssOCSPResponse = CERT_DecodeOCSPResponse(response->encodedResponse); if (response->nssOCSPResponse != NULL) { *pPassed = PKIX_TRUE; *pReturnCode = 0; } else { *pPassed = PKIX_FALSE; *pReturnCode = PORT_GetError(); } 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; }