switch (response->statusValue) { case ocspResponse_successful: break; case ocspResponse_malformedRequest: PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); goto loser; case ocspResponse_internalError: PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); goto loser; case ocspResponse_tryLater: PORT_SetError(SEC_ERROR_OCSP_TRY_SERVER_LATER); goto loser; case ocspResponse_sigRequired:  PORT_SetError(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG); goto loser; case ocspResponse_unauthorized: PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST); goto loser; case ocspResponse_other: case ocspResponse_unused: default: PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
if (CERT_GetOCSPResponseStatus(response) != SECSuccess) {
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,		     int64 time, void *pwArg){    char *location = NULL;    PRBool locationIsDefault;    CERTCertList *certList = NULL;    SECItem *encodedResponse = NULL;    CERTOCSPRequest *request = NULL;    CERTOCSPResponse *response = NULL;    CERTCertificate *signerCert = NULL;    CERTCertificate *issuerCert = NULL;    CERTOCSPCertID *certID;    SECStatus rv = SECFailure;    /*     * The first thing we need to do is find the location of the responder.     * This will be the value of the default responder (if enabled), else     * it will come out of the AIA extension in the cert (if present).     * If we have no such location, then this cert does not "deserve" to     * be checked -- that is, we consider it a success and just return.     * The way we tell that is by looking at the error number to see if     * the problem was no AIA extension was found; any other error was     * a true failure that we unfortunately have to treat as an overall     * failure here.     */    location = ocsp_GetResponderLocation(handle, cert, &locationIsDefault);    if (location == NULL) {	if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND)	    return SECSuccess;	else	    return SECFailure;    }    /*     * For now, create a cert-list of one.     * XXX In the fullness of time, we will want/need to handle a     * certificate chain.  This will be done either when a new parameter     * tells us to, or some configuration variable tells us to.  In any     * case, handling it is complicated because we may need to send as     * many requests (and receive as many responses) as we have certs     * in the chain.  If we are going to talk to a default responder,     * and we only support one default responder, we can put all of the     * certs together into one request.  Otherwise, we must break them up     * into multiple requests.  (Even if all of the requests will go to     * the same location, the signature on each response will be different,     * because each issuer is different.  Carefully read the OCSP spec     * if you do not understand this.)     */    certList = CERT_NewCertList();    if (certList == NULL)	goto loser;    /* dup it because freeing the list will destroy the cert, too */    cert = CERT_DupCertificate(cert);    if (cert == NULL)	goto loser;    if (CERT_AddCertToListTail(certList, cert) != SECSuccess) {	CERT_DestroyCertificate(cert);	goto loser;    }    /*     * XXX If/when signing of requests is supported, that second NULL     * should be changed to be the signer certificate.  Not sure if that     * should be passed into this function or retrieved via some operation     * on the handle/context.     */    encodedResponse = CERT_GetEncodedOCSPResponse(NULL, certList, location,						  time, locationIsDefault,						  NULL, pwArg, &request);    if (encodedResponse == NULL) {	goto loser;    }    response = CERT_DecodeOCSPResponse(encodedResponse);    if (response == NULL) {	goto loser;    }    /*     * Okay, we at least have a response that *looks* like a response!     * Now see if the overall response status value is good or not.     * If not, we set an error and give up.  (It means that either the     * server had a problem, or it didn't like something about our     * request.  Either way there is nothing to do but give up.)     * Otherwise, we continue to find the actual per-cert status     * in the response.     */    switch (response->statusValue) {      case ocspResponse_successful:	break;      case ocspResponse_malformedRequest:	PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);	goto loser;      case ocspResponse_internalError:	PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);	goto loser;      case ocspResponse_tryLater:	PORT_SetError(SEC_ERROR_OCSP_TRY_SERVER_LATER);	goto loser;      case ocspResponse_sigRequired:	/* XXX We *should* retry with a signature, if possible. */	PORT_SetError(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);	goto loser;      case ocspResponse_unauthorized:	PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);	goto loser;      case ocspResponse_other:      case ocspResponse_unused:      default:	PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);	goto loser;    }    /*     * If we've made it this far, we expect a response with a good signature.     * So, check for that.     */    issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);    rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert,			issuerCert);    if (rv != SECSuccess)	goto loser;    PORT_Assert(signerCert != NULL);	/* internal consistency check */    /* XXX probably should set error, return failure if signerCert is null */    /*     * Again, we are only doing one request for one cert.     * XXX When we handle cert chains, the following code will obviously     * have to be modified, in coordation with the code above that will     * have to determine how to make multiple requests, etc.  It will need     * to loop, and for each certID in the request, find the matching     * single response and check the status specified by it.     *     * We are helped here in that we know that the requests are made with     * the request list in the same order as the order of the certs we hand     * to it.  This is why I can directly access the first member of the     * single request array for the one cert I care about.     */    certID = request->tbsRequest->requestList[0]->reqCert;    rv = CERT_GetOCSPStatusForCertID(handle, response, certID,                                      signerCert, time);loser:    if (issuerCert != NULL)	CERT_DestroyCertificate(issuerCert);    if (signerCert != NULL)	CERT_DestroyCertificate(signerCert);    if (response != NULL)	CERT_DestroyOCSPResponse(response);    if (request != NULL)	CERT_DestroyOCSPRequest(request);    if (encodedResponse != NULL)	SECITEM_FreeItem(encodedResponse, PR_TRUE);    if (certList != NULL)	CERT_DestroyCertList(certList);    if (location != NULL)	PORT_Free(location);    return rv;}