Bug Summary

File:s/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c
Warning:line 915, column 13
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pkix_pl_ocspresponse.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/libpkix/pkix_pl_nss/pki -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/libpkix/pkix_pl_nss/pki -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../../../dist/public/nss -I ../../../../../dist/private/nss -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c pkix_pl_ocspresponse.c
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4/*
5 * pkix_pl_ocspresponse.c
6 *
7 */
8
9#include "pkix_pl_ocspresponse.h"
10
11/* ----Public functions------------------------------------- */
12/*
13 * This is the libpkix replacement for CERT_VerifyOCSPResponseSignature.
14 * It is used if it has been set as the verifyFcn member of ocspChecker.
15 */
16PKIX_Error *
17PKIX_PL_OcspResponse_UseBuildChain(
18 PKIX_PL_Cert *signerCert,
19 PKIX_PL_Date *producedAt,
20 PKIX_ProcessingParams *procParams,
21 void **pNBIOContext,
22 void **pState,
23 PKIX_BuildResult **pBuildResult,
24 PKIX_VerifyNode **pVerifyTree,
25 void *plContext)
26{
27 PKIX_ProcessingParams *caProcParams = NULL((void*)0);
28 PKIX_PL_Date *date = NULL((void*)0);
29 PKIX_ComCertSelParams *certSelParams = NULL((void*)0);
30 PKIX_CertSelector *certSelector = NULL((void*)0);
31 void *nbioContext = NULL((void*)0);
32 PKIX_Error *buildError = NULL((void*)0);
33
34 PKIX_ENTER(OCSPRESPONSE, "pkix_OcspResponse_UseBuildChain")static const char cMyFuncName[] = {"pkix_OcspResponse_UseBuildChain"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
35 PKIX_NULLCHECK_THREE(signerCert, producedAt, procParams)do { if (((signerCert) == ((void*)0)) || ((producedAt) == ((void
*)0)) || ((procParams) == ((void*)0))){ stdVars.aPkixErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
36 PKIX_NULLCHECK_THREE(pNBIOContext, pState, pBuildResult)do { if (((pNBIOContext) == ((void*)0)) || ((pState) == ((void
*)0)) || ((pBuildResult) == ((void*)0))){ stdVars.aPkixErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
37
38 nbioContext = *pNBIOContext;
39 *pNBIOContext = NULL((void*)0);
40
41 /* Are we resuming after a WOULDBLOCK return, or starting anew ? */
42 if (nbioContext == NULL((void*)0)) {
43 /* Starting anew */
44 PKIX_CHECK(PKIX_PL_Object_Duplicatedo { stdVars.aPkixErrorResult = (PKIX_PL_Object_Duplicate ((PKIX_PL_Object
*)procParams, (PKIX_PL_Object **)&caProcParams, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTDUPLICATEFAILED; goto cleanup; } } while (0)
45 ((PKIX_PL_Object *)procParams,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Duplicate ((PKIX_PL_Object
*)procParams, (PKIX_PL_Object **)&caProcParams, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTDUPLICATEFAILED; goto cleanup; } } while (0)
46 (PKIX_PL_Object **)&caProcParams,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Duplicate ((PKIX_PL_Object
*)procParams, (PKIX_PL_Object **)&caProcParams, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTDUPLICATEFAILED; goto cleanup; } } while (0)
47 plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Duplicate ((PKIX_PL_Object
*)procParams, (PKIX_PL_Object **)&caProcParams, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTDUPLICATEFAILED; goto cleanup; } } while (0)
48 PKIX_OBJECTDUPLICATEFAILED)do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Duplicate ((PKIX_PL_Object
*)procParams, (PKIX_PL_Object **)&caProcParams, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTDUPLICATEFAILED; goto cleanup; } } while (0)
;
49
50 PKIX_CHECK(PKIX_ProcessingParams_SetDate(procParams, date, plContext),do { stdVars.aPkixErrorResult = (PKIX_ProcessingParams_SetDate
(procParams, date, plContext)); if (stdVars.aPkixErrorResult)
{ stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_PROCESSINGPARAMSSETDATEFAILED
; goto cleanup; } } while (0)
51 PKIX_PROCESSINGPARAMSSETDATEFAILED)do { stdVars.aPkixErrorResult = (PKIX_ProcessingParams_SetDate
(procParams, date, plContext)); if (stdVars.aPkixErrorResult)
{ stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_PROCESSINGPARAMSSETDATEFAILED
; goto cleanup; } } while (0)
;
52
53 /* create CertSelector with target certificate in params */
54
55 PKIX_CHECK(PKIX_CertSelector_Createdo { stdVars.aPkixErrorResult = (PKIX_CertSelector_Create (((
void*)0), ((void*)0), &certSelector, plContext)); if (stdVars
.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; stdVars.aPkixErrorCode = PKIX_CERTSELECTORCREATEFAILED
; goto cleanup; } } while (0)
56 (NULL, NULL, &certSelector, plContext),do { stdVars.aPkixErrorResult = (PKIX_CertSelector_Create (((
void*)0), ((void*)0), &certSelector, plContext)); if (stdVars
.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; stdVars.aPkixErrorCode = PKIX_CERTSELECTORCREATEFAILED
; goto cleanup; } } while (0)
57 PKIX_CERTSELECTORCREATEFAILED)do { stdVars.aPkixErrorResult = (PKIX_CertSelector_Create (((
void*)0), ((void*)0), &certSelector, plContext)); if (stdVars
.aPkixErrorResult) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; stdVars.aPkixErrorCode = PKIX_CERTSELECTORCREATEFAILED
; goto cleanup; } } while (0)
;
58
59 PKIX_CHECK(PKIX_ComCertSelParams_Createdo { stdVars.aPkixErrorResult = (PKIX_ComCertSelParams_Create
(&certSelParams, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COMCERTSELPARAMSCREATEFAILED;
goto cleanup; } } while (0)
60 (&certSelParams, plContext),do { stdVars.aPkixErrorResult = (PKIX_ComCertSelParams_Create
(&certSelParams, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COMCERTSELPARAMSCREATEFAILED;
goto cleanup; } } while (0)
61 PKIX_COMCERTSELPARAMSCREATEFAILED)do { stdVars.aPkixErrorResult = (PKIX_ComCertSelParams_Create
(&certSelParams, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COMCERTSELPARAMSCREATEFAILED;
goto cleanup; } } while (0)
;
62
63 PKIX_CHECK(PKIX_ComCertSelParams_SetCertificatedo { stdVars.aPkixErrorResult = (PKIX_ComCertSelParams_SetCertificate
(certSelParams, signerCert, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED
; goto cleanup; } } while (0)
64 (certSelParams, signerCert, plContext),do { stdVars.aPkixErrorResult = (PKIX_ComCertSelParams_SetCertificate
(certSelParams, signerCert, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED
; goto cleanup; } } while (0)
65 PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED)do { stdVars.aPkixErrorResult = (PKIX_ComCertSelParams_SetCertificate
(certSelParams, signerCert, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED
; goto cleanup; } } while (0)
;
66
67 PKIX_CHECK(PKIX_CertSelector_SetCommonCertSelectorParamsdo { stdVars.aPkixErrorResult = (PKIX_CertSelector_SetCommonCertSelectorParams
(certSelector, certSelParams, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED
; goto cleanup; } } while (0)
68 (certSelector, certSelParams, plContext),do { stdVars.aPkixErrorResult = (PKIX_CertSelector_SetCommonCertSelectorParams
(certSelector, certSelParams, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED
; goto cleanup; } } while (0)
69 PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED)do { stdVars.aPkixErrorResult = (PKIX_CertSelector_SetCommonCertSelectorParams
(certSelector, certSelParams, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED
; goto cleanup; } } while (0)
;
70
71 PKIX_CHECK(PKIX_ProcessingParams_SetTargetCertConstraintsdo { stdVars.aPkixErrorResult = (PKIX_ProcessingParams_SetTargetCertConstraints
(caProcParams, certSelector, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED
; goto cleanup; } } while (0)
72 (caProcParams, certSelector, plContext),do { stdVars.aPkixErrorResult = (PKIX_ProcessingParams_SetTargetCertConstraints
(caProcParams, certSelector, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED
; goto cleanup; } } while (0)
73 PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED)do { stdVars.aPkixErrorResult = (PKIX_ProcessingParams_SetTargetCertConstraints
(caProcParams, certSelector, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED
; goto cleanup; } } while (0)
;
74 }
75
76 buildError = PKIX_BuildChain
77 (caProcParams,
78 &nbioContext,
79 pState,
80 pBuildResult,
81 pVerifyTree,
82 plContext);
83
84 /* non-null nbioContext means the build would block */
85 if (nbioContext != NULL((void*)0)) {
86
87 *pNBIOContext = nbioContext;
88
89 /* no buildResult means the build has failed */
90 } else if (buildError) {
91 pkixErrorResultstdVars.aPkixErrorResult = buildError;
92 buildError = NULL((void*)0);
93 } else {
94 PKIX_DECREF(*pState)do { if (*pState){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(*pState), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } *pState = ((void*)
0); } } while (0)
;
95 }
96
97cleanup:
98
99 PKIX_DECREF(caProcParams)do { if (caProcParams){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(caProcParams), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } caProcParams = ((void
*)0); } } while (0)
;
100 PKIX_DECREF(date)do { if (date){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(date), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } date = ((void*)0);
} } while (0)
;
101 PKIX_DECREF(certSelParams)do { if (certSelParams){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(certSelParams), plContext); if (stdVars.
aPkixTempResult) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult
, plContext); stdVars.aPkixTempResult = ((void*)0); } certSelParams
= ((void*)0); } } while (0)
;
102 PKIX_DECREF(certSelector)do { if (certSelector){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(certSelector), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } certSelector = ((void
*)0); } } while (0)
;
103
104 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
105}
106
107/* --Private-OcspResponse-Functions------------------------------------- */
108
109/*
110 * FUNCTION: pkix_pl_OcspResponse_Destroy
111 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
112 */
113static PKIX_Error *
114pkix_pl_OcspResponse_Destroy(
115 PKIX_PL_Object *object,
116 void *plContext)
117{
118 PKIX_PL_OcspResponse *ocspRsp = NULL((void*)0);
119 const SEC_HttpClientFcn *httpClient = NULL((void*)0);
120 const SEC_HttpClientFcnV1 *hcv1 = NULL((void*)0);
121
122 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Destroy")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_Destroy"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
123 PKIX_NULLCHECK_ONE(object)do { if ((object) == ((void*)0)){ stdVars.aPkixErrorReceived =
((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
124
125 PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE, plContext),do { stdVars.aPkixErrorResult = (pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTNOTANOCSPRESPONSE; goto cleanup; } } while (0)
126 PKIX_OBJECTNOTANOCSPRESPONSE)do { stdVars.aPkixErrorResult = (pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTNOTANOCSPRESPONSE; goto cleanup; } } while (0)
;
127
128 ocspRsp = (PKIX_PL_OcspResponse *)object;
129
130 if (ocspRsp->nssOCSPResponse != NULL((void*)0)) {
131 CERT_DestroyOCSPResponse(ocspRsp->nssOCSPResponse);
132 ocspRsp->nssOCSPResponse = NULL((void*)0);
133 }
134
135 if (ocspRsp->signerCert != NULL((void*)0)) {
136 CERT_DestroyCertificate(ocspRsp->signerCert);
137 ocspRsp->signerCert = NULL((void*)0);
138 }
139
140 httpClient = (const SEC_HttpClientFcn *)(ocspRsp->httpClient);
141
142 if (httpClient && (httpClient->version == 1)) {
143
144 hcv1 = &(httpClient->fcnTable.ftable1);
145
146 if (ocspRsp->sessionRequest != NULL((void*)0)) {
147 (*hcv1->freeFcn)(ocspRsp->sessionRequest);
148 ocspRsp->sessionRequest = NULL((void*)0);
149 }
150
151 if (ocspRsp->serverSession != NULL((void*)0)) {
152 (*hcv1->freeSessionFcn)(ocspRsp->serverSession);
153 ocspRsp->serverSession = NULL((void*)0);
154 }
155 }
156
157 if (ocspRsp->arena != NULL((void*)0)) {
158 PORT_FreeArenaPORT_FreeArena_Util(ocspRsp->arena, PR_FALSE0);
159 ocspRsp->arena = NULL((void*)0);
160 }
161
162 PKIX_DECREF(ocspRsp->producedAtDate)do { if (ocspRsp->producedAtDate){ stdVars.aPkixTempResult
= PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(ocspRsp->producedAtDate
), plContext); if (stdVars.aPkixTempResult) { PKIX_DoAddError
(&stdVars, stdVars.aPkixTempResult, plContext); stdVars.aPkixTempResult
= ((void*)0); } ocspRsp->producedAtDate = ((void*)0); } }
while (0)
;
163 PKIX_DECREF(ocspRsp->pkixSignerCert)do { if (ocspRsp->pkixSignerCert){ stdVars.aPkixTempResult
= PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(ocspRsp->pkixSignerCert
), plContext); if (stdVars.aPkixTempResult) { PKIX_DoAddError
(&stdVars, stdVars.aPkixTempResult, plContext); stdVars.aPkixTempResult
= ((void*)0); } ocspRsp->pkixSignerCert = ((void*)0); } }
while (0)
;
164 PKIX_DECREF(ocspRsp->request)do { if (ocspRsp->request){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(ocspRsp->request), plContext); if (stdVars
.aPkixTempResult) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult
, plContext); stdVars.aPkixTempResult = ((void*)0); } ocspRsp
->request = ((void*)0); } } while (0)
;
165
166cleanup:
167
168 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
169}
170
171/*
172 * FUNCTION: pkix_pl_OcspResponse_Hashcode
173 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
174 */
175static PKIX_Error *
176pkix_pl_OcspResponse_Hashcode(
177 PKIX_PL_Object *object,
178 PKIX_UInt32 *pHashcode,
179 void *plContext)
180{
181 PKIX_PL_OcspResponse *ocspRsp = NULL((void*)0);
182
183 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Hashcode")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_Hashcode"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
184 PKIX_NULLCHECK_TWO(object, pHashcode)do { if (((object) == ((void*)0)) || ((pHashcode) == ((void*)
0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(&
stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);;
} } while (0)
;
185
186 PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE, plContext),do { stdVars.aPkixErrorResult = (pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTNOTANOCSPRESPONSE; goto cleanup; } } while (0)
187 PKIX_OBJECTNOTANOCSPRESPONSE)do { stdVars.aPkixErrorResult = (pkix_CheckType(object, PKIX_OCSPRESPONSE_TYPE
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_OBJECTNOTANOCSPRESPONSE; goto cleanup; } } while (0)
;
188
189 ocspRsp = (PKIX_PL_OcspResponse *)object;
190
191 if (ocspRsp->encodedResponse->data == NULL((void*)0)) {
192 *pHashcode = 0;
193 } else {
194 PKIX_CHECK(pkix_hashdo { stdVars.aPkixErrorResult = (pkix_hash (ocspRsp->encodedResponse
->data, ocspRsp->encodedResponse->len, pHashcode, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_HASHFAILED; goto cleanup; } } while (0)
195 (ocspRsp->encodedResponse->data,do { stdVars.aPkixErrorResult = (pkix_hash (ocspRsp->encodedResponse
->data, ocspRsp->encodedResponse->len, pHashcode, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_HASHFAILED; goto cleanup; } } while (0)
196 ocspRsp->encodedResponse->len,do { stdVars.aPkixErrorResult = (pkix_hash (ocspRsp->encodedResponse
->data, ocspRsp->encodedResponse->len, pHashcode, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_HASHFAILED; goto cleanup; } } while (0)
197 pHashcode,do { stdVars.aPkixErrorResult = (pkix_hash (ocspRsp->encodedResponse
->data, ocspRsp->encodedResponse->len, pHashcode, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_HASHFAILED; goto cleanup; } } while (0)
198 plContext),do { stdVars.aPkixErrorResult = (pkix_hash (ocspRsp->encodedResponse
->data, ocspRsp->encodedResponse->len, pHashcode, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_HASHFAILED; goto cleanup; } } while (0)
199 PKIX_HASHFAILED)do { stdVars.aPkixErrorResult = (pkix_hash (ocspRsp->encodedResponse
->data, ocspRsp->encodedResponse->len, pHashcode, plContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_HASHFAILED; goto cleanup; } } while (0)
;
200 }
201
202cleanup:
203
204 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
205}
206
207/*
208 * FUNCTION: pkix_pl_OcspResponse_Equals
209 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
210 */
211static PKIX_Error *
212pkix_pl_OcspResponse_Equals(
213 PKIX_PL_Object *firstObj,
214 PKIX_PL_Object *secondObj,
215 PKIX_Boolean *pResult,
216 void *plContext)
217{
218 PKIX_UInt32 secondType = 0;
219 PKIX_UInt32 firstLen = 0;
220 PKIX_UInt32 i = 0;
221 PKIX_PL_OcspResponse *rsp1 = NULL((void*)0);
222 PKIX_PL_OcspResponse *rsp2 = NULL((void*)0);
223 const unsigned char *firstData = NULL((void*)0);
224 const unsigned char *secondData = NULL((void*)0);
225
226 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Equals")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_Equals"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
227 PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult)do { if (((firstObj) == ((void*)0)) || ((secondObj) == ((void
*)0)) || ((pResult) == ((void*)0))){ stdVars.aPkixErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
228
229 /* test that firstObj is a OcspResponse */
230 PKIX_CHECK(pkix_CheckType(firstObj, PKIX_OCSPRESPONSE_TYPE, plContext),do { stdVars.aPkixErrorResult = (pkix_CheckType(firstObj, PKIX_OCSPRESPONSE_TYPE
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_FIRSTOBJARGUMENTNOTANOCSPRESPONSE; goto cleanup; } } while
(0)
231 PKIX_FIRSTOBJARGUMENTNOTANOCSPRESPONSE)do { stdVars.aPkixErrorResult = (pkix_CheckType(firstObj, PKIX_OCSPRESPONSE_TYPE
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_FIRSTOBJARGUMENTNOTANOCSPRESPONSE; goto cleanup; } } while
(0)
;
232
233 /*
234 * Since we know firstObj is a OcspResponse, if both references are
235 * identical, they must be equal
236 */
237 if (firstObj == secondObj){
238 *pResult = PKIX_TRUE((PKIX_Boolean) 1);
239 goto cleanup;
240 }
241
242 /*
243 * If secondObj isn't a OcspResponse, we don't throw an error.
244 * We simply return a Boolean result of FALSE
245 */
246 *pResult = PKIX_FALSE((PKIX_Boolean) 0);
247 PKIX_CHECK(PKIX_PL_Object_GetType(secondObj, &secondType, plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_GetType(secondObj
, &secondType, plContext)); if (stdVars.aPkixErrorResult)
{ stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
; goto cleanup; } } while (0)
248 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT)do { stdVars.aPkixErrorResult = (PKIX_PL_Object_GetType(secondObj
, &secondType, plContext)); if (stdVars.aPkixErrorResult)
{ stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
; goto cleanup; } } while (0)
;
249 if (secondType != PKIX_OCSPRESPONSE_TYPE) {
250 goto cleanup;
251 }
252
253 rsp1 = (PKIX_PL_OcspResponse *)firstObj;
254 rsp2 = (PKIX_PL_OcspResponse *)secondObj;
255
256 /* If either lacks an encoded string, they cannot be compared */
257 firstData = (const unsigned char *)rsp1->encodedResponse->data;
258 secondData = (const unsigned char *)rsp2->encodedResponse->data;
259 if ((firstData == NULL((void*)0)) || (secondData == NULL((void*)0))) {
260 goto cleanup;
261 }
262
263 firstLen = rsp1->encodedResponse->len;
264
265 if (firstLen != rsp2->encodedResponse->len) {
266 goto cleanup;
267 }
268
269 for (i = 0; i < firstLen; i++) {
270 if (*firstData++ != *secondData++) {
271 goto cleanup;
272 }
273 }
274
275 *pResult = PKIX_TRUE((PKIX_Boolean) 1);
276
277cleanup:
278
279 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
280}
281
282/*
283 * FUNCTION: pkix_pl_OcspResponse_RegisterSelf
284 * DESCRIPTION:
285 * Registers PKIX_OCSPRESPONSE_TYPE and its related functions with
286 * systemClasses[]
287 * PARAMETERS:
288 * "plContext"
289 * Platform-specific context pointer.
290 * THREAD SAFETY:
291 * Not Thread Safe - for performance and complexity reasons
292 *
293 * Since this function is only called by PKIX_PL_Initialize, which should
294 * only be called once, it is acceptable that this function is not
295 * thread-safe.
296 */
297PKIX_Error *
298pkix_pl_OcspResponse_RegisterSelf(void *plContext)
299{
300 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
301 pkix_ClassTable_Entry *entry = &systemClasses[PKIX_OCSPRESPONSE_TYPE];
302
303 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_RegisterSelf")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_RegisterSelf"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
304
305 entry->description = "OcspResponse";
306 entry->typeObjectSize = sizeof(PKIX_PL_OcspResponse);
307 entry->destructor = pkix_pl_OcspResponse_Destroy;
308 entry->equalsFunction = pkix_pl_OcspResponse_Equals;
309 entry->hashcodeFunction = pkix_pl_OcspResponse_Hashcode;
310 entry->duplicateFunction = pkix_duplicateImmutable;
311
312 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
313}
314
315/* --Public-Functions------------------------------------------------------- */
316
317/*
318 * FUNCTION: pkix_pl_OcspResponse_Create
319 * DESCRIPTION:
320 *
321 * This function transmits the OcspRequest pointed to by "request" and obtains
322 * an OcspResponse, which it stores at "pOcspResponse". If the HTTPClient
323 * supports non-blocking I/O this function may store a non-NULL value at
324 * "pNBIOContext" (the WOULDBLOCK condition). In that case the caller should
325 * make a subsequent call with the same value in "pNBIOContext" and
326 * "pOcspResponse" to resume the operation. Additional WOULDBLOCK returns may
327 * occur; the caller should persist until a return occurs with NULL stored at
328 * "pNBIOContext".
329 *
330 * If a SEC_HttpClientFcn "responder" is supplied, it is used as the client
331 * to which the OCSP query is sent. If none is supplied, the default responder
332 * is used.
333 *
334 * If an OcspResponse_VerifyCallback "verifyFcn" is supplied, it is used to
335 * verify the Cert received from the responder as the signer. If none is
336 * supplied, the default verification function is used.
337 *
338 * The contents of "request" are ignored on calls subsequent to a WOULDBLOCK
339 * return, and the caller is permitted to supply NULL.
340 *
341 * PARAMETERS
342 * "request"
343 * Address of the OcspRequest for which a response is desired.
344 * "httpMethod"
345 * GET or POST
346 * "responder"
347 * Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP
348 * query.
349 * "verifyFcn"
350 * Address, if non-NULL, of the OcspResponse_VerifyCallback function to be
351 * used to verify the Cert of the OCSP responder.
352 * "pNBIOContext"
353 * Address at which platform-dependent information is stored for handling
354 * of non-blocking I/O. Must be non-NULL.
355 * "pOcspResponse"
356 * The address where the created OcspResponse is stored. Must be non-NULL.
357 * "plContext"
358 * Platform-specific context pointer.
359 * THREAD SAFETY:
360 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
361 * RETURNS:
362 * Returns NULL if the function succeeds.
363 * Returns an OcspResponse Error if the function fails in a non-fatal way.
364 * Returns a Fatal Error if the function fails in an unrecoverable way.
365 */
366PKIX_Error *
367pkix_pl_OcspResponse_Create(
368 PKIX_PL_OcspRequest *request,
369 const char *httpMethod,
370 void *responder,
371 PKIX_PL_VerifyCallback verifyFcn,
372 void **pNBIOContext,
373 PKIX_PL_OcspResponse **pResponse,
374 void *plContext)
375{
376 void *nbioContext = NULL((void*)0);
377 PKIX_PL_OcspResponse *ocspResponse = NULL((void*)0);
378 const SEC_HttpClientFcn *httpClient = NULL((void*)0);
379 const SEC_HttpClientFcnV1 *hcv1 = NULL((void*)0);
380 SECStatus rv = SECFailure;
381 char *location = NULL((void*)0);
382 char *hostname = NULL((void*)0);
383 char *path = NULL((void*)0);
384 char *responseContentType = NULL((void*)0);
385 PRUint16 port = 0;
386 SEC_HTTP_SERVER_SESSION serverSession = NULL((void*)0);
387 SEC_HTTP_REQUEST_SESSION sessionRequest = NULL((void*)0);
388 SECItem *encodedRequest = NULL((void*)0);
389 PRUint16 responseCode = 0;
390 char *responseData = NULL((void*)0);
391
392 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_Create"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
393 PKIX_NULLCHECK_TWO(pNBIOContext, pResponse)do { if (((pNBIOContext) == ((void*)0)) || ((pResponse) == ((
void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(&
stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);;
} } while (0)
;
394
395 if (!strcmp(httpMethod, "GET") && !strcmp(httpMethod, "POST")) {
396 PKIX_ERROR(PKIX_INVALIDOCSPHTTPMETHOD){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_INVALIDOCSPHTTPMETHOD, ((void*)0), stdVars.aPkixType, 2
, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean
) 1); stdVars.aPkixErrorCode = PKIX_INVALIDOCSPHTTPMETHOD; goto
cleanup; }
;
397 }
398
399 nbioContext = *pNBIOContext;
400 *pNBIOContext = NULL((void*)0);
401
402 if (nbioContext != NULL((void*)0)) {
403
404 ocspResponse = *pResponse;
405 PKIX_NULLCHECK_ONE(ocspResponse)do { if ((ocspResponse) == ((void*)0)){ stdVars.aPkixErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
406
407 httpClient = ocspResponse->httpClient;
408 serverSession = ocspResponse->serverSession;
409 sessionRequest = ocspResponse->sessionRequest;
410 PKIX_NULLCHECK_THREE(httpClient, serverSession, sessionRequest)do { if (((httpClient) == ((void*)0)) || ((serverSession) == (
(void*)0)) || ((sessionRequest) == ((void*)0))){ stdVars.aPkixErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
411
412 } else {
413 PKIX_UInt32 timeout =
414 ((PKIX_PL_NssContext*)plContext)->timeoutSeconds;
415
416 PKIX_NULLCHECK_ONE(request)do { if ((request) == ((void*)0)){ stdVars.aPkixErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
417
418 PKIX_CHECK(pkix_pl_OcspRequest_GetEncodeddo { stdVars.aPkixErrorResult = (pkix_pl_OcspRequest_GetEncoded
(request, &encodedRequest, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_OCSPREQUESTGETENCODEDFAILED; goto
cleanup; } } while (0)
419 (request, &encodedRequest, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_OcspRequest_GetEncoded
(request, &encodedRequest, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_OCSPREQUESTGETENCODEDFAILED; goto
cleanup; } } while (0)
420 PKIX_OCSPREQUESTGETENCODEDFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_OcspRequest_GetEncoded
(request, &encodedRequest, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_OCSPREQUESTGETENCODEDFAILED; goto
cleanup; } } while (0)
;
421
422 /* prepare initial message to HTTPClient */
423
424 /* Is there a default responder and is it enabled? */
425 if (responder) {
426 httpClient = (const SEC_HttpClientFcn *)responder;
427 } else {
428 httpClient = SEC_GetRegisteredHttpClient();
429 }
430
431 if (httpClient && (httpClient->version == 1)) {
432 char *fullGetPath = NULL((void*)0);
433 const char *sessionPath = NULL((void*)0);
434 PRBool usePOST = !strcmp(httpMethod, "POST");
435
436 hcv1 = &(httpClient->fcnTable.ftable1);
437
438 PKIX_CHECK(pkix_pl_OcspRequest_GetLocationdo { stdVars.aPkixErrorResult = (pkix_pl_OcspRequest_GetLocation
(request, &location, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_OCSPREQUESTGETLOCATIONFAILED;
goto cleanup; } } while (0)
439 (request, &location, plContext),do { stdVars.aPkixErrorResult = (pkix_pl_OcspRequest_GetLocation
(request, &location, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_OCSPREQUESTGETLOCATIONFAILED;
goto cleanup; } } while (0)
440 PKIX_OCSPREQUESTGETLOCATIONFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_OcspRequest_GetLocation
(request, &location, plContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_OCSPREQUESTGETLOCATIONFAILED;
goto cleanup; } } while (0)
;
441
442 /* parse location -> hostname, port, path */
443 rv = CERT_ParseURL(location, &hostname, &port, &path);
444 if (rv == SECFailure || hostname == NULL((void*)0) || path == NULL((void*)0)) {
445 PKIX_ERROR(PKIX_URLPARSINGFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_URLPARSINGFAILED, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_URLPARSINGFAILED; goto cleanup; }
;
446 }
447
448 rv = (*hcv1->createSessionFcn)(hostname, port,
449 &serverSession);
450 if (rv != SECSuccess) {
451 PKIX_ERROR(PKIX_OCSPSERVERERROR){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OCSPSERVERERROR, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OCSPSERVERERROR; goto cleanup; }
;
452 }
453
454 if (usePOST) {
455 sessionPath = path;
456 } else {
457 /* calculate, are we allowed to use GET? */
458 enum { max_get_request_size = 255 }; /* defined by RFC2560 */
459 char b64ReqBuf[max_get_request_size+1];
460 size_t base64size;
461 size_t slashLengthIfNeeded = 0;
462 size_t pathLength;
463 PRInt32 urlEncodedBufLength;
464 size_t getURLLength;
465 char *walkOutput = NULL((void*)0);
466
467 pathLength = strlen(path);
468 if (path[pathLength-1] != '/') {
469 slashLengthIfNeeded = 1;
470 }
471 base64size = (((encodedRequest->len +2)/3) * 4);
472 if (base64size > max_get_request_size) {
473 PKIX_ERROR(PKIX_OCSPGETREQUESTTOOBIG){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OCSPGETREQUESTTOOBIG, ((void*)0), stdVars.aPkixType, 2
, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean
) 1); stdVars.aPkixErrorCode = PKIX_OCSPGETREQUESTTOOBIG; goto
cleanup; }
;
474 }
475 memset(b64ReqBuf, 0, sizeof(b64ReqBuf));
476 PL_Base64Encode((const char *)encodedRequest->data, encodedRequest->len, b64ReqBuf);
477 urlEncodedBufLength = ocsp_UrlEncodeBase64Buf(b64ReqBuf, NULL((void*)0));
478 getURLLength = pathLength + urlEncodedBufLength + slashLengthIfNeeded;
479 fullGetPath = (char*)PORT_AllocPORT_Alloc_Util(getURLLength);
480 if (!fullGetPath) {
481 PKIX_ERROR(PKIX_OUTOFMEMORY){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OUTOFMEMORY, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OUTOFMEMORY; goto cleanup; }
;
482 }
483 strcpy(fullGetPath, path);
484 walkOutput = fullGetPath + pathLength;
485 if (walkOutput > fullGetPath && slashLengthIfNeeded) {
486 strcpy(walkOutput, "/");
487 ++walkOutput;
488 }
489 ocsp_UrlEncodeBase64Buf(b64ReqBuf, walkOutput);
490 sessionPath = fullGetPath;
491 }
492
493 rv = (*hcv1->createFcn)(serverSession, "http",
494 sessionPath, httpMethod,
495 PR_SecondsToInterval(timeout),
496 &sessionRequest);
497 sessionPath = NULL((void*)0);
498 if (fullGetPath) {
499 PORT_FreePORT_Free_Util(fullGetPath);
500 fullGetPath = NULL((void*)0);
501 }
502
503 if (rv != SECSuccess) {
504 PKIX_ERROR(PKIX_OCSPSERVERERROR){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OCSPSERVERERROR, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OCSPSERVERERROR; goto cleanup; }
;
505 }
506
507 if (usePOST) {
508 rv = (*hcv1->setPostDataFcn)(sessionRequest,
509 (char *)encodedRequest->data,
510 encodedRequest->len,
511 "application/ocsp-request");
512 if (rv != SECSuccess) {
513 PKIX_ERROR(PKIX_OCSPSERVERERROR){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OCSPSERVERERROR, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OCSPSERVERERROR; goto cleanup; }
;
514 }
515 }
516
517 /* create a PKIX_PL_OcspResponse object */
518 PKIX_CHECK(PKIX_PL_Object_Allocdo { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE
, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_COULDNOTCREATEOBJECT; goto cleanup; } } while (0)
519 (PKIX_OCSPRESPONSE_TYPE,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE
, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_COULDNOTCREATEOBJECT; goto cleanup; } } while (0)
520 sizeof (PKIX_PL_OcspResponse),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE
, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_COULDNOTCREATEOBJECT; goto cleanup; } } while (0)
521 (PKIX_PL_Object **)&ocspResponse,do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE
, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_COULDNOTCREATEOBJECT; goto cleanup; } } while (0)
522 plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE
, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_COULDNOTCREATEOBJECT; goto cleanup; } } while (0)
523 PKIX_COULDNOTCREATEOBJECT)do { stdVars.aPkixErrorResult = (PKIX_PL_Object_Alloc (PKIX_OCSPRESPONSE_TYPE
, sizeof (PKIX_PL_OcspResponse), (PKIX_PL_Object **)&ocspResponse
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_COULDNOTCREATEOBJECT; goto cleanup; } } while (0)
;
524
525 PKIX_INCREF(request)do { if (request){ stdVars.aPkixTempResult = PKIX_PL_Object_IncRef
((PKIX_PL_Object *)(request), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); goto cleanup; } } } while
(0)
;
526 ocspResponse->request = request;
527 ocspResponse->httpClient = httpClient;
528 ocspResponse->serverSession = serverSession;
529 serverSession = NULL((void*)0);
530 ocspResponse->sessionRequest = sessionRequest;
531 sessionRequest = NULL((void*)0);
532 ocspResponse->verifyFcn = verifyFcn;
533 ocspResponse->handle = CERT_GetDefaultCertDB();
534 ocspResponse->encodedResponse = NULL((void*)0);
535 ocspResponse->arena = NULL((void*)0);
536 ocspResponse->producedAt = 0;
537 ocspResponse->producedAtDate = NULL((void*)0);
538 ocspResponse->pkixSignerCert = NULL((void*)0);
539 ocspResponse->nssOCSPResponse = NULL((void*)0);
540 ocspResponse->signerCert = NULL((void*)0);
541 }
542 }
543
544 /* begin or resume IO to HTTPClient */
545 if (httpClient && (httpClient->version == 1)) {
546 PRUint32 responseDataLen =
547 ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
548
549 hcv1 = &(httpClient->fcnTable.ftable1);
550
551 rv = (*hcv1->trySendAndReceiveFcn)(ocspResponse->sessionRequest,
552 (PRPollDesc **)&nbioContext,
553 &responseCode,
554 (const char **)&responseContentType,
555 NULL((void*)0), /* responseHeaders */
556 (const char **)&responseData,
557 &responseDataLen);
558
559 if (rv != SECSuccess) {
560 PKIX_ERROR(PKIX_OCSPSERVERERROR){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OCSPSERVERERROR, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OCSPSERVERERROR; goto cleanup; }
;
561 }
562 /* responseContentType is a pointer to the null-terminated
563 * string returned by httpclient. Memory allocated for context
564 * type will be freed with freeing of the HttpClient struct. */
565 if (PORT_StrcasecmpPL_strcasecmp(responseContentType,
566 "application/ocsp-response")) {
567 PKIX_ERROR(PKIX_OCSPSERVERERROR){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OCSPSERVERERROR, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OCSPSERVERERROR; goto cleanup; }
;
568 }
569 if (nbioContext != NULL((void*)0)) {
570 *pNBIOContext = nbioContext;
571 goto cleanup;
572 }
573 if (responseCode != 200) {
574 PKIX_ERROR(PKIX_OCSPBADHTTPRESPONSE){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OCSPBADHTTPRESPONSE, ((void*)0), stdVars.aPkixType, 2,
plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean)
1); stdVars.aPkixErrorCode = PKIX_OCSPBADHTTPRESPONSE; goto cleanup
; }
;
575 }
576 ocspResponse->arena = PORT_NewArenaPORT_NewArena_Util(DER_DEFAULT_CHUNKSIZE(2048));
577 if (ocspResponse->arena == NULL((void*)0)) {
578 PKIX_ERROR(PKIX_OUTOFMEMORY){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OUTOFMEMORY, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OUTOFMEMORY; goto cleanup; }
;
579 }
580 ocspResponse->encodedResponse = SECITEM_AllocItemSECITEM_AllocItem_Util
581 (ocspResponse->arena, NULL((void*)0), responseDataLen);
582 if (ocspResponse->encodedResponse == NULL((void*)0)) {
583 PKIX_ERROR(PKIX_OUTOFMEMORY){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_OUTOFMEMORY, ((void*)0), stdVars.aPkixType, 2, plContext
); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_OUTOFMEMORY; goto cleanup; }
;
584 }
585 PORT_Memcpymemcpy(ocspResponse->encodedResponse->data,
586 responseData, responseDataLen);
587 }
588 *pResponse = ocspResponse;
589 ocspResponse = NULL((void*)0);
590
591cleanup:
592
593 if (path != NULL((void*)0)) {
594 PORT_FreePORT_Free_Util(path);
595 }
596 if (hostname != NULL((void*)0)) {
597 PORT_FreePORT_Free_Util(hostname);
598 }
599 if (ocspResponse) {
600 PKIX_DECREF(ocspResponse)do { if (ocspResponse){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(ocspResponse), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } ocspResponse = ((void
*)0); } } while (0)
;
601 }
602 if (serverSession) {
603 hcv1->freeSessionFcn(serverSession);
604 }
605 if (sessionRequest) {
606 hcv1->freeFcn(sessionRequest);
607 }
608
609 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
610}
611
612/*
613 * FUNCTION: pkix_pl_OcspResponse_Decode
614 * DESCRIPTION:
615 *
616 * This function decodes the DER data contained in the OcspResponse pointed to
617 * by "response", storing PKIX_TRUE at "pPassed" if the decoding was
618 * successful, and PKIX_FALSE otherwise.
619 *
620 * PARAMETERS
621 * "response"
622 * The address of the OcspResponse whose DER data is to be decoded. Must
623 * be non-NULL.
624 * "pPassed"
625 * Address at which the Boolean result is stored. Must be non-NULL.
626 * "pReturnCode"
627 * Address at which the SECErrorCodes result is stored. Must be non-NULL.
628 * "plContext"
629 * Platform-specific context pointer.
630 * THREAD SAFETY:
631 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
632 * RETURNS:
633 * Returns NULL if the function succeeds.
634 * Returns an OcspResponse Error if the function fails in a non-fatal way.
635 * Returns a Fatal Error if the function fails in an unrecoverable way.
636 */
637
638PKIX_Error *
639pkix_pl_OcspResponse_Decode(
640 PKIX_PL_OcspResponse *response,
641 PKIX_Boolean *pPassed,
642 SECErrorCodes *pReturnCode,
643 void *plContext)
644{
645
646 PKIX_ENTER(OCSPRESPONSE, "PKIX_PL_OcspResponse_Decode")static const char cMyFuncName[] = {"PKIX_PL_OcspResponse_Decode"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
647 PKIX_NULLCHECK_TWO(response, response->encodedResponse)do { if (((response) == ((void*)0)) || ((response->encodedResponse
) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean
) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn
(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext
);; } } while (0)
;
648
649 response->nssOCSPResponse =
650 CERT_DecodeOCSPResponse(response->encodedResponse);
651
652 if (response->nssOCSPResponse != NULL((void*)0)) {
653 *pPassed = PKIX_TRUE((PKIX_Boolean) 1);
654 *pReturnCode = 0;
655 } else {
656 *pPassed = PKIX_FALSE((PKIX_Boolean) 0);
657 *pReturnCode = PORT_GetErrorPORT_GetError_Util();
658 }
659
660 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
661}
662
663/*
664 * FUNCTION: pkix_pl_OcspResponse_GetStatus
665 * DESCRIPTION:
666 *
667 * This function checks the response status of the OcspResponse pointed to
668 * by "response", storing PKIX_TRUE at "pPassed" if the responder understood
669 * the request and considered it valid, and PKIX_FALSE otherwise.
670 *
671 * PARAMETERS
672 * "response"
673 * The address of the OcspResponse whose status is to be retrieved. Must
674 * be non-NULL.
675 * "pPassed"
676 * Address at which the Boolean result is stored. Must be non-NULL.
677 * "plContext"
678 * Platform-specific context pointer.
679 * THREAD SAFETY:
680 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
681 * RETURNS:
682 * Returns NULL if the function succeeds.
683 * Returns an OcspResponse Error if the function fails in a non-fatal way.
684 * Returns a Fatal Error if the function fails in an unrecoverable way.
685 */
686
687PKIX_Error *
688pkix_pl_OcspResponse_GetStatus(
689 PKIX_PL_OcspResponse *response,
690 PKIX_Boolean *pPassed,
691 SECErrorCodes *pReturnCode,
692 void *plContext)
693{
694 SECStatus rv = SECFailure;
695
696 PKIX_ENTER(OCSPRESPONSE, "PKIX_PL_OcspResponse_GetStatus")static const char cMyFuncName[] = {"PKIX_PL_OcspResponse_GetStatus"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
697 PKIX_NULLCHECK_FOUR(response, response->nssOCSPResponse, pPassed, pReturnCode)do { if (((response) == ((void*)0)) || ((response->nssOCSPResponse
) == ((void*)0)) || ((pPassed) == ((void*)0)) || ((pReturnCode
) == ((void*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean
) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn
(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext
);; } } while (0)
;
698
699 rv = CERT_GetOCSPResponseStatus(response->nssOCSPResponse);
700
701 if (rv == SECSuccess) {
702 *pPassed = PKIX_TRUE((PKIX_Boolean) 1);
703 *pReturnCode = 0;
704 } else {
705 *pPassed = PKIX_FALSE((PKIX_Boolean) 0);
706 *pReturnCode = PORT_GetErrorPORT_GetError_Util();
707 }
708
709 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
710}
711
712
713static PKIX_Error*
714pkix_pl_OcspResponse_VerifyResponse(
715 PKIX_PL_OcspResponse *response,
716 PKIX_ProcessingParams *procParams,
717 SECCertUsage certUsage,
718 void **state,
719 PKIX_BuildResult **buildResult,
720 void **pNBIOContext,
721 void *plContext)
722{
723 SECStatus rv = SECFailure;
724
725 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_VerifyResponse")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_VerifyResponse"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
726
727 if (response->verifyFcn != NULL((void*)0)) {
728 void *lplContext = NULL((void*)0);
729
730 PKIX_CHECK(do { stdVars.aPkixErrorResult = (PKIX_PL_NssContext_Create(((
SECCertificateUsage)1) << certUsage, ((PKIX_Boolean) 0)
, ((void*)0), &lplContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_NSSCONTEXTCREATEFAILED; goto cleanup
; } } while (0)
731 PKIX_PL_NssContext_Create(((SECCertificateUsage)1) << certUsage,do { stdVars.aPkixErrorResult = (PKIX_PL_NssContext_Create(((
SECCertificateUsage)1) << certUsage, ((PKIX_Boolean) 0)
, ((void*)0), &lplContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_NSSCONTEXTCREATEFAILED; goto cleanup
; } } while (0)
732 PKIX_FALSE, NULL, &lplContext),do { stdVars.aPkixErrorResult = (PKIX_PL_NssContext_Create(((
SECCertificateUsage)1) << certUsage, ((PKIX_Boolean) 0)
, ((void*)0), &lplContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_NSSCONTEXTCREATEFAILED; goto cleanup
; } } while (0)
733 PKIX_NSSCONTEXTCREATEFAILED)do { stdVars.aPkixErrorResult = (PKIX_PL_NssContext_Create(((
SECCertificateUsage)1) << certUsage, ((PKIX_Boolean) 0)
, ((void*)0), &lplContext)); if (stdVars.aPkixErrorResult
) { stdVars.aPkixErrorClass = stdVars.aPkixErrorResult->errClass
; stdVars.aPkixErrorCode = PKIX_NSSCONTEXTCREATEFAILED; goto cleanup
; } } while (0)
;
734
735 PKIX_CHECK(do { stdVars.aPkixErrorResult = ((response->verifyFcn)((PKIX_PL_Object
*)response->pkixSignerCert, ((void*)0), response->producedAtDate
, procParams, pNBIOContext, state, buildResult, ((void*)0), lplContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTVERIFYKEYUSAGEFAILED; goto cleanup; } } while (0)
736 (response->verifyFcn)((PKIX_PL_Object*)response->pkixSignerCert,do { stdVars.aPkixErrorResult = ((response->verifyFcn)((PKIX_PL_Object
*)response->pkixSignerCert, ((void*)0), response->producedAtDate
, procParams, pNBIOContext, state, buildResult, ((void*)0), lplContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTVERIFYKEYUSAGEFAILED; goto cleanup; } } while (0)
737 NULL, response->producedAtDate,do { stdVars.aPkixErrorResult = ((response->verifyFcn)((PKIX_PL_Object
*)response->pkixSignerCert, ((void*)0), response->producedAtDate
, procParams, pNBIOContext, state, buildResult, ((void*)0), lplContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTVERIFYKEYUSAGEFAILED; goto cleanup; } } while (0)
738 procParams, pNBIOContext,do { stdVars.aPkixErrorResult = ((response->verifyFcn)((PKIX_PL_Object
*)response->pkixSignerCert, ((void*)0), response->producedAtDate
, procParams, pNBIOContext, state, buildResult, ((void*)0), lplContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTVERIFYKEYUSAGEFAILED; goto cleanup; } } while (0)
739 state, buildResult,do { stdVars.aPkixErrorResult = ((response->verifyFcn)((PKIX_PL_Object
*)response->pkixSignerCert, ((void*)0), response->producedAtDate
, procParams, pNBIOContext, state, buildResult, ((void*)0), lplContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTVERIFYKEYUSAGEFAILED; goto cleanup; } } while (0)
740 NULL, lplContext),do { stdVars.aPkixErrorResult = ((response->verifyFcn)((PKIX_PL_Object
*)response->pkixSignerCert, ((void*)0), response->producedAtDate
, procParams, pNBIOContext, state, buildResult, ((void*)0), lplContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTVERIFYKEYUSAGEFAILED; goto cleanup; } } while (0)
741 PKIX_CERTVERIFYKEYUSAGEFAILED)do { stdVars.aPkixErrorResult = ((response->verifyFcn)((PKIX_PL_Object
*)response->pkixSignerCert, ((void*)0), response->producedAtDate
, procParams, pNBIOContext, state, buildResult, ((void*)0), lplContext
)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass =
stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTVERIFYKEYUSAGEFAILED; goto cleanup; } } while (0)
;
742 rv = SECSuccess;
743 } else {
744 /* checkSig is !isRoot */
745 PRBool checkSig = response->signerCert->isRoot ? PR_FALSE0 : PR_TRUE1;
746 rv = CERT_VerifyCert(response->handle, response->signerCert, checkSig,
747 certUsage, response->producedAt, NULL((void*)0), NULL((void*)0));
748 if (rv != SECSuccess) {
749 PKIX_ERROR(PKIX_CERTVERIFYKEYUSAGEFAILED){ { if (pkixLoggersErrors) { pkix_Logger_CheckWithCode(pkixLoggersErrors
, PKIX_CERTVERIFYKEYUSAGEFAILED, ((void*)0), stdVars.aPkixType
, 2, plContext); } } stdVars.aPkixErrorReceived = ((PKIX_Boolean
) 1); stdVars.aPkixErrorCode = PKIX_CERTVERIFYKEYUSAGEFAILED;
goto cleanup; }
;
750 }
751 }
752
753cleanup:
754 if (rv != SECSuccess) {
755 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
756 }
757
758 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
759}
760
761/*
762 * FUNCTION: pkix_pl_OcspResponse_VerifySignature
763 * DESCRIPTION:
764 *
765 * This function verifies the ocspResponse signature field in the OcspResponse
766 * pointed to by "response", storing PKIX_TRUE at "pPassed" if verification
767 * is successful and PKIX_FALSE otherwise. If verification is unsuccessful an
768 * error code (an enumeration of type SECErrorCodes) is stored at *pReturnCode.
769 *
770 * PARAMETERS
771 * "response"
772 * The address of the OcspResponse whose signature field is to be
773 * retrieved. Must be non-NULL.
774 * "cert"
775 * The address of the Cert for which the OCSP query was made. Must be
776 * non-NULL.
777 * "procParams"
778 * Address of ProcessingParams used to initialize the ExpirationChecker
779 * and TargetCertChecker. Must be non-NULL.
780 * "pPassed"
781 * Address at which the Boolean result is stored. Must be non-NULL.
782 * "pNBIOContext"
783 * Address at which the NBIOContext is stored indicating whether the
784 * checking is complete. Must be non-NULL.
785 * "plContext"
786 * Platform-specific context pointer.
787 * THREAD SAFETY:
788 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
789 * RETURNS:
790 * Returns NULL if the function succeeds.
791 * Returns an OcspResponse Error if the function fails in a non-fatal way.
792 * Returns a Fatal Error if the function fails in an unrecoverable way.
793 */
794PKIX_Error *
795pkix_pl_OcspResponse_VerifySignature(
796 PKIX_PL_OcspResponse *response,
797 PKIX_PL_Cert *cert,
798 PKIX_ProcessingParams *procParams,
799 PKIX_Boolean *pPassed,
800 void **pNBIOContext,
801 void *plContext)
802{
803 SECStatus rv = SECFailure;
804 CERTOCSPResponse *nssOCSPResponse = NULL((void*)0);
805 CERTCertificate *issuerCert = NULL((void*)0);
806 PKIX_BuildResult *buildResult = NULL((void*)0);
807 void *nbio = NULL((void*)0);
808 void *state = NULL((void*)0);
809
810 ocspSignature *signature = NULL((void*)0);
811 ocspResponseData *tbsData = NULL((void*)0);
812 SECItem *tbsResponseDataDER = NULL((void*)0);
813
814
815 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_VerifySignature")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_VerifySignature"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
816 PKIX_NULLCHECK_FOUR(response, cert, pPassed, pNBIOContext)do { if (((response) == ((void*)0)) || ((cert) == ((void*)0))
|| ((pPassed) == ((void*)0)) || ((pNBIOContext) == ((void*)0
))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(&
stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);;
} } while (0)
;
817
818 nbio = *pNBIOContext;
819 *pNBIOContext = NULL((void*)0);
820
821 nssOCSPResponse = response->nssOCSPResponse;
822 if (nssOCSPResponse == NULL((void*)0)) {
823 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
824 goto cleanup;
825 }
826
827 tbsData =
828 ocsp_GetResponseData(nssOCSPResponse, &tbsResponseDataDER);
829
830 signature = ocsp_GetResponseSignature(nssOCSPResponse);
831
832
833 /* Are we resuming after a WOULDBLOCK response? */
834 if (nbio == NULL((void*)0)) {
835 /* No, this is a new query */
836
837 issuerCert = CERT_FindCertIssuer(cert->nssCert, PR_Now(),
838 certUsageAnyCA);
839
840 /*
841 * If this signature has already gone through verification,
842 * just return the cached result.
843 */
844 if (signature->wasChecked) {
845 if (signature->status == SECSuccess) {
846 response->signerCert =
847 CERT_DupCertificate(signature->cert);
848 } else {
849 PORT_SetErrorPORT_SetError_Util(signature->failureReason);
850 goto cleanup;
851 }
852 }
853
854 response->signerCert =
855 ocsp_GetSignerCertificate(response->handle, tbsData,
856 signature, issuerCert);
857
858 if (response->signerCert == NULL((void*)0)) {
859 if (PORT_GetErrorPORT_GetError_Util() == SEC_ERROR_UNKNOWN_CERT) {
860 /* Make the error a little more specific. */
861 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
862 }
863 goto cleanup;
864 }
865 PKIX_CHECK(do { stdVars.aPkixErrorResult = (PKIX_PL_Cert_CreateFromCERTCertificate
(response->signerCert, &(response->pkixSignerCert),
plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTCREATEWITHNSSCERTFAILED; goto cleanup; } } while (
0)
866 PKIX_PL_Cert_CreateFromCERTCertificate(response->signerCert,do { stdVars.aPkixErrorResult = (PKIX_PL_Cert_CreateFromCERTCertificate
(response->signerCert, &(response->pkixSignerCert),
plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTCREATEWITHNSSCERTFAILED; goto cleanup; } } while (
0)
867 &(response->pkixSignerCert),do { stdVars.aPkixErrorResult = (PKIX_PL_Cert_CreateFromCERTCertificate
(response->signerCert, &(response->pkixSignerCert),
plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTCREATEWITHNSSCERTFAILED; goto cleanup; } } while (
0)
868 plContext),do { stdVars.aPkixErrorResult = (PKIX_PL_Cert_CreateFromCERTCertificate
(response->signerCert, &(response->pkixSignerCert),
plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTCREATEWITHNSSCERTFAILED; goto cleanup; } } while (
0)
869 PKIX_CERTCREATEWITHNSSCERTFAILED)do { stdVars.aPkixErrorResult = (PKIX_PL_Cert_CreateFromCERTCertificate
(response->signerCert, &(response->pkixSignerCert),
plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_CERTCREATEWITHNSSCERTFAILED; goto cleanup; } } while (
0)
;
870
871 /*
872 * We could mark this true at the top of this function, or
873 * always below at "finish", but if the problem was just that
874 * we could not find the signer's cert, leave that as if the
875 * signature hasn't been checked. Maybe a subsequent call will
876 * have better luck.
877 */
878 signature->wasChecked = PR_TRUE1;
879
880 /*
881 * We are about to verify the signer certificate; we need to
882 * specify *when* that certificate must be valid -- for our
883 * purposes we expect it to be valid when the response was
884 * signed. The value of "producedAt" is the signing time.
885 */
886 rv = DER_GeneralizedTimeToTimeDER_GeneralizedTimeToTime_Util(&response->producedAt,
887 &tbsData->producedAt);
888 if (rv != SECSuccess) {
889 PORT_SetErrorPORT_SetError_Util(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
890 goto cleanup;
891 }
892
893 /*
894 * We need producedAtDate and pkixSignerCert if we are calling a
895 * user-supplied verification function. Let's put their
896 * creation before the code that gets repeated when
897 * non-blocking I/O is used.
898 */
899
900 PKIX_CHECK(do { stdVars.aPkixErrorResult = (pkix_pl_Date_CreateFromPRTime
((PRTime)response->producedAt, &(response->producedAtDate
), plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_DATECREATEFROMPRTIMEFAILED; goto cleanup; } } while (
0)
901 pkix_pl_Date_CreateFromPRTime((PRTime)response->producedAt,do { stdVars.aPkixErrorResult = (pkix_pl_Date_CreateFromPRTime
((PRTime)response->producedAt, &(response->producedAtDate
), plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_DATECREATEFROMPRTIMEFAILED; goto cleanup; } } while (
0)
902 &(response->producedAtDate),do { stdVars.aPkixErrorResult = (pkix_pl_Date_CreateFromPRTime
((PRTime)response->producedAt, &(response->producedAtDate
), plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_DATECREATEFROMPRTIMEFAILED; goto cleanup; } } while (
0)
903 plContext),do { stdVars.aPkixErrorResult = (pkix_pl_Date_CreateFromPRTime
((PRTime)response->producedAt, &(response->producedAtDate
), plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_DATECREATEFROMPRTIMEFAILED; goto cleanup; } } while (
0)
904 PKIX_DATECREATEFROMPRTIMEFAILED)do { stdVars.aPkixErrorResult = (pkix_pl_Date_CreateFromPRTime
((PRTime)response->producedAt, &(response->producedAtDate
), plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixErrorClass
= stdVars.aPkixErrorResult->errClass; stdVars.aPkixErrorCode
= PKIX_DATECREATEFROMPRTIMEFAILED; goto cleanup; } } while (
0)
;
905
906 }
907
908 /*
909 * Just because we have a cert does not mean it is any good; check
910 * it for validity, trust and usage. Use the caller-supplied
911 * verification function, if one was supplied.
912 */
913 if (ocsp_CertIsOCSPDefaultResponder(response->handle,
914 response->signerCert)) {
915 rv = SECSuccess;
Value stored to 'rv' is never read
916 } else {
917 SECCertUsage certUsage;
918 if (CERT_IsCACert(response->signerCert, NULL((void*)0))) {
919 certUsage = certUsageAnyCA;
920 } else {
921 certUsage = certUsageStatusResponder;
922 }
923 PKIX_CHECK_ONLY_FATAL(do { stdVars.aPkixTempErrorReceived = ((PKIX_Boolean) 0); stdVars
.aPkixErrorResult = (pkix_pl_OcspResponse_VerifyResponse(response
, procParams, certUsage, &state, &buildResult, &nbio
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixTempErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; if (stdVars.aPkixErrorClass == PKIX_FATAL_ERROR
) { goto cleanup; } do { if (stdVars.aPkixErrorResult){ stdVars
.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(
stdVars.aPkixErrorResult), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } stdVars.aPkixErrorResult
= ((void*)0); } } while (0); } } while (0)
924 pkix_pl_OcspResponse_VerifyResponse(response, procParams,do { stdVars.aPkixTempErrorReceived = ((PKIX_Boolean) 0); stdVars
.aPkixErrorResult = (pkix_pl_OcspResponse_VerifyResponse(response
, procParams, certUsage, &state, &buildResult, &nbio
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixTempErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; if (stdVars.aPkixErrorClass == PKIX_FATAL_ERROR
) { goto cleanup; } do { if (stdVars.aPkixErrorResult){ stdVars
.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(
stdVars.aPkixErrorResult), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } stdVars.aPkixErrorResult
= ((void*)0); } } while (0); } } while (0)
925 certUsage, &state,do { stdVars.aPkixTempErrorReceived = ((PKIX_Boolean) 0); stdVars
.aPkixErrorResult = (pkix_pl_OcspResponse_VerifyResponse(response
, procParams, certUsage, &state, &buildResult, &nbio
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixTempErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; if (stdVars.aPkixErrorClass == PKIX_FATAL_ERROR
) { goto cleanup; } do { if (stdVars.aPkixErrorResult){ stdVars
.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(
stdVars.aPkixErrorResult), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } stdVars.aPkixErrorResult
= ((void*)0); } } while (0); } } while (0)
926 &buildResult, &nbio,do { stdVars.aPkixTempErrorReceived = ((PKIX_Boolean) 0); stdVars
.aPkixErrorResult = (pkix_pl_OcspResponse_VerifyResponse(response
, procParams, certUsage, &state, &buildResult, &nbio
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixTempErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; if (stdVars.aPkixErrorClass == PKIX_FATAL_ERROR
) { goto cleanup; } do { if (stdVars.aPkixErrorResult){ stdVars
.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(
stdVars.aPkixErrorResult), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } stdVars.aPkixErrorResult
= ((void*)0); } } while (0); } } while (0)
927 plContext),do { stdVars.aPkixTempErrorReceived = ((PKIX_Boolean) 0); stdVars
.aPkixErrorResult = (pkix_pl_OcspResponse_VerifyResponse(response
, procParams, certUsage, &state, &buildResult, &nbio
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixTempErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; if (stdVars.aPkixErrorClass == PKIX_FATAL_ERROR
) { goto cleanup; } do { if (stdVars.aPkixErrorResult){ stdVars
.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(
stdVars.aPkixErrorResult), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } stdVars.aPkixErrorResult
= ((void*)0); } } while (0); } } while (0)
928 PKIX_CERTVERIFYKEYUSAGEFAILED)do { stdVars.aPkixTempErrorReceived = ((PKIX_Boolean) 0); stdVars
.aPkixErrorResult = (pkix_pl_OcspResponse_VerifyResponse(response
, procParams, certUsage, &state, &buildResult, &nbio
, plContext)); if (stdVars.aPkixErrorResult) { stdVars.aPkixTempErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorClass = stdVars.aPkixErrorResult
->errClass; if (stdVars.aPkixErrorClass == PKIX_FATAL_ERROR
) { goto cleanup; } do { if (stdVars.aPkixErrorResult){ stdVars
.aPkixTempResult = PKIX_PL_Object_DecRef ((PKIX_PL_Object *)(
stdVars.aPkixErrorResult), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } stdVars.aPkixErrorResult
= ((void*)0); } } while (0); } } while (0)
;
929 if (pkixTempErrorReceivedstdVars.aPkixTempErrorReceived) {
930 rv = SECFailure;
931 goto cleanup;
932 }
933 if (nbio != NULL((void*)0)) {
934 *pNBIOContext = nbio;
935 goto cleanup;
936 }
937 }
938
939 rv = ocsp_VerifyResponseSignature(response->signerCert, signature,
940 tbsResponseDataDER, NULL((void*)0));
941
942cleanup:
943 if (rv == SECSuccess) {
944 *pPassed = PKIX_TRUE((PKIX_Boolean) 1);
945 } else {
946 *pPassed = PKIX_FALSE((PKIX_Boolean) 0);
947 }
948
949 if (signature) {
950 if (signature->wasChecked) {
951 signature->status = rv;
952 }
953
954 if (rv != SECSuccess) {
955 signature->failureReason = PORT_GetErrorPORT_GetError_Util();
956 if (response->signerCert != NULL((void*)0)) {
957 CERT_DestroyCertificate(response->signerCert);
958 response->signerCert = NULL((void*)0);
959 }
960 } else {
961 /* Save signer's certificate in signature. */
962 signature->cert = CERT_DupCertificate(response->signerCert);
963 }
964 }
965
966 if (issuerCert)
967 CERT_DestroyCertificate(issuerCert);
968
969 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
970}
971
972/*
973 * FUNCTION: pkix_pl_OcspResponse_GetStatusForCert
974 * DESCRIPTION:
975 *
976 * This function checks the revocation status of the Cert for which the
977 * OcspResponse was obtained, storing PKIX_TRUE at "pPassed" if the Cert has
978 * not been revoked and PKIX_FALSE otherwise.
979 *
980 * PARAMETERS
981 * "response"
982 * The address of the OcspResponse whose certificate status is to be
983 * retrieved. Must be non-NULL.
984 * "pPassed"
985 * Address at which the Boolean result is stored. Must be non-NULL.
986 * "pReturnCode"
987 * Address at which the SECErrorCodes result is stored. Must be non-NULL.
988 * "plContext"
989 * Platform-specific context pointer.
990 * THREAD SAFETY:
991 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
992 * RETURNS:
993 * Returns NULL if the function succeeds.
994 * Returns an OcspResponse Error if the function fails in a non-fatal way.
995 * Returns a Fatal Error if the function fails in an unrecoverable way.
996 */
997PKIX_Error *
998pkix_pl_OcspResponse_GetStatusForCert(
999 PKIX_PL_OcspCertID *cid,
1000 PKIX_PL_OcspResponse *response,
1001 PKIX_Boolean allowCachingOfFailures,
1002 PKIX_PL_Date *validity,
1003 PKIX_Boolean *pPassed,
1004 SECErrorCodes *pReturnCode,
1005 void *plContext)
1006{
1007 PRTime time = 0;
1008 SECStatus rv = SECFailure;
1009 CERTOCSPSingleResponse *single = NULL((void*)0);
1010
1011 PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_GetStatusForCert")static const char cMyFuncName[] = {"pkix_pl_OcspResponse_GetStatusForCert"
}; PKIX_StdVars stdVars = zeroStdVars; stdVars.aMyFuncName = cMyFuncName
; stdVars.aPkixType = PKIX_OCSPRESPONSE_ERROR; ; do { if (pkixLoggersDebugTrace
) { pkix_Logger_Check(pkixLoggersDebugTrace, stdVars.aMyFuncName
, ">>>", stdVars.aPkixType, 5, plContext); } } while
(0);
;
1012 PKIX_NULLCHECK_THREE(response, pPassed, pReturnCode)do { if (((response) == ((void*)0)) || ((pPassed) == ((void*)
0)) || ((pReturnCode) == ((void*)0))){ stdVars.aPkixErrorReceived
= ((PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
1013
1014 /*
1015 * It is an error to call this function except following a successful
1016 * return from pkix_pl_OcspResponse_VerifySignature, which would have
1017 * set response->signerCert.
1018 */
1019 PKIX_NULLCHECK_TWO(response->signerCert, response->request)do { if (((response->signerCert) == ((void*)0)) || ((response
->request) == ((void*)0))){ stdVars.aPkixErrorReceived = (
(PKIX_Boolean) 1); stdVars.aPkixErrorCode = PKIX_NULLARGUMENT
; return PKIX_DoReturn(&stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean
) 1), plContext);; } } while (0)
;
1020 PKIX_NULLCHECK_TWO(cid, cid->certID)do { if (((cid) == ((void*)0)) || ((cid->certID) == ((void
*)0))){ stdVars.aPkixErrorReceived = ((PKIX_Boolean) 1); stdVars
.aPkixErrorCode = PKIX_NULLARGUMENT; return PKIX_DoReturn(&
stdVars, (PKIX_FATAL_ERROR), ((PKIX_Boolean) 1), plContext);;
} } while (0)
;
1021
1022 if (validity != NULL((void*)0)) {
1023 PKIX_Error *er = pkix_pl_Date_GetPRTime(validity, &time, plContext);
1024 PKIX_DECREF(er)do { if (er){ stdVars.aPkixTempResult = PKIX_PL_Object_DecRef
((PKIX_PL_Object *)(er), plContext); if (stdVars.aPkixTempResult
) { PKIX_DoAddError(&stdVars, stdVars.aPkixTempResult, plContext
); stdVars.aPkixTempResult = ((void*)0); } er = ((void*)0); }
} while (0)
;
1025 }
1026 if (!time) {
1027 time = PR_Now();
1028 }
1029
1030 rv = ocsp_GetVerifiedSingleResponseForCertID(response->handle,
1031 response->nssOCSPResponse,
1032 cid->certID,
1033 response->signerCert,
1034 time, &single);
1035 if (rv == SECSuccess) {
1036 /*
1037 * Check whether the status says revoked, and if so
1038 * how that compares to the time value passed into this routine.
1039 */
1040 rv = ocsp_CertHasGoodStatus(single->certStatus, time);
1041 }
1042
1043 if (rv == SECSuccess || allowCachingOfFailures) {
1044 /* allowed to update the cache */
1045 PRBool certIDWasConsumed = PR_FALSE0;
1046
1047 if (single) {
1048 ocsp_CacheSingleResponse(cid->certID,single,
1049 &certIDWasConsumed);
1050 } else {
1051 cert_RememberOCSPProcessingFailure(cid->certID,
1052 &certIDWasConsumed);
1053 }
1054
1055 if (certIDWasConsumed) {
1056 cid->certID = NULL((void*)0);
1057 }
1058 }
1059
1060 if (rv == SECSuccess) {
1061 *pPassed = PKIX_TRUE((PKIX_Boolean) 1);
1062 *pReturnCode = 0;
1063 } else {
1064 *pPassed = PKIX_FALSE((PKIX_Boolean) 0);
1065 *pReturnCode = PORT_GetErrorPORT_GetError_Util();
1066 }
1067
1068 PKIX_RETURN(OCSPRESPONSE)return PKIX_DoReturn(&stdVars, (PKIX_OCSPRESPONSE_ERROR),
((PKIX_Boolean) 1), plContext);
;
1069}