/*
 * 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);
}
Example #2
0
/*
 * 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;
}
Example #3
0
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;
}