| 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 | } |