File: | s/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c |
Warning: | line 603, column 13 Access to field 'freeSessionFcn' results in a dereference of a null pointer (loaded from variable 'hcv1') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | */ | |||
16 | PKIX_Error * | |||
17 | PKIX_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 | ||||
97 | cleanup: | |||
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 | */ | |||
113 | static PKIX_Error * | |||
114 | pkix_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 | ||||
166 | cleanup: | |||
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 | */ | |||
175 | static PKIX_Error * | |||
176 | pkix_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 | ||||
202 | cleanup: | |||
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 | */ | |||
211 | static PKIX_Error * | |||
212 | pkix_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 | ||||
277 | cleanup: | |||
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 | */ | |||
297 | PKIX_Error * | |||
298 | pkix_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 | */ | |||
366 | PKIX_Error * | |||
367 | pkix_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
| |||
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 | ||||
591 | cleanup: | |||
592 | ||||
593 | if (path
| |||
594 | PORT_FreePORT_Free_Util(path); | |||
595 | } | |||
596 | if (hostname
| |||
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 | ||||
638 | PKIX_Error * | |||
639 | pkix_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 | ||||
687 | PKIX_Error * | |||
688 | pkix_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 | ||||
713 | static PKIX_Error* | |||
714 | pkix_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 | ||||
753 | cleanup: | |||
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 | */ | |||
794 | PKIX_Error * | |||
795 | pkix_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; | |||
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 | ||||
942 | cleanup: | |||
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 | */ | |||
997 | PKIX_Error * | |||
998 | pkix_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 | } |