Imported Upstream version 3.15.4
[platform/upstream/nss.git] / nss / lib / libpkix / pkix_pl_nss / pki / pkix_pl_ocspcertid.c
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5  * pkix_pl_ocspcertid.c
6  *
7  * Certificate ID Object for OCSP
8  *
9  */
10
11 #include "pkix_pl_ocspcertid.h"
12
13 /* --Private-Cert-Functions------------------------------------- */
14
15 /*
16  * FUNCTION: pkix_pl_OcspCertID_Destroy
17  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
18  */
19 static PKIX_Error *
20 pkix_pl_OcspCertID_Destroy(
21         PKIX_PL_Object *object,
22         void *plContext)
23 {
24         PKIX_PL_OcspCertID *certID = NULL;
25
26         PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_Destroy");
27
28         PKIX_NULLCHECK_ONE(object);
29
30         PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPCERTID_TYPE, plContext),
31                     PKIX_OBJECTNOTOCSPCERTID);
32
33         certID = (PKIX_PL_OcspCertID *)object;
34
35         if (certID->certID) {
36                 CERT_DestroyOCSPCertID(certID->certID);
37         }
38
39 cleanup:
40
41         PKIX_RETURN(OCSPCERTID);
42 }
43
44 /*
45  * FUNCTION: pkix_pl_OcspCertID_RegisterSelf
46  * DESCRIPTION:
47  *  Registers PKIX_PUBLICKEY_TYPE and its related functions 
48  *  with systemClasses[]
49  * THREAD SAFETY:
50  *  Not Thread Safe - for performance and complexity reasons
51  *
52  *  Since this function is only called by PKIX_PL_Initialize, which should
53  *  only be called once, it is acceptable that this function is not
54  *  thread-safe.
55  */
56 PKIX_Error *
57 pkix_pl_OcspCertID_RegisterSelf(void *plContext)
58 {
59         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
60         pkix_ClassTable_Entry entry;
61
62         PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_RegisterSelf");
63
64         entry.description = "OcspCertID";
65         entry.objCounter = 0;
66         entry.typeObjectSize = sizeof(PKIX_PL_OcspCertID);
67         entry.destructor = pkix_pl_OcspCertID_Destroy;
68         entry.equalsFunction = NULL;
69         entry.hashcodeFunction = NULL;
70         entry.toStringFunction = NULL;
71         entry.comparator = NULL;
72         entry.duplicateFunction = pkix_duplicateImmutable;
73         systemClasses[PKIX_OCSPCERTID_TYPE] = entry;
74
75         PKIX_RETURN(OCSPCERTID);
76 }
77
78 /* --Public-Functions------------------------------------------------------- */
79
80 /*
81  * FUNCTION: PKIX_PL_OcspCertID_Create
82  * DESCRIPTION:
83  *
84  *  This function creates an OcspCertID for a given certificate,
85  *  to be used with OCSP transactions.
86  *
87  *  If a Date is provided in "validity" it may be used in the search for the
88  *  issuer of "cert" but has no effect on the request itself.
89  *
90  * PARAMETERS:
91  *  "cert"
92  *     Address of the Cert for which an OcspCertID is to be created. Must be
93  *     non-NULL.
94  *  "validity"
95  *     Address of the Date for which the Cert's validity is to be determined.
96  *     May be NULL.
97  *  "object"
98  *     Address at which the result is stored. Must be non-NULL.
99  *  "plContext"
100  *      Platform-specific context pointer.
101  * THREAD SAFETY:
102  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
103  * RETURNS:
104  *  Returns NULL if the function succeeds.
105  *  Returns an OcspCertID Error if the function fails in a non-fatal way.
106  *  Returns a Fatal Error if the function fails in an unrecoverable way.
107  */
108 PKIX_Error *
109 PKIX_PL_OcspCertID_Create(
110         PKIX_PL_Cert *cert,
111         PKIX_PL_Date *validity,
112         PKIX_PL_OcspCertID **object,
113         void *plContext)
114 {
115         PKIX_PL_OcspCertID *cid = NULL;
116         PRTime time = 0;
117
118         PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_Create");
119         PKIX_NULLCHECK_TWO(cert, object);
120     
121         PKIX_CHECK(PKIX_PL_Object_Alloc
122                     (PKIX_OCSPCERTID_TYPE,
123                     sizeof (PKIX_PL_OcspCertID),
124                     (PKIX_PL_Object **)&cid,
125                     plContext),
126                     PKIX_COULDNOTCREATEOBJECT);
127
128         if (validity != NULL) {
129                 PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
130                         PKIX_DATEGETPRTIMEFAILED);
131         } else {
132                 time = PR_Now();
133         }
134
135         cid->certID = CERT_CreateOCSPCertID(cert->nssCert, time);
136         if (!cid->certID) {
137                 PKIX_ERROR(PKIX_COULDNOTCREATEOBJECT);
138         }
139
140         *object = cid;
141         cid = NULL;
142 cleanup:
143         PKIX_DECREF(cid);
144         PKIX_RETURN(OCSPCERTID);
145 }
146
147 /*
148  * FUNCTION: PKIX_PL_OcspCertID_GetFreshCacheStatus
149  * DESCRIPTION:
150  *
151  *  This function may return cached OCSP results for the provided
152  *  certificate, but only if stored information is still considered to be
153  *  fresh.
154  *
155  * PARAMETERS
156  *  "cid"
157  *      A certificate ID as used by OCSP
158  *  "validity"
159  *      Optional date parameter to request validity for a specifc time.
160  *  "hasFreshStatus"
161  *      Output parameter, if the function successed to find fresh cached
162  *      information, this will be set to true. Must be non-NULL.
163  *  "statusIsGood"
164  *      The good/bad result stored in the cache. Must be non-NULL.
165  *  "missingResponseError"
166  *      If OCSP status is "bad", this variable may indicate the exact
167  *      reason why the previous OCSP request had failed.
168  *  "plContext"
169  *      Platform-specific context pointer.
170  * RETURNS:
171  *  Returns NULL if the function succeeds.
172  *  Returns an OcspCertID Error if the function fails in a non-fatal way.
173  *  Returns a Fatal Error if the function fails in an unrecoverable way.
174  */
175 PKIX_Error *
176 PKIX_PL_OcspCertID_GetFreshCacheStatus(
177         PKIX_PL_OcspCertID *cid, 
178         PKIX_PL_Date *validity,
179         PKIX_Boolean *hasFreshStatus,
180         PKIX_Boolean *statusIsGood,
181         SECErrorCodes *missingResponseError,
182         void *plContext)
183 {
184         PRTime time = 0;
185         SECStatus rv;
186         SECStatus rvOcsp;
187         OCSPFreshness freshness;
188
189         PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_GetFreshCacheStatus");
190         PKIX_NULLCHECK_THREE(cid, hasFreshStatus, statusIsGood);
191
192         if (validity != NULL) {
193                 PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
194                         PKIX_DATEGETPRTIMEFAILED);
195         } else {
196                 time = PR_Now();
197         }
198
199         rv = ocsp_GetCachedOCSPResponseStatus(
200                 cid->certID, time, PR_TRUE, /*ignoreGlobalOcspFailureSetting*/
201                 &rvOcsp, missingResponseError, &freshness);
202
203         *hasFreshStatus = (rv == SECSuccess && freshness == ocspFresh);
204         if (*hasFreshStatus) {
205                 *statusIsGood = (rvOcsp == SECSuccess);
206         }
207 cleanup:
208         PKIX_RETURN(OCSPCERTID);
209 }
210
211 /*
212  * FUNCTION: PKIX_PL_OcspCertID_RememberOCSPProcessingFailure
213  * DESCRIPTION:
214  *
215  *  Information about the current failure associated to the given certID
216  *  will be remembered in the cache, potentially allowing future calls
217  *  to prevent repetitive OCSP requests.
218  *  After this function got called, it may no longer be safe to
219  *  use the provided cid parameter, because ownership might have been
220  *  transfered to the cache. This status will be recorded inside the
221  *  cid object.
222  *
223  * PARAMETERS
224  *  "cid"
225  *      The certificate ID associated to a failed OCSP processing.
226  *  "plContext"
227  *      Platform-specific context pointer.
228  * RETURNS:
229  *  Returns NULL if the function succeeds.
230  *  Returns an OcspCertID Error if the function fails in a non-fatal way.
231  *  Returns a Fatal Error if the function fails in an unrecoverable way.
232  */
233 PKIX_Error *
234 PKIX_PL_OcspCertID_RememberOCSPProcessingFailure(
235         PKIX_PL_OcspCertID *cid, 
236         void *plContext)
237 {
238         PRBool certIDWasConsumed = PR_FALSE;
239
240         PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_RememberOCSPProcessingFailure");
241         PKIX_NULLCHECK_TWO(cid, cid->certID);
242
243         cert_RememberOCSPProcessingFailure(cid->certID, &certIDWasConsumed);
244
245         if (certIDWasConsumed) {
246                 cid->certID = NULL;
247         }
248
249         PKIX_RETURN(OCSPCERTID);
250 }
251