Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: nss/lib/certhigh/ocsp.c

Issue 1843333003: Update NSPR to 4.12 and NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 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 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/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 /* 5 /*
6 * Implementation of OCSP services, for both client and server. 6 * Implementation of OCSP services, for both client and server.
7 * (XXX, really, mostly just for client right now, but intended to do both.) 7 * (XXX, really, mostly just for client right now, but intended to do both.)
8 */ 8 */
9 9
10 #include "prerror.h" 10 #include "prerror.h"
(...skipping 15 matching lines...) Expand all
26 #include "sechash.h" 26 #include "sechash.h"
27 #include "secasn1.h" 27 #include "secasn1.h"
28 #include "plbase64.h" 28 #include "plbase64.h"
29 #include "keyhi.h" 29 #include "keyhi.h"
30 #include "cryptohi.h" 30 #include "cryptohi.h"
31 #include "ocsp.h" 31 #include "ocsp.h"
32 #include "ocspti.h" 32 #include "ocspti.h"
33 #include "ocspi.h" 33 #include "ocspi.h"
34 #include "genname.h" 34 #include "genname.h"
35 #include "certxutl.h" 35 #include "certxutl.h"
36 #include "pk11func.h"» /* for PK11_HashBuf */ 36 #include "pk11func.h" /* for PK11_HashBuf */
37 #include <stdarg.h> 37 #include <stdarg.h>
38 #include <plhash.h> 38 #include <plhash.h>
39 39
40 #define DEFAULT_OCSP_CACHE_SIZE 1000 40 #define DEFAULT_OCSP_CACHE_SIZE 1000
41 #define DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 1*60*60L 41 #define DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 1 * 60 * 60L
42 #define DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 24*60*60L 42 #define DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT 24 * 60 * 60L
43 #define DEFAULT_OSCP_TIMEOUT_SECONDS 60 43 #define DEFAULT_OSCP_TIMEOUT_SECONDS 60
44 #define MICROSECONDS_PER_SECOND 1000000L 44 #define MICROSECONDS_PER_SECOND 1000000L
45 45
46 typedef struct OCSPCacheItemStr OCSPCacheItem; 46 typedef struct OCSPCacheItemStr OCSPCacheItem;
47 typedef struct OCSPCacheDataStr OCSPCacheData; 47 typedef struct OCSPCacheDataStr OCSPCacheData;
48 48
49 struct OCSPCacheItemStr { 49 struct OCSPCacheItemStr {
50 /* LRU linking */ 50 /* LRU linking */
51 OCSPCacheItem *moreRecent; 51 OCSPCacheItem *moreRecent;
52 OCSPCacheItem *lessRecent; 52 OCSPCacheItem *lessRecent;
(...skipping 29 matching lines...) Expand all
82 PRMonitor *monitor; 82 PRMonitor *monitor;
83 const SEC_HttpClientFcn *defaultHttpClientFcn; 83 const SEC_HttpClientFcn *defaultHttpClientFcn;
84 PRInt32 maxCacheEntries; 84 PRInt32 maxCacheEntries;
85 PRUint32 minimumSecondsToNextFetchAttempt; 85 PRUint32 minimumSecondsToNextFetchAttempt;
86 PRUint32 maximumSecondsToNextFetchAttempt; 86 PRUint32 maximumSecondsToNextFetchAttempt;
87 PRUint32 timeoutSeconds; 87 PRUint32 timeoutSeconds;
88 OCSPCacheData cache; 88 OCSPCacheData cache;
89 SEC_OcspFailureMode ocspFailureMode; 89 SEC_OcspFailureMode ocspFailureMode;
90 CERT_StringFromCertFcn alternateOCSPAIAFcn; 90 CERT_StringFromCertFcn alternateOCSPAIAFcn;
91 PRBool forcePost; 91 PRBool forcePost;
92 } OCSP_Global = { NULL, 92 } OCSP_Global = { NULL,
93 NULL, 93 NULL,
94 DEFAULT_OCSP_CACHE_SIZE, 94 DEFAULT_OCSP_CACHE_SIZE,
95 DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT, 95 DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
96 DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT, 96 DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
97 DEFAULT_OSCP_TIMEOUT_SECONDS, 97 DEFAULT_OSCP_TIMEOUT_SECONDS,
98 {NULL, 0, NULL, NULL}, 98 { NULL, 0, NULL, NULL },
99 ocspMode_FailureIsVerificationFailure, 99 ocspMode_FailureIsVerificationFailure,
100 NULL, 100 NULL,
101 PR_FALSE 101 PR_FALSE };
102 };
103
104
105 102
106 /* Forward declarations */ 103 /* Forward declarations */
107 static SECItem * 104 static SECItem *
108 ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena, 105 ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
109 CERTOCSPRequest *request, 106 CERTOCSPRequest *request,
110 const char *location, 107 const char *location,
111 » » » » const char *method, 108 const char *method,
112 » » » » PRTime time, 109 PRTime time,
113 PRBool addServiceLocator, 110 PRBool addServiceLocator,
114 void *pwArg, 111 void *pwArg,
115 CERTOCSPRequest **pRequest); 112 CERTOCSPRequest **pRequest);
116 static SECStatus 113 static SECStatus
117 ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, 114 ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
118 CERTOCSPCertID *certID, 115 CERTOCSPCertID *certID,
119 CERTCertificate *cert, 116 CERTCertificate *cert,
120 PRTime time, 117 PRTime time,
121 void *pwArg, 118 void *pwArg,
122 PRBool *certIDWasConsumed, 119 PRBool *certIDWasConsumed,
123 SECStatus *rv_ocsp); 120 SECStatus *rv_ocsp);
124 121
125 static SECStatus 122 static SECStatus
126 ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle, 123 ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
127 » » » » » CERTOCSPCertID *certID, 124 CERTOCSPCertID *certID,
128 » » » » » CERTCertificate *cert, 125 CERTCertificate *cert,
129 » » » » » PRTime time, 126 PRTime time,
130 » » » » » void *pwArg, 127 void *pwArg,
131 » » » » » const SECItem *encodedResponse, 128 const SECItem *encodedResponse,
132 » » » » » CERTOCSPResponse **pDecodedResponse, 129 CERTOCSPResponse **pDecodedResponse,
133 » » » » » CERTOCSPSingleResponse **pSingle); 130 CERTOCSPSingleResponse **pSingle);
134 131
135 static SECStatus 132 static SECStatus
136 ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time); 133 ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time);
137 134
138 static CERTOCSPCertID * 135 static CERTOCSPCertID *
139 cert_DupOCSPCertID(const CERTOCSPCertID *src); 136 cert_DupOCSPCertID(const CERTOCSPCertID *src);
140 137
141 #ifndef DEBUG 138 #ifndef DEBUG
142 #define OCSP_TRACE(msg) 139 #define OCSP_TRACE(msg)
143 #define OCSP_TRACE_TIME(msg, time) 140 #define OCSP_TRACE_TIME(msg, time)
144 #define OCSP_TRACE_CERT(cert) 141 #define OCSP_TRACE_CERT(cert)
145 #define OCSP_TRACE_CERTID(certid) 142 #define OCSP_TRACE_CERTID(certid)
146 #else 143 #else
147 #define OCSP_TRACE(msg) ocsp_Trace msg 144 #define OCSP_TRACE(msg) ocsp_Trace msg
148 #define OCSP_TRACE_TIME(msg, time) ocsp_dumpStringWithTime(msg, time) 145 #define OCSP_TRACE_TIME(msg, time) ocsp_dumpStringWithTime(msg, time)
149 #define OCSP_TRACE_CERT(cert) dumpCertificate(cert) 146 #define OCSP_TRACE_CERT(cert) dumpCertificate(cert)
150 #define OCSP_TRACE_CERTID(certid) dumpCertID(certid) 147 #define OCSP_TRACE_CERTID(certid) dumpCertID(certid)
151 148
152 #if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS) \ 149 #if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS) || \
153 || defined(XP_MACOSX) 150 defined(XP_MACOSX)
154 #define NSS_HAVE_GETENV 1 151 #define NSS_HAVE_GETENV 1
155 #endif 152 #endif
156 153
157 static PRBool wantOcspTrace(void) 154 static PRBool
155 wantOcspTrace(void)
158 { 156 {
159 static PRBool firstTime = PR_TRUE; 157 static PRBool firstTime = PR_TRUE;
160 static PRBool wantTrace = PR_FALSE; 158 static PRBool wantTrace = PR_FALSE;
161 159
162 #ifdef NSS_HAVE_GETENV 160 #ifdef NSS_HAVE_GETENV
163 if (firstTime) { 161 if (firstTime) {
164 char *ev = getenv("NSS_TRACE_OCSP"); 162 char *ev = PR_GetEnvSecure("NSS_TRACE_OCSP");
165 if (ev && ev[0]) { 163 if (ev && ev[0]) {
166 wantTrace = PR_TRUE; 164 wantTrace = PR_TRUE;
167 } 165 }
168 firstTime = PR_FALSE; 166 firstTime = PR_FALSE;
169 } 167 }
170 #endif 168 #endif
171 return wantTrace; 169 return wantTrace;
172 } 170 }
173 171
174 static void 172 static void
175 ocsp_Trace(const char *format, ...) 173 ocsp_Trace(const char *format, ...)
176 { 174 {
177 char buf[2000]; 175 char buf[2000];
178 va_list args; 176 va_list args;
179 177
180 if (!wantOcspTrace()) 178 if (!wantOcspTrace())
181 return; 179 return;
182 va_start(args, format); 180 va_start(args, format);
183 PR_vsnprintf(buf, sizeof(buf), format, args); 181 PR_vsnprintf(buf, sizeof(buf), format, args);
184 va_end(args); 182 va_end(args);
185 PR_LogPrint("%s", buf); 183 PR_LogPrint("%s", buf);
186 } 184 }
187 185
188 static void 186 static void
189 ocsp_dumpStringWithTime(const char *str, PRTime time) 187 ocsp_dumpStringWithTime(const char *str, PRTime time)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 ocsp_Trace("OCSP ## SUBJECT: %s\n", cert->subjectName); 226 ocsp_Trace("OCSP ## SUBJECT: %s\n", cert->subjectName);
229 { 227 {
230 PRTime timeBefore, timeAfter; 228 PRTime timeBefore, timeAfter;
231 PRExplodedTime beforePrintable, afterPrintable; 229 PRExplodedTime beforePrintable, afterPrintable;
232 char beforestr[256], afterstr[256]; 230 char beforestr[256], afterstr[256];
233 PRStatus rv1, rv2; 231 PRStatus rv1, rv2;
234 DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore); 232 DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
235 DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter); 233 DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
236 PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable); 234 PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable);
237 PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable); 235 PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable);
238 rv1 = PR_FormatTime(beforestr, 256, "%a %b %d %H:%M:%S %Y", 236 rv1 = PR_FormatTime(beforestr, 256, "%a %b %d %H:%M:%S %Y",
239 &beforePrintable); 237 &beforePrintable);
240 rv2 = PR_FormatTime(afterstr, 256, "%a %b %d %H:%M:%S %Y", 238 rv2 = PR_FormatTime(afterstr, 256, "%a %b %d %H:%M:%S %Y",
241 &afterPrintable); 239 &afterPrintable);
242 ocsp_Trace("OCSP ## VALIDITY: %s to %s\n", rv1 ? beforestr : "", 240 ocsp_Trace("OCSP ## VALIDITY: %s to %s\n", rv1 ? beforestr : "",
243 rv2 ? afterstr : ""); 241 rv2 ? afterstr : "");
244 } 242 }
245 ocsp_Trace("OCSP ## ISSUER: %s\n", cert->issuerName); 243 ocsp_Trace("OCSP ## ISSUER: %s\n", cert->issuerName);
246 printHexString("OCSP ## SERIAL NUMBER:", &cert->serialNumber); 244 printHexString("OCSP ## SERIAL NUMBER:", &cert->serialNumber);
247 } 245 }
248 246
249 static void 247 static void
250 dumpCertID(CERTOCSPCertID *certID) 248 dumpCertID(CERTOCSPCertID *certID)
251 { 249 {
252 if (!wantOcspTrace()) 250 if (!wantOcspTrace())
253 return; 251 return;
254 252
255 printHexString("OCSP certID issuer", &certID->issuerNameHash); 253 printHexString("OCSP certID issuer", &certID->issuerNameHash);
256 printHexString("OCSP certID serial", &certID->serialNumber); 254 printHexString("OCSP certID serial", &certID->serialNumber);
257 } 255 }
258 #endif 256 #endif
259 257
260 SECStatus 258 SECStatus
261 SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable) 259 SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable)
262 { 260 {
263 if (!OCSP_Global.monitor) { 261 if (!OCSP_Global.monitor) {
264 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 262 PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
265 return SECFailure; 263 return SECFailure;
266 } 264 }
267 265
268 PR_EnterMonitor(OCSP_Global.monitor); 266 PR_EnterMonitor(OCSP_Global.monitor);
269 OCSP_Global.defaultHttpClientFcn = fcnTable; 267 OCSP_Global.defaultHttpClientFcn = fcnTable;
270 PR_ExitMonitor(OCSP_Global.monitor); 268 PR_ExitMonitor(OCSP_Global.monitor);
271 269
272 return SECSuccess; 270 return SECSuccess;
273 } 271 }
274 272
275 SECStatus 273 SECStatus
276 CERT_RegisterAlternateOCSPAIAInfoCallBack( 274 CERT_RegisterAlternateOCSPAIAInfoCallBack(
277 » » » CERT_StringFromCertFcn newCallback, 275 CERT_StringFromCertFcn newCallback,
278 » » » CERT_StringFromCertFcn * oldCallback) 276 CERT_StringFromCertFcn *oldCallback)
279 { 277 {
280 CERT_StringFromCertFcn old; 278 CERT_StringFromCertFcn old;
281 279
282 if (!OCSP_Global.monitor) { 280 if (!OCSP_Global.monitor) {
283 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 281 PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
284 return SECFailure; 282 return SECFailure;
285 } 283 }
286 284
287 PR_EnterMonitor(OCSP_Global.monitor); 285 PR_EnterMonitor(OCSP_Global.monitor);
288 old = OCSP_Global.alternateOCSPAIAFcn; 286 old = OCSP_Global.alternateOCSPAIAFcn;
289 OCSP_Global.alternateOCSPAIAFcn = newCallback; 287 OCSP_Global.alternateOCSPAIAFcn = newCallback;
290 PR_ExitMonitor(OCSP_Global.monitor); 288 PR_ExitMonitor(OCSP_Global.monitor);
291 if (oldCallback) 289 if (oldCallback)
292 » *oldCallback = old; 290 *oldCallback = old;
293 return SECSuccess; 291 return SECSuccess;
294 } 292 }
295 293
296 static PLHashNumber PR_CALLBACK 294 static PLHashNumber PR_CALLBACK
297 ocsp_CacheKeyHashFunction(const void *key) 295 ocsp_CacheKeyHashFunction(const void *key)
298 { 296 {
299 CERTOCSPCertID *cid = (CERTOCSPCertID *)key; 297 CERTOCSPCertID *cid = (CERTOCSPCertID *)key;
300 PLHashNumber hash = 0; 298 PLHashNumber hash = 0;
301 unsigned int i; 299 unsigned int i;
302 unsigned char *walk; 300 unsigned char *walk;
303 301
304 /* a very simple hash calculation for the initial coding phase */ 302 /* a very simple hash calculation for the initial coding phase */
305 walk = (unsigned char*)cid->issuerNameHash.data; 303 walk = (unsigned char *)cid->issuerNameHash.data;
306 for (i=0; i < cid->issuerNameHash.len; ++i, ++walk) { 304 for (i = 0; i < cid->issuerNameHash.len; ++i, ++walk) {
307 hash += *walk; 305 hash += *walk;
308 } 306 }
309 walk = (unsigned char*)cid->issuerKeyHash.data; 307 walk = (unsigned char *)cid->issuerKeyHash.data;
310 for (i=0; i < cid->issuerKeyHash.len; ++i, ++walk) { 308 for (i = 0; i < cid->issuerKeyHash.len; ++i, ++walk) {
311 hash += *walk; 309 hash += *walk;
312 } 310 }
313 walk = (unsigned char*)cid->serialNumber.data; 311 walk = (unsigned char *)cid->serialNumber.data;
314 for (i=0; i < cid->serialNumber.len; ++i, ++walk) { 312 for (i = 0; i < cid->serialNumber.len; ++i, ++walk) {
315 hash += *walk; 313 hash += *walk;
316 } 314 }
317 return hash; 315 return hash;
318 } 316 }
319 317
320 static PRIntn PR_CALLBACK 318 static PRIntn PR_CALLBACK
321 ocsp_CacheKeyCompareFunction(const void *v1, const void *v2) 319 ocsp_CacheKeyCompareFunction(const void *v1, const void *v2)
322 { 320 {
323 CERTOCSPCertID *cid1 = (CERTOCSPCertID *)v1; 321 CERTOCSPCertID *cid1 = (CERTOCSPCertID *)v1;
324 CERTOCSPCertID *cid2 = (CERTOCSPCertID *)v2; 322 CERTOCSPCertID *cid2 = (CERTOCSPCertID *)v2;
325 323
326 return (SECEqual == SECITEM_CompareItem(&cid1->issuerNameHash, 324 return (SECEqual == SECITEM_CompareItem(&cid1->issuerNameHash,
327 &cid2->issuerNameHash) 325 &cid2->issuerNameHash) &&
328 && SECEqual == SECITEM_CompareItem(&cid1->issuerKeyHash, 326 SECEqual == SECITEM_CompareItem(&cid1->issuerKeyHash,
329 &cid2->issuerKeyHash) 327 &cid2->issuerKeyHash) &&
330 && SECEqual == SECITEM_CompareItem(&cid1->serialNumber, 328 SECEqual == SECITEM_CompareItem(&cid1->serialNumber,
331 &cid2->serialNumber)); 329 &cid2->serialNumber));
332 } 330 }
333 331
334 static SECStatus 332 static SECStatus
335 ocsp_CopyRevokedInfo(PLArenaPool *arena, ocspCertStatus *dest, 333 ocsp_CopyRevokedInfo(PLArenaPool *arena, ocspCertStatus *dest,
336 ocspRevokedInfo *src) 334 ocspRevokedInfo *src)
337 { 335 {
338 SECStatus rv = SECFailure; 336 SECStatus rv = SECFailure;
339 void *mark; 337 void *mark;
340 338
341 mark = PORT_ArenaMark(arena); 339 mark = PORT_ArenaMark(arena);
342 340
343 dest->certStatusInfo.revokedInfo = 341 dest->certStatusInfo.revokedInfo =
344 (ocspRevokedInfo *) PORT_ArenaZAlloc(arena, sizeof(ocspRevokedInfo)); 342 (ocspRevokedInfo *)PORT_ArenaZAlloc(arena, sizeof(ocspRevokedInfo));
345 if (!dest->certStatusInfo.revokedInfo) { 343 if (!dest->certStatusInfo.revokedInfo) {
346 goto loser; 344 goto loser;
347 } 345 }
348 346
349 rv = SECITEM_CopyItem(arena, 347 rv = SECITEM_CopyItem(arena,
350 &dest->certStatusInfo.revokedInfo->revocationTime, 348 &dest->certStatusInfo.revokedInfo->revocationTime,
351 &src->revocationTime); 349 &src->revocationTime);
352 if (rv != SECSuccess) { 350 if (rv != SECSuccess) {
353 goto loser; 351 goto loser;
354 } 352 }
355 353
356 if (src->revocationReason) { 354 if (src->revocationReason) {
357 dest->certStatusInfo.revokedInfo->revocationReason = 355 dest->certStatusInfo.revokedInfo->revocationReason =
358 SECITEM_ArenaDupItem(arena, src->revocationReason); 356 SECITEM_ArenaDupItem(arena, src->revocationReason);
359 if (!dest->certStatusInfo.revokedInfo->revocationReason) { 357 if (!dest->certStatusInfo.revokedInfo->revocationReason) {
360 goto loser; 358 goto loser;
361 } 359 }
362 } else { 360 } else {
363 dest->certStatusInfo.revokedInfo->revocationReason = NULL; 361 dest->certStatusInfo.revokedInfo->revocationReason = NULL;
364 } 362 }
365 363
366 PORT_ArenaUnmark(arena, mark); 364 PORT_ArenaUnmark(arena, mark);
367 return SECSuccess; 365 return SECSuccess;
368 366
369 loser: 367 loser:
370 PORT_ArenaRelease(arena, mark); 368 PORT_ArenaRelease(arena, mark);
371 return SECFailure; 369 return SECFailure;
372 } 370 }
373 371
374 static SECStatus 372 static SECStatus
375 ocsp_CopyCertStatus(PLArenaPool *arena, ocspCertStatus *dest, 373 ocsp_CopyCertStatus(PLArenaPool *arena, ocspCertStatus *dest,
376 ocspCertStatus*src) 374 ocspCertStatus *src)
377 { 375 {
378 SECStatus rv = SECFailure; 376 SECStatus rv = SECFailure;
379 dest->certStatusType = src->certStatusType; 377 dest->certStatusType = src->certStatusType;
380 378
381 switch (src->certStatusType) { 379 switch (src->certStatusType) {
382 case ocspCertStatus_good: 380 case ocspCertStatus_good:
383 dest->certStatusInfo.goodInfo = 381 dest->certStatusInfo.goodInfo =
384 SECITEM_ArenaDupItem(arena, src->certStatusInfo.goodInfo); 382 SECITEM_ArenaDupItem(arena, src->certStatusInfo.goodInfo);
385 if (dest->certStatusInfo.goodInfo != NULL) { 383 if (dest->certStatusInfo.goodInfo != NULL) {
386 rv = SECSuccess; 384 rv = SECSuccess;
387 } 385 }
388 break; 386 break;
389 case ocspCertStatus_revoked: 387 case ocspCertStatus_revoked:
390 rv = ocsp_CopyRevokedInfo(arena, dest, 388 rv = ocsp_CopyRevokedInfo(arena, dest,
391 src->certStatusInfo.revokedInfo); 389 src->certStatusInfo.revokedInfo);
392 break; 390 break;
393 case ocspCertStatus_unknown: 391 case ocspCertStatus_unknown:
394 dest->certStatusInfo.unknownInfo = 392 dest->certStatusInfo.unknownInfo =
395 SECITEM_ArenaDupItem(arena, src->certStatusInfo.unknownInfo); 393 SECITEM_ArenaDupItem(arena, src->certStatusInfo.unknownInfo);
396 if (dest->certStatusInfo.unknownInfo != NULL) { 394 if (dest->certStatusInfo.unknownInfo != NULL) {
397 rv = SECSuccess; 395 rv = SECSuccess;
398 } 396 }
399 break; 397 break;
400 case ocspCertStatus_other: 398 case ocspCertStatus_other:
401 default: 399 default:
402 PORT_Assert(src->certStatusType == ocspCertStatus_other); 400 PORT_Assert(src->certStatusType == ocspCertStatus_other);
403 dest->certStatusInfo.otherInfo = 401 dest->certStatusInfo.otherInfo =
404 SECITEM_ArenaDupItem(arena, src->certStatusInfo.otherInfo); 402 SECITEM_ArenaDupItem(arena, src->certStatusInfo.otherInfo);
405 if (dest->certStatusInfo.otherInfo != NULL) { 403 if (dest->certStatusInfo.otherInfo != NULL) {
406 rv = SECSuccess; 404 rv = SECSuccess;
407 } 405 }
408 break; 406 break;
409 } 407 }
410 return rv; 408 return rv;
411 } 409 }
412 410
413 static void 411 static void
414 ocsp_AddCacheItemToLinkedList(OCSPCacheData *cache, OCSPCacheItem *new_most_rece nt) 412 ocsp_AddCacheItemToLinkedList(OCSPCacheData *cache, OCSPCacheItem *new_most_rece nt)
415 { 413 {
416 PR_EnterMonitor(OCSP_Global.monitor); 414 PR_EnterMonitor(OCSP_Global.monitor);
417 415
418 if (!cache->LRUitem) { 416 if (!cache->LRUitem) {
(...skipping 27 matching lines...) Expand all
446 PORT_Assert(cache->numberOfEntries == 1); 444 PORT_Assert(cache->numberOfEntries == 1);
447 PORT_Assert(item->moreRecent == NULL); 445 PORT_Assert(item->moreRecent == NULL);
448 cache->MRUitem = NULL; 446 cache->MRUitem = NULL;
449 cache->LRUitem = NULL; 447 cache->LRUitem = NULL;
450 } 448 }
451 PR_ExitMonitor(OCSP_Global.monitor); 449 PR_ExitMonitor(OCSP_Global.monitor);
452 return; 450 return;
453 } 451 }
454 452
455 PORT_Assert(cache->numberOfEntries > 1); 453 PORT_Assert(cache->numberOfEntries > 1);
456 454
457 if (item == cache->LRUitem) { 455 if (item == cache->LRUitem) {
458 PORT_Assert(item != cache->MRUitem); 456 PORT_Assert(item != cache->MRUitem);
459 PORT_Assert(item->lessRecent == NULL); 457 PORT_Assert(item->lessRecent == NULL);
460 PORT_Assert(item->moreRecent != NULL); 458 PORT_Assert(item->moreRecent != NULL);
461 PORT_Assert(item->moreRecent->lessRecent == item); 459 PORT_Assert(item->moreRecent->lessRecent == item);
462 cache->LRUitem = item->moreRecent; 460 cache->LRUitem = item->moreRecent;
463 cache->LRUitem->lessRecent = NULL; 461 cache->LRUitem->lessRecent = NULL;
464 } 462 } else if (item == cache->MRUitem) {
465 else if (item == cache->MRUitem) {
466 PORT_Assert(item->moreRecent == NULL); 463 PORT_Assert(item->moreRecent == NULL);
467 PORT_Assert(item->lessRecent != NULL); 464 PORT_Assert(item->lessRecent != NULL);
468 PORT_Assert(item->lessRecent->moreRecent == item); 465 PORT_Assert(item->lessRecent->moreRecent == item);
469 cache->MRUitem = item->lessRecent; 466 cache->MRUitem = item->lessRecent;
470 cache->MRUitem->moreRecent = NULL; 467 cache->MRUitem->moreRecent = NULL;
471 } else { 468 } else {
472 /* remove an entry in the middle of the list */ 469 /* remove an entry in the middle of the list */
473 PORT_Assert(item->moreRecent != NULL); 470 PORT_Assert(item->moreRecent != NULL);
474 PORT_Assert(item->lessRecent != NULL); 471 PORT_Assert(item->lessRecent != NULL);
475 PORT_Assert(item->lessRecent->moreRecent == item); 472 PORT_Assert(item->lessRecent->moreRecent == item);
476 PORT_Assert(item->moreRecent->lessRecent == item); 473 PORT_Assert(item->moreRecent->lessRecent == item);
477 item->moreRecent->lessRecent = item->lessRecent; 474 item->moreRecent->lessRecent = item->lessRecent;
478 item->lessRecent->moreRecent = item->moreRecent; 475 item->lessRecent->moreRecent = item->moreRecent;
479 } 476 }
480 477
481 item->lessRecent = NULL; 478 item->lessRecent = NULL;
482 item->moreRecent = NULL; 479 item->moreRecent = NULL;
483 480
484 PR_ExitMonitor(OCSP_Global.monitor); 481 PR_ExitMonitor(OCSP_Global.monitor);
485 } 482 }
486 483
487 static void 484 static void
488 ocsp_MakeCacheEntryMostRecent(OCSPCacheData *cache, OCSPCacheItem *new_most_rece nt) 485 ocsp_MakeCacheEntryMostRecent(OCSPCacheData *cache, OCSPCacheItem *new_most_rece nt)
489 { 486 {
490 OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent THREADID %p\n", 487 OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent THREADID %p\n",
491 PR_GetCurrentThread())); 488 PR_GetCurrentThread()));
492 PR_EnterMonitor(OCSP_Global.monitor); 489 PR_EnterMonitor(OCSP_Global.monitor);
493 if (cache->MRUitem == new_most_recent) { 490 if (cache->MRUitem == new_most_recent) {
494 OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent ALREADY MOST\n")); 491 OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent ALREADY MOST\n"));
495 PR_ExitMonitor(OCSP_Global.monitor); 492 PR_ExitMonitor(OCSP_Global.monitor);
496 return; 493 return;
497 } 494 }
498 OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent NEW entry\n")); 495 OCSP_TRACE(("OCSP ocsp_MakeCacheEntryMostRecent NEW entry\n"));
499 ocsp_RemoveCacheItemFromLinkedList(cache, new_most_recent); 496 ocsp_RemoveCacheItemFromLinkedList(cache, new_most_recent);
500 ocsp_AddCacheItemToLinkedList(cache, new_most_recent); 497 ocsp_AddCacheItemToLinkedList(cache, new_most_recent);
501 PR_ExitMonitor(OCSP_Global.monitor); 498 PR_ExitMonitor(OCSP_Global.monitor);
502 } 499 }
503 500
504 static PRBool 501 static PRBool
505 ocsp_IsCacheDisabled(void) 502 ocsp_IsCacheDisabled(void)
506 { 503 {
507 /* 504 /*
508 * maxCacheEntries == 0 means unlimited cache entries 505 * maxCacheEntries == 0 means unlimited cache entries
509 * maxCacheEntries < 0 means cache is disabled 506 * maxCacheEntries < 0 means cache is disabled
510 */ 507 */
511 PRBool retval; 508 PRBool retval;
512 PR_EnterMonitor(OCSP_Global.monitor); 509 PR_EnterMonitor(OCSP_Global.monitor);
513 retval = (OCSP_Global.maxCacheEntries < 0); 510 retval = (OCSP_Global.maxCacheEntries < 0);
514 PR_ExitMonitor(OCSP_Global.monitor); 511 PR_ExitMonitor(OCSP_Global.monitor);
515 return retval; 512 return retval;
516 } 513 }
517 514
518 static OCSPCacheItem * 515 static OCSPCacheItem *
519 ocsp_FindCacheEntry(OCSPCacheData *cache, CERTOCSPCertID *certID) 516 ocsp_FindCacheEntry(OCSPCacheData *cache, CERTOCSPCertID *certID)
520 { 517 {
521 OCSPCacheItem *found_ocsp_item = NULL; 518 OCSPCacheItem *found_ocsp_item = NULL;
522 OCSP_TRACE(("OCSP ocsp_FindCacheEntry\n")); 519 OCSP_TRACE(("OCSP ocsp_FindCacheEntry\n"));
523 OCSP_TRACE_CERTID(certID); 520 OCSP_TRACE_CERTID(certID);
524 PR_EnterMonitor(OCSP_Global.monitor); 521 PR_EnterMonitor(OCSP_Global.monitor);
525 if (ocsp_IsCacheDisabled()) 522 if (ocsp_IsCacheDisabled())
526 goto loser; 523 goto loser;
527 524
528 found_ocsp_item = (OCSPCacheItem *)PL_HashTableLookup( 525 found_ocsp_item = (OCSPCacheItem *)PL_HashTableLookup(
529 cache->entries, certID); 526 cache->entries, certID);
530 if (!found_ocsp_item) 527 if (!found_ocsp_item)
531 goto loser; 528 goto loser;
532 529
533 OCSP_TRACE(("OCSP ocsp_FindCacheEntry FOUND!\n")); 530 OCSP_TRACE(("OCSP ocsp_FindCacheEntry FOUND!\n"));
534 ocsp_MakeCacheEntryMostRecent(cache, found_ocsp_item); 531 ocsp_MakeCacheEntryMostRecent(cache, found_ocsp_item);
535 532
536 loser: 533 loser:
537 PR_ExitMonitor(OCSP_Global.monitor); 534 PR_ExitMonitor(OCSP_Global.monitor);
538 return found_ocsp_item; 535 return found_ocsp_item;
539 } 536 }
540 537
541 static void 538 static void
542 ocsp_FreeCacheItem(OCSPCacheItem *item) 539 ocsp_FreeCacheItem(OCSPCacheItem *item)
543 { 540 {
544 OCSP_TRACE(("OCSP ocsp_FreeCacheItem\n")); 541 OCSP_TRACE(("OCSP ocsp_FreeCacheItem\n"));
545 if (item->certStatusArena) { 542 if (item->certStatusArena) {
546 PORT_FreeArena(item->certStatusArena, PR_FALSE); 543 PORT_FreeArena(item->certStatusArena, PR_FALSE);
547 } 544 }
548 if (item->certID->poolp) { 545 if (item->certID->poolp) {
549 /* freeing this poolp arena will also free item */ 546 /* freeing this poolp arena will also free item */
550 PORT_FreeArena(item->certID->poolp, PR_FALSE); 547 PORT_FreeArena(item->certID->poolp, PR_FALSE);
551 } 548 }
552 } 549 }
553 550
554 static void 551 static void
555 ocsp_RemoveCacheItem(OCSPCacheData *cache, OCSPCacheItem *item) 552 ocsp_RemoveCacheItem(OCSPCacheData *cache, OCSPCacheItem *item)
556 { 553 {
557 /* The item we're removing could be either the least recently used item, 554 /* The item we're removing could be either the least recently used item,
558 * or it could be an item that couldn't get updated with newer status info 555 * or it could be an item that couldn't get updated with newer status info
559 * because of an allocation failure, or it could get removed because we're 556 * because of an allocation failure, or it could get removed because we're
560 * cleaning up. 557 * cleaning up.
561 */ 558 */
562 OCSP_TRACE(("OCSP ocsp_RemoveCacheItem, THREADID %p\n", PR_GetCurrentThread( ))); 559 OCSP_TRACE(("OCSP ocsp_RemoveCacheItem, THREADID %p\n", PR_GetCurrentThread( )));
563 PR_EnterMonitor(OCSP_Global.monitor); 560 PR_EnterMonitor(OCSP_Global.monitor);
564 561
565 ocsp_RemoveCacheItemFromLinkedList(cache, item); 562 ocsp_RemoveCacheItemFromLinkedList(cache, item);
566 #ifdef DEBUG 563 #ifdef DEBUG
567 { 564 {
568 PRBool couldRemoveFromHashTable = PL_HashTableRemove(cache->entries, 565 PRBool couldRemoveFromHashTable = PL_HashTableRemove(cache->entries,
569 item->certID); 566 item->certID);
570 PORT_Assert(couldRemoveFromHashTable); 567 PORT_Assert(couldRemoveFromHashTable);
571 } 568 }
572 #else 569 #else
573 PL_HashTableRemove(cache->entries, item->certID); 570 PL_HashTableRemove(cache->entries, item->certID);
574 #endif 571 #endif
575 --cache->numberOfEntries; 572 --cache->numberOfEntries;
576 ocsp_FreeCacheItem(item); 573 ocsp_FreeCacheItem(item);
577 PR_ExitMonitor(OCSP_Global.monitor); 574 PR_ExitMonitor(OCSP_Global.monitor);
578 } 575 }
579 576
580 static void 577 static void
581 ocsp_CheckCacheSize(OCSPCacheData *cache) 578 ocsp_CheckCacheSize(OCSPCacheData *cache)
582 { 579 {
583 OCSP_TRACE(("OCSP ocsp_CheckCacheSize\n")); 580 OCSP_TRACE(("OCSP ocsp_CheckCacheSize\n"));
584 PR_EnterMonitor(OCSP_Global.monitor); 581 PR_EnterMonitor(OCSP_Global.monitor);
585 if (OCSP_Global.maxCacheEntries > 0) { 582 if (OCSP_Global.maxCacheEntries > 0) {
586 /* Cache is not disabled. Number of cache entries is limited. 583 /* Cache is not disabled. Number of cache entries is limited.
587 * The monitor ensures that maxCacheEntries remains positive. 584 * The monitor ensures that maxCacheEntries remains positive.
588 */ 585 */
589 while (cache->numberOfEntries > 586 while (cache->numberOfEntries >
590 (PRUint32)OCSP_Global.maxCacheEntries) { 587 (PRUint32)OCSP_Global.maxCacheEntries) {
591 ocsp_RemoveCacheItem(cache, cache->LRUitem); 588 ocsp_RemoveCacheItem(cache, cache->LRUitem);
592 } 589 }
593 } 590 }
594 PR_ExitMonitor(OCSP_Global.monitor); 591 PR_ExitMonitor(OCSP_Global.monitor);
595 } 592 }
596 593
597 SECStatus 594 SECStatus
598 CERT_ClearOCSPCache(void) 595 CERT_ClearOCSPCache(void)
599 { 596 {
600 OCSP_TRACE(("OCSP CERT_ClearOCSPCache\n")); 597 OCSP_TRACE(("OCSP CERT_ClearOCSPCache\n"));
601 PR_EnterMonitor(OCSP_Global.monitor); 598 PR_EnterMonitor(OCSP_Global.monitor);
602 while (OCSP_Global.cache.numberOfEntries > 0) { 599 while (OCSP_Global.cache.numberOfEntries > 0) {
603 ocsp_RemoveCacheItem(&OCSP_Global.cache, 600 ocsp_RemoveCacheItem(&OCSP_Global.cache,
604 OCSP_Global.cache.LRUitem); 601 OCSP_Global.cache.LRUitem);
605 } 602 }
606 PR_ExitMonitor(OCSP_Global.monitor); 603 PR_ExitMonitor(OCSP_Global.monitor);
607 return SECSuccess; 604 return SECSuccess;
608 } 605 }
609 606
610 static SECStatus 607 static SECStatus
611 ocsp_CreateCacheItemAndConsumeCertID(OCSPCacheData *cache, 608 ocsp_CreateCacheItemAndConsumeCertID(OCSPCacheData *cache,
612 CERTOCSPCertID *certID, 609 CERTOCSPCertID *certID,
613 OCSPCacheItem **pCacheItem) 610 OCSPCacheItem **pCacheItem)
614 { 611 {
615 PLArenaPool *arena; 612 PLArenaPool *arena;
616 void *mark; 613 void *mark;
617 PLHashEntry *new_hash_entry; 614 PLHashEntry *new_hash_entry;
618 OCSPCacheItem *item; 615 OCSPCacheItem *item;
619 616
620 PORT_Assert(pCacheItem != NULL); 617 PORT_Assert(pCacheItem != NULL);
621 *pCacheItem = NULL; 618 *pCacheItem = NULL;
622 619
623 PR_EnterMonitor(OCSP_Global.monitor); 620 PR_EnterMonitor(OCSP_Global.monitor);
624 arena = certID->poolp; 621 arena = certID->poolp;
625 mark = PORT_ArenaMark(arena); 622 mark = PORT_ArenaMark(arena);
626 623
627 /* ZAlloc will init all Bools to False and all Pointers to NULL 624 /* ZAlloc will init all Bools to False and all Pointers to NULL
628 and all error codes to zero/good. */ 625 and all error codes to zero/good. */
629 item = (OCSPCacheItem *)PORT_ArenaZAlloc(certID->poolp, 626 item = (OCSPCacheItem *)PORT_ArenaZAlloc(certID->poolp,
630 sizeof(OCSPCacheItem)); 627 sizeof(OCSPCacheItem));
631 if (!item) { 628 if (!item) {
632 goto loser; 629 goto loser;
633 } 630 }
634 item->certID = certID; 631 item->certID = certID;
635 new_hash_entry = PL_HashTableAdd(cache->entries, item->certID, 632 new_hash_entry = PL_HashTableAdd(cache->entries, item->certID,
636 item); 633 item);
637 if (!new_hash_entry) { 634 if (!new_hash_entry) {
638 goto loser; 635 goto loser;
639 } 636 }
640 ++cache->numberOfEntries; 637 ++cache->numberOfEntries;
641 PORT_ArenaUnmark(arena, mark); 638 PORT_ArenaUnmark(arena, mark);
642 ocsp_AddCacheItemToLinkedList(cache, item); 639 ocsp_AddCacheItemToLinkedList(cache, item);
643 *pCacheItem = item; 640 *pCacheItem = item;
644 641
645 PR_ExitMonitor(OCSP_Global.monitor); 642 PR_ExitMonitor(OCSP_Global.monitor);
646 return SECSuccess; 643 return SECSuccess;
647 644
648 loser: 645 loser:
649 PORT_ArenaRelease(arena, mark); 646 PORT_ArenaRelease(arena, mark);
650 PR_ExitMonitor(OCSP_Global.monitor); 647 PR_ExitMonitor(OCSP_Global.monitor);
651 return SECFailure; 648 return SECFailure;
652 } 649 }
653 650
654 static SECStatus 651 static SECStatus
655 ocsp_SetCacheItemResponse(OCSPCacheItem *item, 652 ocsp_SetCacheItemResponse(OCSPCacheItem *item,
656 const CERTOCSPSingleResponse *response) 653 const CERTOCSPSingleResponse *response)
657 { 654 {
658 if (item->certStatusArena) { 655 if (item->certStatusArena) {
659 PORT_FreeArena(item->certStatusArena, PR_FALSE); 656 PORT_FreeArena(item->certStatusArena, PR_FALSE);
660 item->certStatusArena = NULL; 657 item->certStatusArena = NULL;
661 } 658 }
662 item->haveThisUpdate = item->haveNextUpdate = PR_FALSE; 659 item->haveThisUpdate = item->haveNextUpdate = PR_FALSE;
663 if (response) { 660 if (response) {
664 SECStatus rv; 661 SECStatus rv;
665 item->certStatusArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 662 item->certStatusArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
666 if (item->certStatusArena == NULL) { 663 if (item->certStatusArena == NULL) {
667 return SECFailure; 664 return SECFailure;
668 } 665 }
669 rv = ocsp_CopyCertStatus(item->certStatusArena, &item->certStatus, 666 rv = ocsp_CopyCertStatus(item->certStatusArena, &item->certStatus,
670 response->certStatus); 667 response->certStatus);
671 if (rv != SECSuccess) { 668 if (rv != SECSuccess) {
672 PORT_FreeArena(item->certStatusArena, PR_FALSE); 669 PORT_FreeArena(item->certStatusArena, PR_FALSE);
673 item->certStatusArena = NULL; 670 item->certStatusArena = NULL;
674 return rv; 671 return rv;
675 } 672 }
676 item->missingResponseError = 0; 673 item->missingResponseError = 0;
677 rv = DER_GeneralizedTimeToTime(&item->thisUpdate, 674 rv = DER_GeneralizedTimeToTime(&item->thisUpdate,
678 &response->thisUpdate); 675 &response->thisUpdate);
679 item->haveThisUpdate = (rv == SECSuccess); 676 item->haveThisUpdate = (rv == SECSuccess);
680 if (response->nextUpdate) { 677 if (response->nextUpdate) {
681 rv = DER_GeneralizedTimeToTime(&item->nextUpdate, 678 rv = DER_GeneralizedTimeToTime(&item->nextUpdate,
682 response->nextUpdate); 679 response->nextUpdate);
683 item->haveNextUpdate = (rv == SECSuccess); 680 item->haveNextUpdate = (rv == SECSuccess);
684 } else { 681 } else {
685 item->haveNextUpdate = PR_FALSE; 682 item->haveNextUpdate = PR_FALSE;
686 } 683 }
687 } 684 }
688 return SECSuccess; 685 return SECSuccess;
689 } 686 }
690 687
691 static void 688 static void
692 ocsp_FreshenCacheItemNextFetchAttemptTime(OCSPCacheItem *cacheItem) 689 ocsp_FreshenCacheItemNextFetchAttemptTime(OCSPCacheItem *cacheItem)
693 { 690 {
694 PRTime now; 691 PRTime now;
695 PRTime earliestAllowedNextFetchAttemptTime; 692 PRTime earliestAllowedNextFetchAttemptTime;
696 PRTime latestTimeWhenResponseIsConsideredFresh; 693 PRTime latestTimeWhenResponseIsConsideredFresh;
697 694
698 OCSP_TRACE(("OCSP ocsp_FreshenCacheItemNextFetchAttemptTime\n")); 695 OCSP_TRACE(("OCSP ocsp_FreshenCacheItemNextFetchAttemptTime\n"));
699 696
700 PR_EnterMonitor(OCSP_Global.monitor); 697 PR_EnterMonitor(OCSP_Global.monitor);
701 698
702 now = PR_Now(); 699 now = PR_Now();
703 OCSP_TRACE_TIME("now:", now); 700 OCSP_TRACE_TIME("now:", now);
704 701
705 if (cacheItem->haveThisUpdate) { 702 if (cacheItem->haveThisUpdate) {
706 OCSP_TRACE_TIME("thisUpdate:", cacheItem->thisUpdate); 703 OCSP_TRACE_TIME("thisUpdate:", cacheItem->thisUpdate);
707 latestTimeWhenResponseIsConsideredFresh = cacheItem->thisUpdate + 704 latestTimeWhenResponseIsConsideredFresh = cacheItem->thisUpdate +
708 OCSP_Global.maximumSecondsToNextFetchAttempt * 705 OCSP_Global.maximumSecondsToNe xtFetchAttempt *
709 MICROSECONDS_PER_SECOND; 706 MICROSECONDS_PER_SECOND;
710 OCSP_TRACE_TIME("latestTimeWhenResponseIsConsideredFresh:", 707 OCSP_TRACE_TIME("latestTimeWhenResponseIsConsideredFresh:",
711 latestTimeWhenResponseIsConsideredFresh); 708 latestTimeWhenResponseIsConsideredFresh);
712 } else { 709 } else {
713 latestTimeWhenResponseIsConsideredFresh = now + 710 latestTimeWhenResponseIsConsideredFresh = now +
714 OCSP_Global.minimumSecondsToNextFetchAttempt * 711 OCSP_Global.minimumSecondsToNe xtFetchAttempt *
715 MICROSECONDS_PER_SECOND; 712 MICROSECONDS_PER_SECOND;
716 OCSP_TRACE_TIME("no thisUpdate, " 713 OCSP_TRACE_TIME("no thisUpdate, "
717 "latestTimeWhenResponseIsConsideredFresh:", 714 "latestTimeWhenResponseIsConsideredFresh:",
718 latestTimeWhenResponseIsConsideredFresh); 715 latestTimeWhenResponseIsConsideredFresh);
719 } 716 }
720 717
721 if (cacheItem->haveNextUpdate) { 718 if (cacheItem->haveNextUpdate) {
722 OCSP_TRACE_TIME("have nextUpdate:", cacheItem->nextUpdate); 719 OCSP_TRACE_TIME("have nextUpdate:", cacheItem->nextUpdate);
723 } 720 }
724 721
725 if (cacheItem->haveNextUpdate && 722 if (cacheItem->haveNextUpdate &&
726 cacheItem->nextUpdate < latestTimeWhenResponseIsConsideredFresh) { 723 cacheItem->nextUpdate < latestTimeWhenResponseIsConsideredFresh) {
727 latestTimeWhenResponseIsConsideredFresh = cacheItem->nextUpdate; 724 latestTimeWhenResponseIsConsideredFresh = cacheItem->nextUpdate;
728 OCSP_TRACE_TIME("nextUpdate is smaller than latestFresh, setting " 725 OCSP_TRACE_TIME("nextUpdate is smaller than latestFresh, setting "
729 "latestTimeWhenResponseIsConsideredFresh:", 726 "latestTimeWhenResponseIsConsideredFresh:",
730 latestTimeWhenResponseIsConsideredFresh); 727 latestTimeWhenResponseIsConsideredFresh);
731 } 728 }
732 729
733 earliestAllowedNextFetchAttemptTime = now + 730 earliestAllowedNextFetchAttemptTime = now +
734 OCSP_Global.minimumSecondsToNextFetchAttempt * 731 OCSP_Global.minimumSecondsToNextFetchA ttempt *
735 MICROSECONDS_PER_SECOND; 732 MICROSECONDS_PER_SECOND;
736 OCSP_TRACE_TIME("earliestAllowedNextFetchAttemptTime:", 733 OCSP_TRACE_TIME("earliestAllowedNextFetchAttemptTime:",
737 earliestAllowedNextFetchAttemptTime); 734 earliestAllowedNextFetchAttemptTime);
738 735
739 if (latestTimeWhenResponseIsConsideredFresh < 736 if (latestTimeWhenResponseIsConsideredFresh <
740 earliestAllowedNextFetchAttemptTime) { 737 earliestAllowedNextFetchAttemptTime) {
741 latestTimeWhenResponseIsConsideredFresh = 738 latestTimeWhenResponseIsConsideredFresh =
742 earliestAllowedNextFetchAttemptTime; 739 earliestAllowedNextFetchAttemptTime;
743 OCSP_TRACE_TIME("latest < earliest, setting latest to:", 740 OCSP_TRACE_TIME("latest < earliest, setting latest to:",
744 latestTimeWhenResponseIsConsideredFresh); 741 latestTimeWhenResponseIsConsideredFresh);
745 } 742 }
746 743
747 cacheItem->nextFetchAttemptTime = 744 cacheItem->nextFetchAttemptTime =
748 latestTimeWhenResponseIsConsideredFresh; 745 latestTimeWhenResponseIsConsideredFresh;
749 OCSP_TRACE_TIME("nextFetchAttemptTime", 746 OCSP_TRACE_TIME("nextFetchAttemptTime",
750 latestTimeWhenResponseIsConsideredFresh); 747 latestTimeWhenResponseIsConsideredFresh);
751 748
752 PR_ExitMonitor(OCSP_Global.monitor); 749 PR_ExitMonitor(OCSP_Global.monitor);
753 } 750 }
754 751
755 static PRBool 752 static PRBool
756 ocsp_IsCacheItemFresh(OCSPCacheItem *cacheItem) 753 ocsp_IsCacheItemFresh(OCSPCacheItem *cacheItem)
757 { 754 {
758 PRTime now; 755 PRTime now;
759 PRBool fresh; 756 PRBool fresh;
760 757
761 now = PR_Now(); 758 now = PR_Now();
762 759
763 fresh = cacheItem->nextFetchAttemptTime > now; 760 fresh = cacheItem->nextFetchAttemptTime > now;
764 761
765 /* Work around broken OCSP responders that return unknown responses for 762 /* Work around broken OCSP responders that return unknown responses for
766 * certificates, especially certificates that were just recently issued. 763 * certificates, especially certificates that were just recently issued.
767 */ 764 */
768 if (fresh && cacheItem->certStatusArena && 765 if (fresh && cacheItem->certStatusArena &&
769 cacheItem->certStatus.certStatusType == ocspCertStatus_unknown) { 766 cacheItem->certStatus.certStatusType == ocspCertStatus_unknown) {
770 fresh = PR_FALSE; 767 fresh = PR_FALSE;
771 } 768 }
772 769
773 OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", fresh)); 770 OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", fresh));
774 771
775 return fresh; 772 return fresh;
776 } 773 }
777 774
778 /* 775 /*
779 * Status in *certIDWasConsumed will always be correct, regardless of 776 * Status in *certIDWasConsumed will always be correct, regardless of
780 * return value. 777 * return value.
781 * If the caller is unable to transfer ownership of certID, 778 * If the caller is unable to transfer ownership of certID,
782 * then the caller must set certIDWasConsumed to NULL, 779 * then the caller must set certIDWasConsumed to NULL,
783 * and this function will potentially duplicate the certID object. 780 * and this function will potentially duplicate the certID object.
784 */ 781 */
785 static SECStatus 782 static SECStatus
786 ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache, 783 ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
787 CERTOCSPCertID *certID, 784 CERTOCSPCertID *certID,
788 CERTOCSPSingleResponse *single, 785 CERTOCSPSingleResponse *single,
789 PRBool *certIDWasConsumed) 786 PRBool *certIDWasConsumed)
790 { 787 {
791 SECStatus rv; 788 SECStatus rv;
792 OCSPCacheItem *cacheItem; 789 OCSPCacheItem *cacheItem;
793 OCSP_TRACE(("OCSP ocsp_CreateOrUpdateCacheEntry\n")); 790 OCSP_TRACE(("OCSP ocsp_CreateOrUpdateCacheEntry\n"));
794 791
795 if (certIDWasConsumed) 792 if (certIDWasConsumed)
796 *certIDWasConsumed = PR_FALSE; 793 *certIDWasConsumed = PR_FALSE;
797 794
798 PR_EnterMonitor(OCSP_Global.monitor); 795 PR_EnterMonitor(OCSP_Global.monitor);
799 PORT_Assert(OCSP_Global.maxCacheEntries >= 0); 796 PORT_Assert(OCSP_Global.maxCacheEntries >= 0);
800 797
801 cacheItem = ocsp_FindCacheEntry(cache, certID); 798 cacheItem = ocsp_FindCacheEntry(cache, certID);
802 799
803 /* Don't replace an unknown or revoked entry with an error entry, even if 800 /* Don't replace an unknown or revoked entry with an error entry, even if
804 * the existing entry is expired. Instead, we'll continue to use the 801 * the existing entry is expired. Instead, we'll continue to use the
805 * existing (possibly expired) cache entry until we receive a valid signed 802 * existing (possibly expired) cache entry until we receive a valid signed
806 * response to replace it. 803 * response to replace it.
807 */ 804 */
808 if (!single && cacheItem && cacheItem->certStatusArena && 805 if (!single && cacheItem && cacheItem->certStatusArena &&
809 (cacheItem->certStatus.certStatusType == ocspCertStatus_revoked || 806 (cacheItem->certStatus.certStatusType == ocspCertStatus_revoked ||
810 cacheItem->certStatus.certStatusType == ocspCertStatus_unknown)) { 807 cacheItem->certStatus.certStatusType == ocspCertStatus_unknown)) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 ocsp_CheckCacheSize(cache); 857 ocsp_CheckCacheSize(cache);
861 858
862 PR_ExitMonitor(OCSP_Global.monitor); 859 PR_ExitMonitor(OCSP_Global.monitor);
863 return SECSuccess; 860 return SECSuccess;
864 } 861 }
865 862
866 extern SECStatus 863 extern SECStatus
867 CERT_SetOCSPFailureMode(SEC_OcspFailureMode ocspFailureMode) 864 CERT_SetOCSPFailureMode(SEC_OcspFailureMode ocspFailureMode)
868 { 865 {
869 switch (ocspFailureMode) { 866 switch (ocspFailureMode) {
870 case ocspMode_FailureIsVerificationFailure: 867 case ocspMode_FailureIsVerificationFailure:
871 case ocspMode_FailureIsNotAVerificationFailure: 868 case ocspMode_FailureIsNotAVerificationFailure:
872 break; 869 break;
873 default: 870 default:
874 PORT_SetError(SEC_ERROR_INVALID_ARGS); 871 PORT_SetError(SEC_ERROR_INVALID_ARGS);
875 return SECFailure; 872 return SECFailure;
876 } 873 }
877 874
878 PR_EnterMonitor(OCSP_Global.monitor); 875 PR_EnterMonitor(OCSP_Global.monitor);
879 OCSP_Global.ocspFailureMode = ocspFailureMode; 876 OCSP_Global.ocspFailureMode = ocspFailureMode;
880 PR_ExitMonitor(OCSP_Global.monitor); 877 PR_ExitMonitor(OCSP_Global.monitor);
881 return SECSuccess; 878 return SECSuccess;
882 } 879 }
883 880
884 SECStatus 881 SECStatus
885 CERT_OCSPCacheSettings(PRInt32 maxCacheEntries, 882 CERT_OCSPCacheSettings(PRInt32 maxCacheEntries,
886 PRUint32 minimumSecondsToNextFetchAttempt, 883 PRUint32 minimumSecondsToNextFetchAttempt,
887 PRUint32 maximumSecondsToNextFetchAttempt) 884 PRUint32 maximumSecondsToNextFetchAttempt)
888 { 885 {
889 if (minimumSecondsToNextFetchAttempt > maximumSecondsToNextFetchAttempt 886 if (minimumSecondsToNextFetchAttempt > maximumSecondsToNextFetchAttempt ||
890 || maxCacheEntries < -1) { 887 maxCacheEntries < -1) {
891 PORT_SetError(SEC_ERROR_INVALID_ARGS); 888 PORT_SetError(SEC_ERROR_INVALID_ARGS);
892 return SECFailure; 889 return SECFailure;
893 } 890 }
894 891
895 PR_EnterMonitor(OCSP_Global.monitor); 892 PR_EnterMonitor(OCSP_Global.monitor);
896 893
897 if (maxCacheEntries < 0) { 894 if (maxCacheEntries < 0) {
898 OCSP_Global.maxCacheEntries = -1; /* disable cache */ 895 OCSP_Global.maxCacheEntries = -1; /* disable cache */
899 } else if (maxCacheEntries == 0) { 896 } else if (maxCacheEntries == 0) {
900 OCSP_Global.maxCacheEntries = 0; /* unlimited cache entries */ 897 OCSP_Global.maxCacheEntries = 0; /* unlimited cache entries */
901 } else { 898 } else {
902 OCSP_Global.maxCacheEntries = maxCacheEntries; 899 OCSP_Global.maxCacheEntries = maxCacheEntries;
903 } 900 }
904 901
905 if (minimumSecondsToNextFetchAttempt < 902 if (minimumSecondsToNextFetchAttempt <
906 OCSP_Global.minimumSecondsToNextFetchAttempt 903 OCSP_Global.minimumSecondsToNextFetchAttempt ||
907 || maximumSecondsToNextFetchAttempt < 904 maximumSecondsToNextFetchAttempt <
908 OCSP_Global.maximumSecondsToNextFetchAttempt) { 905 OCSP_Global.maximumSecondsToNextFetchAttempt) {
909 /* 906 /*
910 * Ensure our existing cache entries are not used longer than the 907 * Ensure our existing cache entries are not used longer than the
911 * new settings allow, we're lazy and just clear the cache 908 * new settings allow, we're lazy and just clear the cache
912 */ 909 */
913 CERT_ClearOCSPCache(); 910 CERT_ClearOCSPCache();
914 } 911 }
915 912
916 OCSP_Global.minimumSecondsToNextFetchAttempt = 913 OCSP_Global.minimumSecondsToNextFetchAttempt =
917 minimumSecondsToNextFetchAttempt; 914 minimumSecondsToNextFetchAttempt;
918 OCSP_Global.maximumSecondsToNextFetchAttempt = 915 OCSP_Global.maximumSecondsToNextFetchAttempt =
919 maximumSecondsToNextFetchAttempt; 916 maximumSecondsToNextFetchAttempt;
920 ocsp_CheckCacheSize(&OCSP_Global.cache); 917 ocsp_CheckCacheSize(&OCSP_Global.cache);
921 918
922 PR_ExitMonitor(OCSP_Global.monitor); 919 PR_ExitMonitor(OCSP_Global.monitor);
923 return SECSuccess; 920 return SECSuccess;
924 } 921 }
925 922
926 SECStatus 923 SECStatus
927 CERT_SetOCSPTimeout(PRUint32 seconds) 924 CERT_SetOCSPTimeout(PRUint32 seconds)
928 { 925 {
929 /* no locking, see bug 406120 */ 926 /* no locking, see bug 406120 */
930 OCSP_Global.timeoutSeconds = seconds; 927 OCSP_Global.timeoutSeconds = seconds;
931 return SECSuccess; 928 return SECSuccess;
932 } 929 }
933 930
934 /* this function is called at NSS initialization time */ 931 /* this function is called at NSS initialization time */
935 SECStatus OCSP_InitGlobal(void) 932 SECStatus
933 OCSP_InitGlobal(void)
936 { 934 {
937 SECStatus rv = SECFailure; 935 SECStatus rv = SECFailure;
938 936
939 if (OCSP_Global.monitor == NULL) { 937 if (OCSP_Global.monitor == NULL) {
940 OCSP_Global.monitor = PR_NewMonitor(); 938 OCSP_Global.monitor = PR_NewMonitor();
941 } 939 }
942 if (!OCSP_Global.monitor) 940 if (!OCSP_Global.monitor)
943 return SECFailure; 941 return SECFailure;
944 942
945 PR_EnterMonitor(OCSP_Global.monitor); 943 PR_EnterMonitor(OCSP_Global.monitor);
946 if (!OCSP_Global.cache.entries) { 944 if (!OCSP_Global.cache.entries) {
947 OCSP_Global.cache.entries = 945 OCSP_Global.cache.entries =
948 PL_NewHashTable(0, 946 PL_NewHashTable(0,
949 ocsp_CacheKeyHashFunction, 947 ocsp_CacheKeyHashFunction,
950 ocsp_CacheKeyCompareFunction, 948 ocsp_CacheKeyCompareFunction,
951 PL_CompareValues, 949 PL_CompareValues,
952 NULL, 950 NULL,
953 NULL); 951 NULL);
954 OCSP_Global.ocspFailureMode = ocspMode_FailureIsVerificationFailure; 952 OCSP_Global.ocspFailureMode = ocspMode_FailureIsVerificationFailure;
955 OCSP_Global.cache.numberOfEntries = 0; 953 OCSP_Global.cache.numberOfEntries = 0;
956 OCSP_Global.cache.MRUitem = NULL; 954 OCSP_Global.cache.MRUitem = NULL;
957 OCSP_Global.cache.LRUitem = NULL; 955 OCSP_Global.cache.LRUitem = NULL;
958 } else { 956 } else {
959 /* 957 /*
960 * NSS might call this function twice while attempting to init. 958 * NSS might call this function twice while attempting to init.
961 * But it's not allowed to call this again after any activity. 959 * But it's not allowed to call this again after any activity.
962 */ 960 */
963 PORT_Assert(OCSP_Global.cache.numberOfEntries == 0); 961 PORT_Assert(OCSP_Global.cache.numberOfEntries == 0);
964 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 962 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
965 } 963 }
966 if (OCSP_Global.cache.entries) 964 if (OCSP_Global.cache.entries)
967 rv = SECSuccess; 965 rv = SECSuccess;
968 PR_ExitMonitor(OCSP_Global.monitor); 966 PR_ExitMonitor(OCSP_Global.monitor);
969 return rv; 967 return rv;
970 } 968 }
971 969
972 SECStatus OCSP_ShutdownGlobal(void) 970 SECStatus
971 OCSP_ShutdownGlobal(void)
973 { 972 {
974 if (!OCSP_Global.monitor) 973 if (!OCSP_Global.monitor)
975 return SECSuccess; 974 return SECSuccess;
976 975
977 PR_EnterMonitor(OCSP_Global.monitor); 976 PR_EnterMonitor(OCSP_Global.monitor);
978 if (OCSP_Global.cache.entries) { 977 if (OCSP_Global.cache.entries) {
979 CERT_ClearOCSPCache(); 978 CERT_ClearOCSPCache();
980 PL_HashTableDestroy(OCSP_Global.cache.entries); 979 PL_HashTableDestroy(OCSP_Global.cache.entries);
981 OCSP_Global.cache.entries = NULL; 980 OCSP_Global.cache.entries = NULL;
982 } 981 }
983 PORT_Assert(OCSP_Global.cache.numberOfEntries == 0); 982 PORT_Assert(OCSP_Global.cache.numberOfEntries == 0);
984 OCSP_Global.cache.MRUitem = NULL; 983 OCSP_Global.cache.MRUitem = NULL;
985 OCSP_Global.cache.LRUitem = NULL; 984 OCSP_Global.cache.LRUitem = NULL;
986 985
987 OCSP_Global.defaultHttpClientFcn = NULL; 986 OCSP_Global.defaultHttpClientFcn = NULL;
988 OCSP_Global.maxCacheEntries = DEFAULT_OCSP_CACHE_SIZE; 987 OCSP_Global.maxCacheEntries = DEFAULT_OCSP_CACHE_SIZE;
989 OCSP_Global.minimumSecondsToNextFetchAttempt = 988 OCSP_Global.minimumSecondsToNextFetchAttempt =
990 DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT; 989 DEFAULT_MINIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
991 OCSP_Global.maximumSecondsToNextFetchAttempt = 990 OCSP_Global.maximumSecondsToNextFetchAttempt =
992 DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT; 991 DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT;
993 OCSP_Global.ocspFailureMode = 992 OCSP_Global.ocspFailureMode =
994 ocspMode_FailureIsVerificationFailure; 993 ocspMode_FailureIsVerificationFailure;
995 PR_ExitMonitor(OCSP_Global.monitor); 994 PR_ExitMonitor(OCSP_Global.monitor);
996 995
997 PR_DestroyMonitor(OCSP_Global.monitor); 996 PR_DestroyMonitor(OCSP_Global.monitor);
998 OCSP_Global.monitor = NULL; 997 OCSP_Global.monitor = NULL;
999 return SECSuccess; 998 return SECSuccess;
1000 } 999 }
1001 1000
1002 /* 1001 /*
1003 * A return value of NULL means: 1002 * A return value of NULL means:
1004 * The application did not register it's own HTTP client. 1003 * The application did not register it's own HTTP client.
1005 */ 1004 */
1006 const SEC_HttpClientFcn *SEC_GetRegisteredHttpClient(void) 1005 const SEC_HttpClientFcn *
1006 SEC_GetRegisteredHttpClient(void)
1007 { 1007 {
1008 const SEC_HttpClientFcn *retval; 1008 const SEC_HttpClientFcn *retval;
1009 1009
1010 if (!OCSP_Global.monitor) { 1010 if (!OCSP_Global.monitor) {
1011 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 1011 PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
1012 return NULL; 1012 return NULL;
1013 } 1013 }
1014 1014
1015 PR_EnterMonitor(OCSP_Global.monitor); 1015 PR_EnterMonitor(OCSP_Global.monitor);
1016 retval = OCSP_Global.defaultHttpClientFcn; 1016 retval = OCSP_Global.defaultHttpClientFcn;
1017 PR_ExitMonitor(OCSP_Global.monitor); 1017 PR_ExitMonitor(OCSP_Global.monitor);
1018 1018
1019 return retval; 1019 return retval;
1020 } 1020 }
1021 1021
1022 /* 1022 /*
1023 * The following structure is only used internally. It is allocated when 1023 * The following structure is only used internally. It is allocated when
1024 * someone turns on OCSP checking, and hangs off of the status-configuration 1024 * someone turns on OCSP checking, and hangs off of the status-configuration
1025 * structure in the certdb structure. We use it to keep configuration 1025 * structure in the certdb structure. We use it to keep configuration
1026 * information specific to OCSP checking. 1026 * information specific to OCSP checking.
1027 */ 1027 */
1028 typedef struct ocspCheckingContextStr { 1028 typedef struct ocspCheckingContextStr {
(...skipping 21 matching lines...) Expand all
1050 */ 1050 */
1051 extern const SEC_ASN1Template ocsp_CertIDTemplate[]; 1051 extern const SEC_ASN1Template ocsp_CertIDTemplate[];
1052 extern const SEC_ASN1Template ocsp_PointerToSignatureTemplate[]; 1052 extern const SEC_ASN1Template ocsp_PointerToSignatureTemplate[];
1053 extern const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[]; 1053 extern const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[];
1054 extern const SEC_ASN1Template ocsp_ResponseDataTemplate[]; 1054 extern const SEC_ASN1Template ocsp_ResponseDataTemplate[];
1055 extern const SEC_ASN1Template ocsp_RevokedInfoTemplate[]; 1055 extern const SEC_ASN1Template ocsp_RevokedInfoTemplate[];
1056 extern const SEC_ASN1Template ocsp_SingleRequestTemplate[]; 1056 extern const SEC_ASN1Template ocsp_SingleRequestTemplate[];
1057 extern const SEC_ASN1Template ocsp_SingleResponseTemplate[]; 1057 extern const SEC_ASN1Template ocsp_SingleResponseTemplate[];
1058 extern const SEC_ASN1Template ocsp_TBSRequestTemplate[]; 1058 extern const SEC_ASN1Template ocsp_TBSRequestTemplate[];
1059 1059
1060
1061 /* 1060 /*
1062 * Request-related templates... 1061 * Request-related templates...
1063 */ 1062 */
1064 1063
1065 /* 1064 /*
1066 * OCSPRequest ::= SEQUENCE { 1065 * OCSPRequest ::= SEQUENCE {
1067 * tbsRequest TBSRequest, 1066 * tbsRequest TBSRequest,
1068 * optionalSignature [0] EXPLICIT Signature OPTIONAL } 1067 * optionalSignature [0] EXPLICIT Signature OPTIONAL }
1069 */ 1068 */
1070 static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = { 1069 static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = {
1071 { SEC_ASN1_SEQUENCE, 1070 { SEC_ASN1_SEQUENCE,
1072 » 0, NULL, sizeof(CERTOCSPRequest) }, 1071 0, NULL, sizeof(CERTOCSPRequest) },
1073 { SEC_ASN1_POINTER, 1072 { SEC_ASN1_POINTER,
1074 » offsetof(CERTOCSPRequest, tbsRequest), 1073 offsetof(CERTOCSPRequest, tbsRequest),
1075 » ocsp_TBSRequestTemplate }, 1074 ocsp_TBSRequestTemplate },
1076 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1075 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1077 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 1076 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
1078 » offsetof(CERTOCSPRequest, optionalSignature), 1077 offsetof(CERTOCSPRequest, optionalSignature),
1079 » ocsp_PointerToSignatureTemplate }, 1078 ocsp_PointerToSignatureTemplate },
1080 { 0 } 1079 { 0 }
1081 }; 1080 };
1082 1081
1083 /* 1082 /*
1084 * TBSRequest ::= SEQUENCE { 1083 * TBSRequest ::= SEQUENCE {
1085 * version [0] EXPLICIT Version DEFAULT v1, 1084 * version [0] EXPLICIT Version DEFAULT v1,
1086 * requestorName [1] EXPLICIT GeneralName OPTIONAL, 1085 * requestorName [1] EXPLICIT GeneralName OPTIONAL,
1087 * requestList SEQUENCE OF Request, 1086 * requestList SEQUENCE OF Request,
1088 * requestExtensions [2] EXPLICIT Extensions OPTIONAL } 1087 * requestExtensions [2] EXPLICIT Extensions OPTIONAL }
1089 * 1088 *
1090 * Version ::= INTEGER { v1(0) } 1089 * Version ::= INTEGER { v1(0) }
1091 * 1090 *
1092 * Note: this should be static but the AIX compiler doesn't like it (because it 1091 * Note: this should be static but the AIX compiler doesn't like it (because it
1093 * was forward-declared above); it is not meant to be exported, but this 1092 * was forward-declared above); it is not meant to be exported, but this
1094 * is the only way it will compile. 1093 * is the only way it will compile.
1095 */ 1094 */
1096 const SEC_ASN1Template ocsp_TBSRequestTemplate[] = { 1095 const SEC_ASN1Template ocsp_TBSRequestTemplate[] = {
1097 { SEC_ASN1_SEQUENCE, 1096 { SEC_ASN1_SEQUENCE,
1098 » 0, NULL, sizeof(ocspTBSRequest) }, 1097 0, NULL, sizeof(ocspTBSRequest) },
1099 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |» » /* XXX DER_DEFAULT */ 1098 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
1100 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1099 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
1101 » offsetof(ocspTBSRequest, version), 1100 offsetof(ocspTBSRequest, version),
1102 » SEC_ASN1_SUB(SEC_IntegerTemplate) }, 1101 SEC_ASN1_SUB(SEC_IntegerTemplate) },
1103 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1102 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1104 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, 1103 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
1105 » offsetof(ocspTBSRequest, derRequestorName), 1104 offsetof(ocspTBSRequest, derRequestorName),
1106 » SEC_ASN1_SUB(SEC_PointerToAnyTemplate) }, 1105 SEC_ASN1_SUB(SEC_PointerToAnyTemplate) },
1107 { SEC_ASN1_SEQUENCE_OF, 1106 { SEC_ASN1_SEQUENCE_OF,
1108 » offsetof(ocspTBSRequest, requestList), 1107 offsetof(ocspTBSRequest, requestList),
1109 » ocsp_SingleRequestTemplate }, 1108 ocsp_SingleRequestTemplate },
1110 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1109 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1111 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, 1110 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
1112 » offsetof(ocspTBSRequest, requestExtensions), 1111 offsetof(ocspTBSRequest, requestExtensions),
1113 » CERT_SequenceOfCertExtensionTemplate }, 1112 CERT_SequenceOfCertExtensionTemplate },
1114 { 0 } 1113 { 0 }
1115 }; 1114 };
1116 1115
1117 /* 1116 /*
1118 * Signature ::= SEQUENCE { 1117 * Signature ::= SEQUENCE {
1119 * signatureAlgorithm AlgorithmIdentifier, 1118 * signatureAlgorithm AlgorithmIdentifier,
1120 * signature BIT STRING, 1119 * signature BIT STRING,
1121 * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } 1120 * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
1122 */ 1121 */
1123 static const SEC_ASN1Template ocsp_SignatureTemplate[] = { 1122 static const SEC_ASN1Template ocsp_SignatureTemplate[] = {
1124 { SEC_ASN1_SEQUENCE, 1123 { SEC_ASN1_SEQUENCE,
1125 » 0, NULL, sizeof(ocspSignature) }, 1124 0, NULL, sizeof(ocspSignature) },
1126 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 1125 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
1127 » offsetof(ocspSignature, signatureAlgorithm), 1126 offsetof(ocspSignature, signatureAlgorithm),
1128 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 1127 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
1129 { SEC_ASN1_BIT_STRING, 1128 { SEC_ASN1_BIT_STRING,
1130 » offsetof(ocspSignature, signature) }, 1129 offsetof(ocspSignature, signature) },
1131 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1130 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1132 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1131 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
1133 » offsetof(ocspSignature, derCerts), 1132 offsetof(ocspSignature, derCerts),
1134 » SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) }, 1133 SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
1135 { 0 } 1134 { 0 }
1136 }; 1135 };
1137 1136
1138 /* 1137 /*
1139 * This template is just an extra level to use in an explicitly-tagged 1138 * This template is just an extra level to use in an explicitly-tagged
1140 * reference to a Signature. 1139 * reference to a Signature.
1141 * 1140 *
1142 * Note: this should be static but the AIX compiler doesn't like it (because it 1141 * Note: this should be static but the AIX compiler doesn't like it (because it
1143 * was forward-declared above); it is not meant to be exported, but this 1142 * was forward-declared above); it is not meant to be exported, but this
1144 * is the only way it will compile. 1143 * is the only way it will compile.
1145 */ 1144 */
1146 const SEC_ASN1Template ocsp_PointerToSignatureTemplate[] = { 1145 const SEC_ASN1Template ocsp_PointerToSignatureTemplate[] = {
1147 { SEC_ASN1_POINTER, 0, ocsp_SignatureTemplate } 1146 { SEC_ASN1_POINTER, 0, ocsp_SignatureTemplate }
1148 }; 1147 };
1149 1148
1150 /* 1149 /*
1151 * Request ::= SEQUENCE { 1150 * Request ::= SEQUENCE {
1152 * reqCert CertID, 1151 * reqCert CertID,
1153 * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } 1152 * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
1154 * 1153 *
1155 * Note: this should be static but the AIX compiler doesn't like it (because it 1154 * Note: this should be static but the AIX compiler doesn't like it (because it
1156 * was forward-declared above); it is not meant to be exported, but this 1155 * was forward-declared above); it is not meant to be exported, but this
1157 * is the only way it will compile. 1156 * is the only way it will compile.
1158 */ 1157 */
1159 const SEC_ASN1Template ocsp_SingleRequestTemplate[] = { 1158 const SEC_ASN1Template ocsp_SingleRequestTemplate[] = {
1160 { SEC_ASN1_SEQUENCE, 1159 { SEC_ASN1_SEQUENCE,
1161 » 0, NULL, sizeof(ocspSingleRequest) }, 1160 0, NULL, sizeof(ocspSingleRequest) },
1162 { SEC_ASN1_POINTER, 1161 { SEC_ASN1_POINTER,
1163 » offsetof(ocspSingleRequest, reqCert), 1162 offsetof(ocspSingleRequest, reqCert),
1164 » ocsp_CertIDTemplate }, 1163 ocsp_CertIDTemplate },
1165 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1164 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1166 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 1165 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
1167 » offsetof(ocspSingleRequest, singleRequestExtensions), 1166 offsetof(ocspSingleRequest, singleRequestExtensions),
1168 » CERT_SequenceOfCertExtensionTemplate }, 1167 CERT_SequenceOfCertExtensionTemplate },
1169 { 0 } 1168 { 0 }
1170 }; 1169 };
1171 1170
1172
1173 /* 1171 /*
1174 * This data structure and template (CertID) is used by both OCSP 1172 * This data structure and template (CertID) is used by both OCSP
1175 * requests and responses. It is the only one that is shared. 1173 * requests and responses. It is the only one that is shared.
1176 * 1174 *
1177 * CertID ::= SEQUENCE { 1175 * CertID ::= SEQUENCE {
1178 * hashAlgorithm AlgorithmIdentifier, 1176 * hashAlgorithm AlgorithmIdentifier,
1179 * issuerNameHash OCTET STRING, -- Hash of Issuer DN 1177 * issuerNameHash OCTET STRING, -- Hash of Issuer DN
1180 * issuerKeyHash OCTET STRING, -- Hash of Issuer public key 1178 * issuerKeyHash OCTET STRING, -- Hash of Issuer public key
1181 * serialNumber CertificateSerialNumber } 1179 * serialNumber CertificateSerialNumber }
1182 * 1180 *
1183 * CertificateSerialNumber ::= INTEGER 1181 * CertificateSerialNumber ::= INTEGER
1184 * 1182 *
1185 * Note: this should be static but the AIX compiler doesn't like it (because it 1183 * Note: this should be static but the AIX compiler doesn't like it (because it
1186 * was forward-declared above); it is not meant to be exported, but this 1184 * was forward-declared above); it is not meant to be exported, but this
1187 * is the only way it will compile. 1185 * is the only way it will compile.
1188 */ 1186 */
1189 const SEC_ASN1Template ocsp_CertIDTemplate[] = { 1187 const SEC_ASN1Template ocsp_CertIDTemplate[] = {
1190 { SEC_ASN1_SEQUENCE, 1188 { SEC_ASN1_SEQUENCE,
1191 » 0, NULL, sizeof(CERTOCSPCertID) }, 1189 0, NULL, sizeof(CERTOCSPCertID) },
1192 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 1190 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
1193 » offsetof(CERTOCSPCertID, hashAlgorithm), 1191 offsetof(CERTOCSPCertID, hashAlgorithm),
1194 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 1192 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
1195 { SEC_ASN1_OCTET_STRING, 1193 { SEC_ASN1_OCTET_STRING,
1196 » offsetof(CERTOCSPCertID, issuerNameHash) }, 1194 offsetof(CERTOCSPCertID, issuerNameHash) },
1197 { SEC_ASN1_OCTET_STRING, 1195 { SEC_ASN1_OCTET_STRING,
1198 » offsetof(CERTOCSPCertID, issuerKeyHash) }, 1196 offsetof(CERTOCSPCertID, issuerKeyHash) },
1199 { SEC_ASN1_INTEGER, 1197 { SEC_ASN1_INTEGER,
1200 » offsetof(CERTOCSPCertID, serialNumber) }, 1198 offsetof(CERTOCSPCertID, serialNumber) },
1201 { 0 } 1199 { 0 }
1202 }; 1200 };
1203 1201
1204
1205 /* 1202 /*
1206 * Response-related templates... 1203 * Response-related templates...
1207 */ 1204 */
1208 1205
1209 /* 1206 /*
1210 * OCSPResponse ::= SEQUENCE { 1207 * OCSPResponse ::= SEQUENCE {
1211 * responseStatus OCSPResponseStatus, 1208 * responseStatus OCSPResponseStatus,
1212 * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } 1209 * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
1213 */ 1210 */
1214 const SEC_ASN1Template ocsp_OCSPResponseTemplate[] = { 1211 const SEC_ASN1Template ocsp_OCSPResponseTemplate[] = {
1215 { SEC_ASN1_SEQUENCE, 1212 { SEC_ASN1_SEQUENCE,
1216 » 0, NULL, sizeof(CERTOCSPResponse) }, 1213 0, NULL, sizeof(CERTOCSPResponse) },
1217 { SEC_ASN1_ENUMERATED, 1214 { SEC_ASN1_ENUMERATED,
1218 » offsetof(CERTOCSPResponse, responseStatus) }, 1215 offsetof(CERTOCSPResponse, responseStatus) },
1219 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1216 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1220 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 1217 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
1221 » offsetof(CERTOCSPResponse, responseBytes), 1218 offsetof(CERTOCSPResponse, responseBytes),
1222 » ocsp_PointerToResponseBytesTemplate }, 1219 ocsp_PointerToResponseBytesTemplate },
1223 { 0 } 1220 { 0 }
1224 }; 1221 };
1225 1222
1226 /* 1223 /*
1227 * ResponseBytes ::= SEQUENCE { 1224 * ResponseBytes ::= SEQUENCE {
1228 * responseType OBJECT IDENTIFIER, 1225 * responseType OBJECT IDENTIFIER,
1229 * response OCTET STRING } 1226 * response OCTET STRING }
1230 */ 1227 */
1231 const SEC_ASN1Template ocsp_ResponseBytesTemplate[] = { 1228 const SEC_ASN1Template ocsp_ResponseBytesTemplate[] = {
1232 { SEC_ASN1_SEQUENCE, 1229 { SEC_ASN1_SEQUENCE,
1233 » 0, NULL, sizeof(ocspResponseBytes) }, 1230 0, NULL, sizeof(ocspResponseBytes) },
1234 { SEC_ASN1_OBJECT_ID, 1231 { SEC_ASN1_OBJECT_ID,
1235 » offsetof(ocspResponseBytes, responseType) }, 1232 offsetof(ocspResponseBytes, responseType) },
1236 { SEC_ASN1_OCTET_STRING, 1233 { SEC_ASN1_OCTET_STRING,
1237 » offsetof(ocspResponseBytes, response) }, 1234 offsetof(ocspResponseBytes, response) },
1238 { 0 } 1235 { 0 }
1239 }; 1236 };
1240 1237
1241 /* 1238 /*
1242 * This template is just an extra level to use in an explicitly-tagged 1239 * This template is just an extra level to use in an explicitly-tagged
1243 * reference to a ResponseBytes. 1240 * reference to a ResponseBytes.
1244 * 1241 *
1245 * Note: this should be static but the AIX compiler doesn't like it (because it 1242 * Note: this should be static but the AIX compiler doesn't like it (because it
1246 * was forward-declared above); it is not meant to be exported, but this 1243 * was forward-declared above); it is not meant to be exported, but this
1247 * is the only way it will compile. 1244 * is the only way it will compile.
1248 */ 1245 */
1249 const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = { 1246 const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = {
1250 { SEC_ASN1_POINTER, 0, ocsp_ResponseBytesTemplate } 1247 { SEC_ASN1_POINTER, 0, ocsp_ResponseBytesTemplate }
1251 }; 1248 };
1252 1249
1253 /* 1250 /*
1254 * BasicOCSPResponse ::= SEQUENCE { 1251 * BasicOCSPResponse ::= SEQUENCE {
1255 * tbsResponseData ResponseData, 1252 * tbsResponseData ResponseData,
1256 * signatureAlgorithm AlgorithmIdentifier, 1253 * signatureAlgorithm AlgorithmIdentifier,
1257 * signature BIT STRING, 1254 * signature BIT STRING,
1258 * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } 1255 * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
1259 */ 1256 */
1260 static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = { 1257 static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = {
1261 { SEC_ASN1_SEQUENCE, 1258 { SEC_ASN1_SEQUENCE,
1262 » 0, NULL, sizeof(ocspBasicOCSPResponse) }, 1259 0, NULL, sizeof(ocspBasicOCSPResponse) },
1263 { SEC_ASN1_ANY | SEC_ASN1_SAVE, 1260 { SEC_ASN1_ANY | SEC_ASN1_SAVE,
1264 » offsetof(ocspBasicOCSPResponse, tbsResponseDataDER) }, 1261 offsetof(ocspBasicOCSPResponse, tbsResponseDataDER) },
1265 { SEC_ASN1_POINTER, 1262 { SEC_ASN1_POINTER,
1266 » offsetof(ocspBasicOCSPResponse, tbsResponseData), 1263 offsetof(ocspBasicOCSPResponse, tbsResponseData),
1267 » ocsp_ResponseDataTemplate }, 1264 ocsp_ResponseDataTemplate },
1268 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 1265 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
1269 » offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm), 1266 offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
1270 » SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 1267 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
1271 { SEC_ASN1_BIT_STRING, 1268 { SEC_ASN1_BIT_STRING,
1272 » offsetof(ocspBasicOCSPResponse, responseSignature.signature) }, 1269 offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
1273 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1270 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1274 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1271 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
1275 » offsetof(ocspBasicOCSPResponse, responseSignature.derCerts), 1272 offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
1276 » SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) }, 1273 SEC_ASN1_SUB(SEC_SequenceOfAnyTemplate) },
1277 { 0 } 1274 { 0 }
1278 }; 1275 };
1279 1276
1280 /* 1277 /*
1281 * ResponseData ::= SEQUENCE { 1278 * ResponseData ::= SEQUENCE {
1282 * version [0] EXPLICIT Version DEFAULT v1, 1279 * version [0] EXPLICIT Version DEFAULT v1,
1283 * responderID ResponderID, 1280 * responderID ResponderID,
1284 * producedAt GeneralizedTime, 1281 * producedAt GeneralizedTime,
1285 * responses SEQUENCE OF SingleResponse, 1282 * responses SEQUENCE OF SingleResponse,
1286 * responseExtensions [1] EXPLICIT Extensions OPTIONAL } 1283 * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
1287 * 1284 *
1288 * Note: this should be static but the AIX compiler doesn't like it (because it 1285 * Note: this should be static but the AIX compiler doesn't like it (because it
1289 * was forward-declared above); it is not meant to be exported, but this 1286 * was forward-declared above); it is not meant to be exported, but this
1290 * is the only way it will compile. 1287 * is the only way it will compile.
1291 */ 1288 */
1292 const SEC_ASN1Template ocsp_ResponseDataTemplate[] = { 1289 const SEC_ASN1Template ocsp_ResponseDataTemplate[] = {
1293 { SEC_ASN1_SEQUENCE, 1290 { SEC_ASN1_SEQUENCE,
1294 » 0, NULL, sizeof(ocspResponseData) }, 1291 0, NULL, sizeof(ocspResponseData) },
1295 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |» » /* XXX DER_DEFAULT */ 1292 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
1296 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1293 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
1297 » offsetof(ocspResponseData, version), 1294 offsetof(ocspResponseData, version),
1298 » SEC_ASN1_SUB(SEC_IntegerTemplate) }, 1295 SEC_ASN1_SUB(SEC_IntegerTemplate) },
1299 { SEC_ASN1_ANY, 1296 { SEC_ASN1_ANY,
1300 » offsetof(ocspResponseData, derResponderID) }, 1297 offsetof(ocspResponseData, derResponderID) },
1301 { SEC_ASN1_GENERALIZED_TIME, 1298 { SEC_ASN1_GENERALIZED_TIME,
1302 » offsetof(ocspResponseData, producedAt) }, 1299 offsetof(ocspResponseData, producedAt) },
1303 { SEC_ASN1_SEQUENCE_OF, 1300 { SEC_ASN1_SEQUENCE_OF,
1304 » offsetof(ocspResponseData, responses), 1301 offsetof(ocspResponseData, responses),
1305 » ocsp_SingleResponseTemplate }, 1302 ocsp_SingleResponseTemplate },
1306 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1303 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1307 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 1304 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
1308 » offsetof(ocspResponseData, responseExtensions), 1305 offsetof(ocspResponseData, responseExtensions),
1309 » CERT_SequenceOfCertExtensionTemplate }, 1306 CERT_SequenceOfCertExtensionTemplate },
1310 { 0 } 1307 { 0 }
1311 }; 1308 };
1312 1309
1313 /* 1310 /*
1314 * ResponderID ::= CHOICE { 1311 * ResponderID ::= CHOICE {
1315 * byName [1] EXPLICIT Name, 1312 * byName [1] EXPLICIT Name,
1316 * byKey [2] EXPLICIT KeyHash } 1313 * byKey [2] EXPLICIT KeyHash }
1317 * 1314 *
1318 * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key 1315 * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
1319 * (excluding the tag and length fields) 1316 * (excluding the tag and length fields)
1320 * 1317 *
1321 * XXX Because the ASN.1 encoder and decoder currently do not provide 1318 * XXX Because the ASN.1 encoder and decoder currently do not provide
1322 * a way to automatically handle a CHOICE, we need to do it in two 1319 * a way to automatically handle a CHOICE, we need to do it in two
1323 * steps, looking at the type tag and feeding the exact choice back 1320 * steps, looking at the type tag and feeding the exact choice back
1324 * to the ASN.1 code. Hopefully that will change someday and this 1321 * to the ASN.1 code. Hopefully that will change someday and this
1325 * can all be simplified down into a single template. Anyway, for 1322 * can all be simplified down into a single template. Anyway, for
1326 * now we list each choice as its own template: 1323 * now we list each choice as its own template:
1327 */ 1324 */
1328 const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[] = { 1325 const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[] = {
1329 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 1326 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
1330 » offsetof(ocspResponderID, responderIDValue.name), 1327 offsetof(ocspResponderID, responderIDValue.name),
1331 » CERT_NameTemplate } 1328 CERT_NameTemplate }
1332 }; 1329 };
1333 const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[] = { 1330 const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[] = {
1334 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1331 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
1335 SEC_ASN1_XTRN | 2, 1332 SEC_ASN1_XTRN | 2,
1336 » offsetof(ocspResponderID, responderIDValue.keyHash), 1333 offsetof(ocspResponderID, responderIDValue.keyHash),
1337 » SEC_ASN1_SUB(SEC_OctetStringTemplate) } 1334 SEC_ASN1_SUB(SEC_OctetStringTemplate) }
1338 }; 1335 };
1339 static const SEC_ASN1Template ocsp_ResponderIDOtherTemplate[] = { 1336 static const SEC_ASN1Template ocsp_ResponderIDOtherTemplate[] = {
1340 { SEC_ASN1_ANY, 1337 { SEC_ASN1_ANY,
1341 » offsetof(ocspResponderID, responderIDValue.other) } 1338 offsetof(ocspResponderID, responderIDValue.other) }
1342 }; 1339 };
1343 1340
1344 /* Decode choice container, but leave x509 name object encoded */ 1341 /* Decode choice container, but leave x509 name object encoded */
1345 static const SEC_ASN1Template ocsp_ResponderIDDerNameTemplate[] = { 1342 static const SEC_ASN1Template ocsp_ResponderIDDerNameTemplate[] = {
1346 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1343 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
1347 SEC_ASN1_XTRN | 1, 0, SEC_ASN1_SUB(SEC_AnyTemplate) } 1344 SEC_ASN1_XTRN | 1,
1345 0, SEC_ASN1_SUB(SEC_AnyTemplate) }
1348 }; 1346 };
1349 1347
1350 /* 1348 /*
1351 * SingleResponse ::= SEQUENCE { 1349 * SingleResponse ::= SEQUENCE {
1352 * certID CertID, 1350 * certID CertID,
1353 * certStatus CertStatus, 1351 * certStatus CertStatus,
1354 * thisUpdate GeneralizedTime, 1352 * thisUpdate GeneralizedTime,
1355 * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, 1353 * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
1356 * singleExtensions [1] EXPLICIT Extensions OPTIONAL } 1354 * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
1357 * 1355 *
1358 * Note: this should be static but the AIX compiler doesn't like it (because it 1356 * Note: this should be static but the AIX compiler doesn't like it (because it
1359 * was forward-declared above); it is not meant to be exported, but this 1357 * was forward-declared above); it is not meant to be exported, but this
1360 * is the only way it will compile. 1358 * is the only way it will compile.
1361 */ 1359 */
1362 const SEC_ASN1Template ocsp_SingleResponseTemplate[] = { 1360 const SEC_ASN1Template ocsp_SingleResponseTemplate[] = {
1363 { SEC_ASN1_SEQUENCE, 1361 { SEC_ASN1_SEQUENCE,
1364 » 0, NULL, sizeof(CERTOCSPSingleResponse) }, 1362 0, NULL, sizeof(CERTOCSPSingleResponse) },
1365 { SEC_ASN1_POINTER, 1363 { SEC_ASN1_POINTER,
1366 » offsetof(CERTOCSPSingleResponse, certID), 1364 offsetof(CERTOCSPSingleResponse, certID),
1367 » ocsp_CertIDTemplate }, 1365 ocsp_CertIDTemplate },
1368 { SEC_ASN1_ANY, 1366 { SEC_ASN1_ANY,
1369 » offsetof(CERTOCSPSingleResponse, derCertStatus) }, 1367 offsetof(CERTOCSPSingleResponse, derCertStatus) },
1370 { SEC_ASN1_GENERALIZED_TIME, 1368 { SEC_ASN1_GENERALIZED_TIME,
1371 » offsetof(CERTOCSPSingleResponse, thisUpdate) }, 1369 offsetof(CERTOCSPSingleResponse, thisUpdate) },
1372 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1370 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1373 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1371 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
1374 » offsetof(CERTOCSPSingleResponse, nextUpdate), 1372 offsetof(CERTOCSPSingleResponse, nextUpdate),
1375 » SEC_ASN1_SUB(SEC_PointerToGeneralizedTimeTemplate) }, 1373 SEC_ASN1_SUB(SEC_PointerToGeneralizedTimeTemplate) },
1376 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1374 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1377 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 1375 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
1378 » offsetof(CERTOCSPSingleResponse, singleExtensions), 1376 offsetof(CERTOCSPSingleResponse, singleExtensions),
1379 » CERT_SequenceOfCertExtensionTemplate }, 1377 CERT_SequenceOfCertExtensionTemplate },
1380 { 0 } 1378 { 0 }
1381 }; 1379 };
1382 1380
1383 /* 1381 /*
1384 * CertStatus ::= CHOICE { 1382 * CertStatus ::= CHOICE {
1385 * good [0] IMPLICIT NULL, 1383 * good [0] IMPLICIT NULL,
1386 * revoked [1] IMPLICIT RevokedInfo, 1384 * revoked [1] IMPLICIT RevokedInfo,
1387 * unknown [2] IMPLICIT UnknownInfo } 1385 * unknown [2] IMPLICIT UnknownInfo }
1388 * 1386 *
1389 * Because the ASN.1 encoder and decoder currently do not provide 1387 * Because the ASN.1 encoder and decoder currently do not provide
1390 * a way to automatically handle a CHOICE, we need to do it in two 1388 * a way to automatically handle a CHOICE, we need to do it in two
1391 * steps, looking at the type tag and feeding the exact choice back 1389 * steps, looking at the type tag and feeding the exact choice back
1392 * to the ASN.1 code. Hopefully that will change someday and this 1390 * to the ASN.1 code. Hopefully that will change someday and this
1393 * can all be simplified down into a single template. Anyway, for 1391 * can all be simplified down into a single template. Anyway, for
1394 * now we list each choice as its own template: 1392 * now we list each choice as its own template:
1395 */ 1393 */
1396 static const SEC_ASN1Template ocsp_CertStatusGoodTemplate[] = { 1394 static const SEC_ASN1Template ocsp_CertStatusGoodTemplate[] = {
1397 { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1395 { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
1398 » offsetof(ocspCertStatus, certStatusInfo.goodInfo), 1396 offsetof(ocspCertStatus, certStatusInfo.goodInfo),
1399 » SEC_ASN1_SUB(SEC_NullTemplate) } 1397 SEC_ASN1_SUB(SEC_NullTemplate) }
1400 }; 1398 };
1401 static const SEC_ASN1Template ocsp_CertStatusRevokedTemplate[] = { 1399 static const SEC_ASN1Template ocsp_CertStatusRevokedTemplate[] = {
1402 { SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 1400 { SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
1403 » offsetof(ocspCertStatus, certStatusInfo.revokedInfo), 1401 offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
1404 » ocsp_RevokedInfoTemplate } 1402 ocsp_RevokedInfoTemplate }
1405 }; 1403 };
1406 static const SEC_ASN1Template ocsp_CertStatusUnknownTemplate[] = { 1404 static const SEC_ASN1Template ocsp_CertStatusUnknownTemplate[] = {
1407 { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, 1405 { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
1408 » offsetof(ocspCertStatus, certStatusInfo.unknownInfo), 1406 offsetof(ocspCertStatus, certStatusInfo.unknownInfo),
1409 » SEC_ASN1_SUB(SEC_NullTemplate) } 1407 SEC_ASN1_SUB(SEC_NullTemplate) }
1410 }; 1408 };
1411 static const SEC_ASN1Template ocsp_CertStatusOtherTemplate[] = { 1409 static const SEC_ASN1Template ocsp_CertStatusOtherTemplate[] = {
1412 { SEC_ASN1_POINTER | SEC_ASN1_XTRN, 1410 { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
1413 » offsetof(ocspCertStatus, certStatusInfo.otherInfo), 1411 offsetof(ocspCertStatus, certStatusInfo.otherInfo),
1414 » SEC_ASN1_SUB(SEC_AnyTemplate) } 1412 SEC_ASN1_SUB(SEC_AnyTemplate) }
1415 }; 1413 };
1416 1414
1417 /* 1415 /*
1418 * RevokedInfo ::= SEQUENCE { 1416 * RevokedInfo ::= SEQUENCE {
1419 * revocationTime GeneralizedTime, 1417 * revocationTime GeneralizedTime,
1420 * revocationReason [0] EXPLICIT CRLReason OPTIONAL } 1418 * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
1421 * 1419 *
1422 * Note: this should be static but the AIX compiler doesn't like it (because it 1420 * Note: this should be static but the AIX compiler doesn't like it (because it
1423 * was forward-declared above); it is not meant to be exported, but this 1421 * was forward-declared above); it is not meant to be exported, but this
1424 * is the only way it will compile. 1422 * is the only way it will compile.
1425 */ 1423 */
1426 const SEC_ASN1Template ocsp_RevokedInfoTemplate[] = { 1424 const SEC_ASN1Template ocsp_RevokedInfoTemplate[] = {
1427 { SEC_ASN1_SEQUENCE, 1425 { SEC_ASN1_SEQUENCE,
1428 » 0, NULL, sizeof(ocspRevokedInfo) }, 1426 0, NULL, sizeof(ocspRevokedInfo) },
1429 { SEC_ASN1_GENERALIZED_TIME, 1427 { SEC_ASN1_GENERALIZED_TIME,
1430 » offsetof(ocspRevokedInfo, revocationTime) }, 1428 offsetof(ocspRevokedInfo, revocationTime) },
1431 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 1429 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
1432 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1430 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
1433 SEC_ASN1_XTRN | 0, 1431 SEC_ASN1_XTRN | 0,
1434 » offsetof(ocspRevokedInfo, revocationReason), 1432 offsetof(ocspRevokedInfo, revocationReason),
1435 » SEC_ASN1_SUB(SEC_PointerToEnumeratedTemplate) }, 1433 SEC_ASN1_SUB(SEC_PointerToEnumeratedTemplate) },
1436 { 0 } 1434 { 0 }
1437 }; 1435 };
1438 1436
1439
1440 /* 1437 /*
1441 * OCSP-specific extension templates: 1438 * OCSP-specific extension templates:
1442 */ 1439 */
1443 1440
1444 /* 1441 /*
1445 * ServiceLocator ::= SEQUENCE { 1442 * ServiceLocator ::= SEQUENCE {
1446 * issuer Name, 1443 * issuer Name,
1447 * locator AuthorityInfoAccessSyntax OPTIONAL } 1444 * locator AuthorityInfoAccessSyntax OPTIONAL }
1448 */ 1445 */
1449 static const SEC_ASN1Template ocsp_ServiceLocatorTemplate[] = { 1446 static const SEC_ASN1Template ocsp_ServiceLocatorTemplate[] = {
1450 { SEC_ASN1_SEQUENCE, 1447 { SEC_ASN1_SEQUENCE,
1451 » 0, NULL, sizeof(ocspServiceLocator) }, 1448 0, NULL, sizeof(ocspServiceLocator) },
1452 { SEC_ASN1_POINTER, 1449 { SEC_ASN1_POINTER,
1453 » offsetof(ocspServiceLocator, issuer), 1450 offsetof(ocspServiceLocator, issuer),
1454 » CERT_NameTemplate }, 1451 CERT_NameTemplate },
1455 { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, 1452 { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
1456 » offsetof(ocspServiceLocator, locator) }, 1453 offsetof(ocspServiceLocator, locator) },
1457 { 0 } 1454 { 0 }
1458 }; 1455 };
1459 1456
1460
1461 /* 1457 /*
1462 * REQUEST SUPPORT FUNCTIONS (encode/create/decode/destroy): 1458 * REQUEST SUPPORT FUNCTIONS (encode/create/decode/destroy):
1463 */ 1459 */
1464 1460
1465 /* 1461 /*
1466 * FUNCTION: CERT_EncodeOCSPRequest 1462 * FUNCTION: CERT_EncodeOCSPRequest
1467 * DER encodes an OCSP Request, possibly adding a signature as well. 1463 * DER encodes an OCSP Request, possibly adding a signature as well.
1468 * XXX Signing is not yet supported, however; see comments in code. 1464 * XXX Signing is not yet supported, however; see comments in code.
1469 * INPUTS: 1465 * INPUTS:
1470 * PLArenaPool *arena 1466 * PLArenaPool *arena
1471 * The return value is allocated from here. 1467 * The return value is allocated from here.
1472 * If a NULL is passed in, allocation is done from the heap instead. 1468 * If a NULL is passed in, allocation is done from the heap instead.
1473 * CERTOCSPRequest *request 1469 * CERTOCSPRequest *request
1474 * The request to be encoded. 1470 * The request to be encoded.
1475 * void *pwArg 1471 * void *pwArg
1476 * Pointer to argument for password prompting, if needed. (Definitely 1472 * Pointer to argument for password prompting, if needed. (Definitely
1477 * not needed if not signing.) 1473 * not needed if not signing.)
1478 * RETURN: 1474 * RETURN:
1479 * Returns a NULL on error and a pointer to the SECItem with the 1475 * Returns a NULL on error and a pointer to the SECItem with the
1480 * encoded value otherwise. Any error is likely to be low-level 1476 * encoded value otherwise. Any error is likely to be low-level
1481 * (e.g. no memory). 1477 * (e.g. no memory).
1482 */ 1478 */
1483 SECItem * 1479 SECItem *
1484 CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request, 1480 CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
1485 » » void *pwArg) 1481 void *pwArg)
1486 { 1482 {
1487 SECStatus rv; 1483 SECStatus rv;
1488 1484
1489 /* XXX All of these should generate errors if they fail. */ 1485 /* XXX All of these should generate errors if they fail. */
1490 PORT_Assert(request); 1486 PORT_Assert(request);
1491 PORT_Assert(request->tbsRequest); 1487 PORT_Assert(request->tbsRequest);
1492 1488
1493 if (request->tbsRequest->extensionHandle != NULL) { 1489 if (request->tbsRequest->extensionHandle != NULL) {
1494 » rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle); 1490 rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle);
1495 » request->tbsRequest->extensionHandle = NULL; 1491 request->tbsRequest->extensionHandle = NULL;
1496 » if (rv != SECSuccess) 1492 if (rv != SECSuccess)
1497 » return NULL; 1493 return NULL;
1498 } 1494 }
1499 1495
1500 /* 1496 /*
1501 * XXX When signed requests are supported and request->optionalSignature 1497 * XXX When signed requests are supported and request->optionalSignature
1502 * is not NULL: 1498 * is not NULL:
1503 * - need to encode tbsRequest->requestorName 1499 * - need to encode tbsRequest->requestorName
1504 * - need to encode tbsRequest 1500 * - need to encode tbsRequest
1505 * - need to sign that encoded result (using cert in sig), filling in the 1501 * - need to sign that encoded result (using cert in sig), filling in the
1506 * request->optionalSignature structure with the result, the signing 1502 * request->optionalSignature structure with the result, the signing
1507 * algorithm and (perhaps?) the cert (and its chain?) in derCerts 1503 * algorithm and (perhaps?) the cert (and its chain?) in derCerts
1508 */ 1504 */
1509 1505
1510 return SEC_ASN1EncodeItem(arena, NULL, request, ocsp_OCSPRequestTemplate); 1506 return SEC_ASN1EncodeItem(arena, NULL, request, ocsp_OCSPRequestTemplate);
1511 } 1507 }
1512 1508
1513
1514 /* 1509 /*
1515 * FUNCTION: CERT_DecodeOCSPRequest 1510 * FUNCTION: CERT_DecodeOCSPRequest
1516 * Decode a DER encoded OCSP Request. 1511 * Decode a DER encoded OCSP Request.
1517 * INPUTS: 1512 * INPUTS:
1518 * SECItem *src 1513 * SECItem *src
1519 * Pointer to a SECItem holding DER encoded OCSP Request. 1514 * Pointer to a SECItem holding DER encoded OCSP Request.
1520 * RETURN: 1515 * RETURN:
1521 * Returns a pointer to a CERTOCSPRequest containing the decoded request. 1516 * Returns a pointer to a CERTOCSPRequest containing the decoded request.
1522 * On error, returns NULL. Most likely error is trouble decoding 1517 * On error, returns NULL. Most likely error is trouble decoding
1523 * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory). 1518 * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory).
1524 */ 1519 */
1525 CERTOCSPRequest * 1520 CERTOCSPRequest *
1526 CERT_DecodeOCSPRequest(const SECItem *src) 1521 CERT_DecodeOCSPRequest(const SECItem *src)
1527 { 1522 {
1528 PLArenaPool *arena = NULL; 1523 PLArenaPool *arena = NULL;
1529 SECStatus rv = SECFailure; 1524 SECStatus rv = SECFailure;
1530 CERTOCSPRequest *dest = NULL; 1525 CERTOCSPRequest *dest = NULL;
1531 int i; 1526 int i;
1532 SECItem newSrc; 1527 SECItem newSrc;
1533 1528
1534 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1529 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1535 if (arena == NULL) { 1530 if (arena == NULL) {
1536 » goto loser; 1531 goto loser;
1537 } 1532 }
1538 dest = (CERTOCSPRequest *) PORT_ArenaZAlloc(arena, 1533 dest = (CERTOCSPRequest *)PORT_ArenaZAlloc(arena,
1539 » » » » » » sizeof(CERTOCSPRequest)); 1534 sizeof(CERTOCSPRequest));
1540 if (dest == NULL) { 1535 if (dest == NULL) {
1541 » goto loser; 1536 goto loser;
1542 } 1537 }
1543 dest->arena = arena; 1538 dest->arena = arena;
1544 1539
1545 /* copy the DER into the arena, since Quick DER returns data that points 1540 /* copy the DER into the arena, since Quick DER returns data that points
1546 into the DER input, which may get freed by the caller */ 1541 into the DER input, which may get freed by the caller */
1547 rv = SECITEM_CopyItem(arena, &newSrc, src); 1542 rv = SECITEM_CopyItem(arena, &newSrc, src);
1548 if ( rv != SECSuccess ) { 1543 if (rv != SECSuccess) {
1549 » goto loser; 1544 goto loser;
1550 } 1545 }
1551 1546
1552 rv = SEC_QuickDERDecodeItem(arena, dest, ocsp_OCSPRequestTemplate, &newSrc); 1547 rv = SEC_QuickDERDecodeItem(arena, dest, ocsp_OCSPRequestTemplate, &newSrc);
1553 if (rv != SECSuccess) { 1548 if (rv != SECSuccess) {
1554 » if (PORT_GetError() == SEC_ERROR_BAD_DER) 1549 if (PORT_GetError() == SEC_ERROR_BAD_DER)
1555 » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); 1550 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
1556 » goto loser; 1551 goto loser;
1557 } 1552 }
1558 1553
1559 /* 1554 /*
1560 * XXX I would like to find a way to get rid of the necessity 1555 * XXX I would like to find a way to get rid of the necessity
1561 * of doing this copying of the arena pointer. 1556 * of doing this copying of the arena pointer.
1562 */ 1557 */
1563 for (i = 0; dest->tbsRequest->requestList[i] != NULL; i++) { 1558 for (i = 0; dest->tbsRequest->requestList[i] != NULL; i++) {
1564 » dest->tbsRequest->requestList[i]->arena = arena; 1559 dest->tbsRequest->requestList[i]->arena = arena;
1565 } 1560 }
1566 1561
1567 return dest; 1562 return dest;
1568 1563
1569 loser: 1564 loser:
1570 if (arena != NULL) { 1565 if (arena != NULL) {
1571 » PORT_FreeArena(arena, PR_FALSE); 1566 PORT_FreeArena(arena, PR_FALSE);
1572 } 1567 }
1573 return NULL; 1568 return NULL;
1574 } 1569 }
1575 1570
1576 SECStatus 1571 SECStatus
1577 CERT_DestroyOCSPCertID(CERTOCSPCertID* certID) 1572 CERT_DestroyOCSPCertID(CERTOCSPCertID *certID)
1578 { 1573 {
1579 if (certID && certID->poolp) { 1574 if (certID && certID->poolp) {
1580 » PORT_FreeArena(certID->poolp, PR_FALSE); 1575 PORT_FreeArena(certID->poolp, PR_FALSE);
1581 » return SECSuccess; 1576 return SECSuccess;
1582 } 1577 }
1583 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1578 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1584 return SECFailure; 1579 return SECFailure;
1585 } 1580 }
1586 1581
1587 /* 1582 /*
1588 * Digest data using the specified algorithm. 1583 * Digest data using the specified algorithm.
1589 * The necessary storage for the digest data is allocated. If "fill" is 1584 * The necessary storage for the digest data is allocated. If "fill" is
1590 * non-null, the data is put there, otherwise a SECItem is allocated. 1585 * non-null, the data is put there, otherwise a SECItem is allocated.
1591 * Allocation from "arena" if it is non-null, heap otherwise. Any problem 1586 * Allocation from "arena" if it is non-null, heap otherwise. Any problem
1592 * results in a NULL being returned (and an appropriate error set). 1587 * results in a NULL being returned (and an appropriate error set).
1593 */ 1588 */
1594 1589
1595 SECItem * 1590 SECItem *
1596 ocsp_DigestValue(PLArenaPool *arena, SECOidTag digestAlg, 1591 ocsp_DigestValue(PLArenaPool *arena, SECOidTag digestAlg,
1597 SECItem *fill, const SECItem *src) 1592 SECItem *fill, const SECItem *src)
1598 { 1593 {
1599 const SECHashObject *digestObject; 1594 const SECHashObject *digestObject;
1600 SECItem *result = NULL; 1595 SECItem *result = NULL;
1601 void *mark = NULL; 1596 void *mark = NULL;
1602 void *digestBuff = NULL; 1597 void *digestBuff = NULL;
1603 1598
1604 if ( arena != NULL ) { 1599 if (arena != NULL) {
1605 mark = PORT_ArenaMark(arena); 1600 mark = PORT_ArenaMark(arena);
1606 } 1601 }
1607 1602
1608 digestObject = HASH_GetHashObjectByOidTag(digestAlg); 1603 digestObject = HASH_GetHashObjectByOidTag(digestAlg);
1609 if ( digestObject == NULL ) { 1604 if (digestObject == NULL) {
1610 goto loser; 1605 goto loser;
1611 } 1606 }
1612 1607
1613 if (fill == NULL || fill->data == NULL) { 1608 if (fill == NULL || fill->data == NULL) {
1614 » result = SECITEM_AllocItem(arena, fill, digestObject->length); 1609 result = SECITEM_AllocItem(arena, fill, digestObject->length);
1615 » if ( result == NULL ) { 1610 if (result == NULL) {
1616 » goto loser; 1611 goto loser;
1617 » } 1612 }
1618 » digestBuff = result->data; 1613 digestBuff = result->data;
1619 } else { 1614 } else {
1620 » if (fill->len < digestObject->length) { 1615 if (fill->len < digestObject->length) {
1621 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 1616 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1622 » goto loser; 1617 goto loser;
1623 » } 1618 }
1624 » digestBuff = fill->data; 1619 digestBuff = fill->data;
1625 } 1620 }
1626 1621
1627 if (PK11_HashBuf(digestAlg, digestBuff, 1622 if (PK11_HashBuf(digestAlg, digestBuff,
1628 src->data, src->len) != SECSuccess) { 1623 src->data, src->len) != SECSuccess) {
1629 goto loser; 1624 goto loser;
1630 } 1625 }
1631 1626
1632 if ( arena != NULL ) { 1627 if (arena != NULL) {
1633 PORT_ArenaUnmark(arena, mark); 1628 PORT_ArenaUnmark(arena, mark);
1634 } 1629 }
1635 1630
1636 if (result == NULL) { 1631 if (result == NULL) {
1637 result = fill; 1632 result = fill;
1638 } 1633 }
1639 return result; 1634 return result;
1640 1635
1641 loser: 1636 loser:
1642 if (arena != NULL) { 1637 if (arena != NULL) {
1643 PORT_ArenaRelease(arena, mark); 1638 PORT_ArenaRelease(arena, mark);
1644 } else { 1639 } else {
1645 if (result != NULL) { 1640 if (result != NULL) {
1646 SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE); 1641 SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
1647 } 1642 }
1648 } 1643 }
1649 return(NULL); 1644 return (NULL);
1650 } 1645 }
1651 1646
1652 /* 1647 /*
1653 * Digest the cert's subject public key using the specified algorithm. 1648 * Digest the cert's subject public key using the specified algorithm.
1654 * The necessary storage for the digest data is allocated. If "fill" is 1649 * The necessary storage for the digest data is allocated. If "fill" is
1655 * non-null, the data is put there, otherwise a SECItem is allocated. 1650 * non-null, the data is put there, otherwise a SECItem is allocated.
1656 * Allocation from "arena" if it is non-null, heap otherwise. Any problem 1651 * Allocation from "arena" if it is non-null, heap otherwise. Any problem
1657 * results in a NULL being returned (and an appropriate error set). 1652 * results in a NULL being returned (and an appropriate error set).
1658 */ 1653 */
1659 SECItem * 1654 SECItem *
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 { 1701 {
1707 CERTOCSPCertID *certID; 1702 CERTOCSPCertID *certID;
1708 CERTCertificate *issuerCert = NULL; 1703 CERTCertificate *issuerCert = NULL;
1709 void *mark = PORT_ArenaMark(arena); 1704 void *mark = PORT_ArenaMark(arena);
1710 SECStatus rv; 1705 SECStatus rv;
1711 1706
1712 PORT_Assert(arena != NULL); 1707 PORT_Assert(arena != NULL);
1713 1708
1714 certID = PORT_ArenaZNew(arena, CERTOCSPCertID); 1709 certID = PORT_ArenaZNew(arena, CERTOCSPCertID);
1715 if (certID == NULL) { 1710 if (certID == NULL) {
1716 » goto loser; 1711 goto loser;
1717 } 1712 }
1718 1713
1719 rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1, 1714 rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1,
1720 » » » NULL); 1715 NULL);
1721 if (rv != SECSuccess) { 1716 if (rv != SECSuccess) {
1722 » goto loser; 1717 goto loser;
1723 } 1718 }
1724 1719
1725 issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA); 1720 issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
1726 if (issuerCert == NULL) { 1721 if (issuerCert == NULL) {
1727 » goto loser; 1722 goto loser;
1728 } 1723 }
1729 1724
1730 if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_SHA1, 1725 if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_SHA1,
1731 &(certID->issuerNameHash)) == NULL) { 1726 &(certID->issuerNameHash)) == NULL) {
1732 goto loser; 1727 goto loser;
1733 } 1728 }
1734 certID->issuerSHA1NameHash.data = certID->issuerNameHash.data; 1729 certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
1735 certID->issuerSHA1NameHash.len = certID->issuerNameHash.len; 1730 certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;
1736 1731
1737 if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD5, 1732 if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD5,
1738 &(certID->issuerMD5NameHash)) == NULL) { 1733 &(certID->issuerMD5NameHash)) == NULL) {
1739 goto loser; 1734 goto loser;
1740 } 1735 }
1741 1736
1742 if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD2, 1737 if (CERT_GetSubjectNameDigest(arena, issuerCert, SEC_OID_MD2,
1743 &(certID->issuerMD2NameHash)) == NULL) { 1738 &(certID->issuerMD2NameHash)) == NULL) {
1744 goto loser; 1739 goto loser;
1745 } 1740 }
1746 1741
1747 if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_SHA1, 1742 if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_SHA1,
1748 » » » » &certID->issuerKeyHash) == NULL) { 1743 &certID->issuerKeyHash) == NULL) {
1749 » goto loser; 1744 goto loser;
1750 } 1745 }
1751 certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data; 1746 certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
1752 certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len; 1747 certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
1753 /* cache the other two hash algorithms as well */ 1748 /* cache the other two hash algorithms as well */
1754 if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD5, 1749 if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD5,
1755 » » » » &certID->issuerMD5KeyHash) == NULL) { 1750 &certID->issuerMD5KeyHash) == NULL) {
1756 » goto loser; 1751 goto loser;
1757 } 1752 }
1758 if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD2, 1753 if (CERT_GetSubjectPublicKeyDigest(arena, issuerCert, SEC_OID_MD2,
1759 » » » » &certID->issuerMD2KeyHash) == NULL) { 1754 &certID->issuerMD2KeyHash) == NULL) {
1760 » goto loser; 1755 goto loser;
1761 } 1756 }
1762 1757
1763
1764 /* now we are done with issuerCert */ 1758 /* now we are done with issuerCert */
1765 CERT_DestroyCertificate(issuerCert); 1759 CERT_DestroyCertificate(issuerCert);
1766 issuerCert = NULL; 1760 issuerCert = NULL;
1767 1761
1768 rv = SECITEM_CopyItem(arena, &certID->serialNumber, &cert->serialNumber); 1762 rv = SECITEM_CopyItem(arena, &certID->serialNumber, &cert->serialNumber);
1769 if (rv != SECSuccess) { 1763 if (rv != SECSuccess) {
1770 » goto loser; 1764 goto loser;
1771 } 1765 }
1772 1766
1773 PORT_ArenaUnmark(arena, mark); 1767 PORT_ArenaUnmark(arena, mark);
1774 return certID; 1768 return certID;
1775 1769
1776 loser: 1770 loser:
1777 if (issuerCert != NULL) { 1771 if (issuerCert != NULL) {
1778 » CERT_DestroyCertificate(issuerCert); 1772 CERT_DestroyCertificate(issuerCert);
1779 } 1773 }
1780 PORT_ArenaRelease(arena, mark); 1774 PORT_ArenaRelease(arena, mark);
1781 return NULL; 1775 return NULL;
1782 } 1776 }
1783 1777
1784 CERTOCSPCertID* 1778 CERTOCSPCertID *
1785 CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time) 1779 CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time)
1786 { 1780 {
1787 PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1781 PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1788 CERTOCSPCertID *certID; 1782 CERTOCSPCertID *certID;
1789 PORT_Assert(arena != NULL); 1783 PORT_Assert(arena != NULL);
1790 if (!arena) 1784 if (!arena)
1791 » return NULL; 1785 return NULL;
1792 1786
1793 certID = ocsp_CreateCertID(arena, cert, time); 1787 certID = ocsp_CreateCertID(arena, cert, time);
1794 if (!certID) { 1788 if (!certID) {
1795 » PORT_FreeArena(arena, PR_FALSE); 1789 PORT_FreeArena(arena, PR_FALSE);
1796 » return NULL; 1790 return NULL;
1797 } 1791 }
1798 certID->poolp = arena; 1792 certID->poolp = arena;
1799 return certID; 1793 return certID;
1800 } 1794 }
1801 1795
1802 static CERTOCSPCertID * 1796 static CERTOCSPCertID *
1803 cert_DupOCSPCertID(const CERTOCSPCertID *src) 1797 cert_DupOCSPCertID(const CERTOCSPCertID *src)
1804 { 1798 {
1805 CERTOCSPCertID *dest; 1799 CERTOCSPCertID *dest;
1806 PLArenaPool *arena = NULL; 1800 PLArenaPool *arena = NULL;
1807 1801
1808 if (!src) { 1802 if (!src) {
1809 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1803 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1810 return NULL; 1804 return NULL;
1811 } 1805 }
1812 1806
1813 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1807 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1814 if (!arena) 1808 if (!arena)
1815 goto loser; 1809 goto loser;
1816 1810
1817 dest = PORT_ArenaZNew(arena, CERTOCSPCertID); 1811 dest = PORT_ArenaZNew(arena, CERTOCSPCertID);
1818 if (!dest) 1812 if (!dest)
1819 goto loser; 1813 goto loser;
1820 1814
1821 #define DUPHELP(element) \ 1815 #define DUPHELP(element) \
1822 if (src->element.data && \ 1816 if (src->element.data && \
1823 SECITEM_CopyItem(arena, &dest->element, &src->element) \ 1817 SECITEM_CopyItem(arena, &dest->element, &src->element) != \
1824 != SECSuccess) { \ 1818 SECSuccess) { \
1825 goto loser; \ 1819 goto loser; \
1826 } 1820 }
1827 1821
1828 DUPHELP(hashAlgorithm.algorithm) 1822 DUPHELP(hashAlgorithm.algorithm)
1829 DUPHELP(hashAlgorithm.parameters) 1823 DUPHELP(hashAlgorithm.parameters)
1830 DUPHELP(issuerNameHash) 1824 DUPHELP(issuerNameHash)
1831 DUPHELP(issuerKeyHash) 1825 DUPHELP(issuerKeyHash)
1832 DUPHELP(serialNumber) 1826 DUPHELP(serialNumber)
1833 DUPHELP(issuerSHA1NameHash) 1827 DUPHELP(issuerSHA1NameHash)
1834 DUPHELP(issuerMD5NameHash) 1828 DUPHELP(issuerMD5NameHash)
1835 DUPHELP(issuerMD2NameHash) 1829 DUPHELP(issuerMD2NameHash)
1836 DUPHELP(issuerSHA1KeyHash) 1830 DUPHELP(issuerSHA1KeyHash)
1837 DUPHELP(issuerMD5KeyHash) 1831 DUPHELP(issuerMD5KeyHash)
1838 DUPHELP(issuerMD2KeyHash) 1832 DUPHELP(issuerMD2KeyHash)
1839 1833
1840 dest->poolp = arena; 1834 dest->poolp = arena;
1841 return dest; 1835 return dest;
1842 1836
1843 loser: 1837 loser:
1844 if (arena) 1838 if (arena)
1845 PORT_FreeArena(arena, PR_FALSE); 1839 PORT_FreeArena(arena, PR_FALSE);
1846 PORT_SetError(PR_OUT_OF_MEMORY_ERROR); 1840 PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
1847 return NULL; 1841 return NULL;
1848 } 1842 }
1849 1843
1850 /* 1844 /*
1851 * Callback to set Extensions in request object 1845 * Callback to set Extensions in request object
1852 */ 1846 */
1853 void SetSingleReqExts(void *object, CERTCertExtension **exts) 1847 void
1848 SetSingleReqExts(void *object, CERTCertExtension **exts)
1854 { 1849 {
1855 ocspSingleRequest *singleRequest = 1850 ocspSingleRequest *singleRequest =
1856 (ocspSingleRequest *)object; 1851 (ocspSingleRequest *)object;
1857 1852
1858 singleRequest->singleRequestExtensions = exts; 1853 singleRequest->singleRequestExtensions = exts;
1859 } 1854 }
1860 1855
1861 /* 1856 /*
1862 * Add the Service Locator extension to the singleRequestExtensions 1857 * Add the Service Locator extension to the singleRequestExtensions
1863 * for the given singleRequest. 1858 * for the given singleRequest.
1864 * 1859 *
1865 * All errors are internal or low-level problems (e.g. no memory). 1860 * All errors are internal or low-level problems (e.g. no memory).
1866 */ 1861 */
1867 static SECStatus 1862 static SECStatus
1868 ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest, 1863 ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest,
1869 » » » » CERTCertificate *cert) 1864 CERTCertificate *cert)
1870 { 1865 {
1871 ocspServiceLocator *serviceLocator = NULL; 1866 ocspServiceLocator *serviceLocator = NULL;
1872 void *extensionHandle = NULL; 1867 void *extensionHandle = NULL;
1873 SECStatus rv = SECFailure; 1868 SECStatus rv = SECFailure;
1874 1869
1875 serviceLocator = PORT_ZNew(ocspServiceLocator); 1870 serviceLocator = PORT_ZNew(ocspServiceLocator);
1876 if (serviceLocator == NULL) 1871 if (serviceLocator == NULL)
1877 » goto loser; 1872 goto loser;
1878 1873
1879 /* 1874 /*
1880 * Normally it would be a bad idea to do a direct reference like 1875 * Normally it would be a bad idea to do a direct reference like
1881 * this rather than allocate and copy the name *or* at least dup 1876 * this rather than allocate and copy the name *or* at least dup
1882 * a reference of the cert. But all we need is to be able to read 1877 * a reference of the cert. But all we need is to be able to read
1883 * the issuer name during the encoding we are about to do, so a 1878 * the issuer name during the encoding we are about to do, so a
1884 * copy is just a waste of time. 1879 * copy is just a waste of time.
1885 */ 1880 */
1886 serviceLocator->issuer = &cert->issuer; 1881 serviceLocator->issuer = &cert->issuer;
1887 1882
1888 rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS, 1883 rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
1889 » » » » &serviceLocator->locator); 1884 &serviceLocator->locator);
1890 if (rv != SECSuccess) { 1885 if (rv != SECSuccess) {
1891 » if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) 1886 if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
1892 » goto loser; 1887 goto loser;
1893 } 1888 }
1894 1889
1895 /* prepare for following loser gotos */ 1890 /* prepare for following loser gotos */
1896 rv = SECFailure; 1891 rv = SECFailure;
1897 PORT_SetError(0); 1892 PORT_SetError(0);
1898 1893
1899 extensionHandle = cert_StartExtensions(singleRequest, 1894 extensionHandle = cert_StartExtensions(singleRequest,
1900 singleRequest->arena, SetSingleReqExts); 1895 singleRequest->arena, SetSingleReqExt s);
1901 if (extensionHandle == NULL) 1896 if (extensionHandle == NULL)
1902 » goto loser; 1897 goto loser;
1903 1898
1904 rv = CERT_EncodeAndAddExtension(extensionHandle, 1899 rv = CERT_EncodeAndAddExtension(extensionHandle,
1905 » » » » SEC_OID_PKIX_OCSP_SERVICE_LOCATOR, 1900 SEC_OID_PKIX_OCSP_SERVICE_LOCATOR,
1906 » » » » serviceLocator, PR_FALSE, 1901 serviceLocator, PR_FALSE,
1907 » » » » ocsp_ServiceLocatorTemplate); 1902 ocsp_ServiceLocatorTemplate);
1908 1903
1909 loser: 1904 loser:
1910 if (extensionHandle != NULL) { 1905 if (extensionHandle != NULL) {
1911 » /* 1906 /*
1912 * Either way we have to finish out the extension context (so it gets 1907 * Either way we have to finish out the extension context (so it gets
1913 * freed). But careful not to override any already-set bad status. 1908 * freed). But careful not to override any already-set bad status.
1914 */ 1909 */
1915 » SECStatus tmprv = CERT_FinishExtensions(extensionHandle); 1910 SECStatus tmprv = CERT_FinishExtensions(extensionHandle);
1916 » if (rv == SECSuccess) 1911 if (rv == SECSuccess)
1917 » rv = tmprv; 1912 rv = tmprv;
1918 } 1913 }
1919 1914
1920 /* 1915 /*
1921 * Finally, free the serviceLocator structure itself and we are done. 1916 * Finally, free the serviceLocator structure itself and we are done.
1922 */ 1917 */
1923 if (serviceLocator != NULL) { 1918 if (serviceLocator != NULL) {
1924 » if (serviceLocator->locator.data != NULL) 1919 if (serviceLocator->locator.data != NULL)
1925 » SECITEM_FreeItem(&serviceLocator->locator, PR_FALSE); 1920 SECITEM_FreeItem(&serviceLocator->locator, PR_FALSE);
1926 » PORT_Free(serviceLocator); 1921 PORT_Free(serviceLocator);
1927 } 1922 }
1928 1923
1929 return rv; 1924 return rv;
1930 } 1925 }
1931 1926
1932 /* 1927 /*
1933 * Creates an array of ocspSingleRequest based on a list of certs. 1928 * Creates an array of ocspSingleRequest based on a list of certs.
1934 * Note that the code which later compares the request list with the 1929 * Note that the code which later compares the request list with the
1935 * response expects this array to be in the exact same order as the 1930 * response expects this array to be in the exact same order as the
1936 * certs are found in the list. It would be harder to change that 1931 * certs are found in the list. It would be harder to change that
1937 * order than preserve it, but since the requirement is not obvious, 1932 * order than preserve it, but since the requirement is not obvious,
1938 * it deserves to be mentioned. 1933 * it deserves to be mentioned.
1939 * 1934 *
1940 * Any problem causes a null return and error set: 1935 * Any problem causes a null return and error set:
1941 * SEC_ERROR_UNKNOWN_ISSUER 1936 * SEC_ERROR_UNKNOWN_ISSUER
1942 * Other errors are low-level problems (no memory, bad database, etc.). 1937 * Other errors are low-level problems (no memory, bad database, etc.).
1943 */ 1938 */
1944 static ocspSingleRequest ** 1939 static ocspSingleRequest **
1945 ocsp_CreateSingleRequestList(PLArenaPool *arena, CERTCertList *certList, 1940 ocsp_CreateSingleRequestList(PLArenaPool *arena, CERTCertList *certList,
1946 PRTime time, PRBool includeLocator) 1941 PRTime time, PRBool includeLocator)
1947 { 1942 {
1948 ocspSingleRequest **requestList = NULL; 1943 ocspSingleRequest **requestList = NULL;
1949 CERTCertListNode *node = NULL; 1944 CERTCertListNode *node = NULL;
1950 int i, count; 1945 int i, count;
1951 void *mark = PORT_ArenaMark(arena); 1946 void *mark = PORT_ArenaMark(arena);
1952 1947
1953 node = CERT_LIST_HEAD(certList); 1948 node = CERT_LIST_HEAD(certList);
1954 for (count = 0; !CERT_LIST_END(node, certList); count++) { 1949 for (count = 0; !CERT_LIST_END(node, certList); count++) {
1955 node = CERT_LIST_NEXT(node); 1950 node = CERT_LIST_NEXT(node);
1956 } 1951 }
1957 1952
1958 if (count == 0) 1953 if (count == 0)
1959 » goto loser; 1954 goto loser;
1960 1955
1961 requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, count + 1); 1956 requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, count + 1);
1962 if (requestList == NULL) 1957 if (requestList == NULL)
1963 » goto loser; 1958 goto loser;
1964 1959
1965 node = CERT_LIST_HEAD(certList); 1960 node = CERT_LIST_HEAD(certList);
1966 for (i = 0; !CERT_LIST_END(node, certList); i++) { 1961 for (i = 0; !CERT_LIST_END(node, certList); i++) {
1967 requestList[i] = PORT_ArenaZNew(arena, ocspSingleRequest); 1962 requestList[i] = PORT_ArenaZNew(arena, ocspSingleRequest);
1968 if (requestList[i] == NULL) 1963 if (requestList[i] == NULL)
1969 goto loser; 1964 goto loser;
1970 1965
1971 OCSP_TRACE(("OCSP CERT_CreateOCSPRequest %s\n", node->cert->subjectName) ); 1966 OCSP_TRACE(("OCSP CERT_CreateOCSPRequest %s\n", node->cert->subjectName) );
1972 requestList[i]->arena = arena; 1967 requestList[i]->arena = arena;
1973 requestList[i]->reqCert = ocsp_CreateCertID(arena, node->cert, time); 1968 requestList[i]->reqCert = ocsp_CreateCertID(arena, node->cert, time);
(...skipping 17 matching lines...) Expand all
1991 requestList[i] = NULL; 1986 requestList[i] = NULL;
1992 return requestList; 1987 return requestList;
1993 1988
1994 loser: 1989 loser:
1995 PORT_ArenaRelease(arena, mark); 1990 PORT_ArenaRelease(arena, mark);
1996 return NULL; 1991 return NULL;
1997 } 1992 }
1998 1993
1999 static ocspSingleRequest ** 1994 static ocspSingleRequest **
2000 ocsp_CreateRequestFromCert(PLArenaPool *arena, 1995 ocsp_CreateRequestFromCert(PLArenaPool *arena,
2001 CERTOCSPCertID *certID, 1996 CERTOCSPCertID *certID,
2002 CERTCertificate *singleCert, 1997 CERTCertificate *singleCert,
2003 PRTime time, 1998 PRTime time,
2004 PRBool includeLocator) 1999 PRBool includeLocator)
2005 { 2000 {
2006 ocspSingleRequest **requestList = NULL; 2001 ocspSingleRequest **requestList = NULL;
2007 void *mark = PORT_ArenaMark(arena); 2002 void *mark = PORT_ArenaMark(arena);
2008 PORT_Assert(certID != NULL && singleCert != NULL); 2003 PORT_Assert(certID != NULL && singleCert != NULL);
2009 2004
2010 /* meaning of value 2: one entry + one end marker */ 2005 /* meaning of value 2: one entry + one end marker */
2011 requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, 2); 2006 requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, 2);
2012 if (requestList == NULL) 2007 if (requestList == NULL)
2013 goto loser; 2008 goto loser;
2014 requestList[0] = PORT_ArenaZNew(arena, ocspSingleRequest); 2009 requestList[0] = PORT_ArenaZNew(arena, ocspSingleRequest);
2015 if (requestList[0] == NULL) 2010 if (requestList[0] == NULL)
2016 goto loser; 2011 goto loser;
2017 requestList[0]->arena = arena; 2012 requestList[0]->arena = arena;
2018 /* certID will live longer than the request */ 2013 /* certID will live longer than the request */
2019 requestList[0]->reqCert = certID; 2014 requestList[0]->reqCert = certID;
2020 2015
2021 if (includeLocator == PR_TRUE) { 2016 if (includeLocator == PR_TRUE) {
2022 SECStatus rv; 2017 SECStatus rv;
2023 rv = ocsp_AddServiceLocatorExtension(requestList[0], singleCert); 2018 rv = ocsp_AddServiceLocatorExtension(requestList[0], singleCert);
2024 if (rv != SECSuccess) 2019 if (rv != SECSuccess)
2025 goto loser; 2020 goto loser;
2026 } 2021 }
2027 2022
2028 PORT_ArenaUnmark(arena, mark); 2023 PORT_ArenaUnmark(arena, mark);
2029 requestList[1] = NULL; 2024 requestList[1] = NULL;
(...skipping 30 matching lines...) Expand all
2060 return request; 2055 return request;
2061 2056
2062 loser: 2057 loser:
2063 if (arena != NULL) { 2058 if (arena != NULL) {
2064 PORT_FreeArena(arena, PR_FALSE); 2059 PORT_FreeArena(arena, PR_FALSE);
2065 } 2060 }
2066 return NULL; 2061 return NULL;
2067 } 2062 }
2068 2063
2069 CERTOCSPRequest * 2064 CERTOCSPRequest *
2070 cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID, 2065 cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
2071 CERTCertificate *singleCert, 2066 CERTCertificate *singleCert,
2072 PRTime time, 2067 PRTime time,
2073 PRBool addServiceLocator, 2068 PRBool addServiceLocator,
2074 CERTCertificate *signerCert) 2069 CERTCertificate *signerCert)
2075 { 2070 {
2076 CERTOCSPRequest *request; 2071 CERTOCSPRequest *request;
2077 OCSP_TRACE(("OCSP cert_CreateSingleCertOCSPRequest %s\n", singleCert->subjec tName)); 2072 OCSP_TRACE(("OCSP cert_CreateSingleCertOCSPRequest %s\n", singleCert->subjec tName));
2078 2073
2079 /* XXX Support for signerCert may be implemented later, 2074 /* XXX Support for signerCert may be implemented later,
2080 * see also the comment in CERT_CreateOCSPRequest. 2075 * see also the comment in CERT_CreateOCSPRequest.
2081 */ 2076 */
2082 if (signerCert != NULL) { 2077 if (signerCert != NULL) {
2083 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 2078 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
2084 return NULL; 2079 return NULL;
2085 } 2080 }
2086 2081
2087 request = ocsp_prepareEmptyOCSPRequest(); 2082 request = ocsp_prepareEmptyOCSPRequest();
2088 if (!request) 2083 if (!request)
2089 return NULL; 2084 return NULL;
2090 /* 2085 /*
2091 * Version 1 is the default, so we need not fill in a version number. 2086 * Version 1 is the default, so we need not fill in a version number.
2092 * Now create the list of single requests, one for each cert. 2087 * Now create the list of single requests, one for each cert.
2093 */ 2088 */
2094 request->tbsRequest->requestList = 2089 request->tbsRequest->requestList =
2095 ocsp_CreateRequestFromCert(request->arena, 2090 ocsp_CreateRequestFromCert(request->arena,
2096 certID, 2091 certID,
2097 singleCert, 2092 singleCert,
2098 time, 2093 time,
2099 addServiceLocator); 2094 addServiceLocator);
2100 if (request->tbsRequest->requestList == NULL) { 2095 if (request->tbsRequest->requestList == NULL) {
2101 PORT_FreeArena(request->arena, PR_FALSE); 2096 PORT_FreeArena(request->arena, PR_FALSE);
2102 return NULL; 2097 return NULL;
2103 } 2098 }
2104 return request; 2099 return request;
2105 } 2100 }
2106 2101
2107 /* 2102 /*
2108 * FUNCTION: CERT_CreateOCSPRequest 2103 * FUNCTION: CERT_CreateOCSPRequest
2109 * Creates a CERTOCSPRequest, requesting the status of the certs in 2104 * Creates a CERTOCSPRequest, requesting the status of the certs in
2110 * the given list. 2105 * the given list.
2111 * INPUTS: 2106 * INPUTS:
2112 * CERTCertList *certList 2107 * CERTCertList *certList
2113 * A list of certs for which status will be requested. 2108 * A list of certs for which status will be requested.
2114 * Note that all of these certificates should have the same issuer, 2109 * Note that all of these certificates should have the same issuer,
2115 * or it's expected the response will be signed by a trusted responder. 2110 * or it's expected the response will be signed by a trusted responder.
2116 * If the certs need to be broken up into multiple requests, that 2111 * If the certs need to be broken up into multiple requests, that
2117 * must be handled by the caller (and thus by having multiple calls 2112 * must be handled by the caller (and thus by having multiple calls
2118 * to this routine), who knows about where the request(s) are being 2113 * to this routine), who knows about where the request(s) are being
2119 * sent and whether there are any trusted responders in place. 2114 * sent and whether there are any trusted responders in place.
2120 * PRTime time 2115 * PRTime time
2121 * Indicates the time for which the certificate status is to be 2116 * Indicates the time for which the certificate status is to be
2122 * determined -- this may be used in the search for the cert's issuer 2117 * determined -- this may be used in the search for the cert's issuer
2123 * but has no effect on the request itself. 2118 * but has no effect on the request itself.
2124 * PRBool addServiceLocator 2119 * PRBool addServiceLocator
2125 * If true, the Service Locator extension should be added to the 2120 * If true, the Service Locator extension should be added to the
2126 * single request(s) for each cert. 2121 * single request(s) for each cert.
2127 * CERTCertificate *signerCert 2122 * CERTCertificate *signerCert
2128 * If non-NULL, means sign the request using this cert. Otherwise, 2123 * If non-NULL, means sign the request using this cert. Otherwise,
2129 * do not sign. 2124 * do not sign.
2130 * XXX note that request signing is not yet supported; see comment in code 2125 * XXX note that request signing is not yet supported; see comment in code
2131 * RETURN: 2126 * RETURN:
2132 * A pointer to a CERTOCSPRequest structure containing an OCSP request 2127 * A pointer to a CERTOCSPRequest structure containing an OCSP request
2133 * for the cert list. On error, null is returned, with an error set 2128 * for the cert list. On error, null is returned, with an error set
2134 * indicating the reason. This is likely SEC_ERROR_UNKNOWN_ISSUER. 2129 * indicating the reason. This is likely SEC_ERROR_UNKNOWN_ISSUER.
2135 * (The issuer is needed to create a request for the certificate.) 2130 * (The issuer is needed to create a request for the certificate.)
2136 * Other errors are low-level problems (no memory, bad database, etc.). 2131 * Other errors are low-level problems (no memory, bad database, etc.).
2137 */ 2132 */
2138 CERTOCSPRequest * 2133 CERTOCSPRequest *
2139 CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time, 2134 CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
2140 » » PRBool addServiceLocator, 2135 PRBool addServiceLocator,
2141 » » CERTCertificate *signerCert) 2136 CERTCertificate *signerCert)
2142 { 2137 {
2143 CERTOCSPRequest *request = NULL; 2138 CERTOCSPRequest *request = NULL;
2144 2139
2145 if (!certList) { 2140 if (!certList) {
2146 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2141 PORT_SetError(SEC_ERROR_INVALID_ARGS);
2147 return NULL; 2142 return NULL;
2148 } 2143 }
2149 /* 2144 /*
2150 * XXX When we are prepared to put signing of requests back in, 2145 * XXX When we are prepared to put signing of requests back in,
2151 * we will need to allocate a signature 2146 * we will need to allocate a signature
2152 * structure for the request, fill in the "derCerts" field in it, 2147 * structure for the request, fill in the "derCerts" field in it,
2153 * save the signerCert there, as well as fill in the "requestorName" 2148 * save the signerCert there, as well as fill in the "requestorName"
2154 * field of the tbsRequest. 2149 * field of the tbsRequest.
2155 */ 2150 */
2156 if (signerCert != NULL) { 2151 if (signerCert != NULL) {
2157 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 2152 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
2158 return NULL; 2153 return NULL;
2159 } 2154 }
2160 request = ocsp_prepareEmptyOCSPRequest(); 2155 request = ocsp_prepareEmptyOCSPRequest();
2161 if (!request) 2156 if (!request)
2162 return NULL; 2157 return NULL;
2163 /* 2158 /*
2164 * Now create the list of single requests, one for each cert. 2159 * Now create the list of single requests, one for each cert.
2165 */ 2160 */
2166 request->tbsRequest->requestList = 2161 request->tbsRequest->requestList =
2167 ocsp_CreateSingleRequestList(request->arena, 2162 ocsp_CreateSingleRequestList(request->arena,
2168 certList, 2163 certList,
2169 time, 2164 time,
2170 addServiceLocator); 2165 addServiceLocator);
2171 if (request->tbsRequest->requestList == NULL) { 2166 if (request->tbsRequest->requestList == NULL) {
2172 PORT_FreeArena(request->arena, PR_FALSE); 2167 PORT_FreeArena(request->arena, PR_FALSE);
2173 return NULL; 2168 return NULL;
2174 } 2169 }
2175 return request; 2170 return request;
2176 } 2171 }
2177 2172
2178 /* 2173 /*
2179 * FUNCTION: CERT_AddOCSPAcceptableResponses 2174 * FUNCTION: CERT_AddOCSPAcceptableResponses
2180 * Add the AcceptableResponses extension to an OCSP Request. 2175 * Add the AcceptableResponses extension to an OCSP Request.
2181 * INPUTS: 2176 * INPUTS:
2182 * CERTOCSPRequest *request 2177 * CERTOCSPRequest *request
2183 * The request to which the extension should be added. 2178 * The request to which the extension should be added.
2184 * ... 2179 * ...
2185 * A list (of one or more) of SECOidTag -- each of the response types 2180 * A list (of one or more) of SECOidTag -- each of the response types
2186 * to be added. The last OID *must* be SEC_OID_PKIX_OCSP_BASIC_RESPONSE. 2181 * to be added. The last OID *must* be SEC_OID_PKIX_OCSP_BASIC_RESPONSE.
2187 * (This marks the end of the list, and it must be specified because a 2182 * (This marks the end of the list, and it must be specified because a
2188 * client conforming to the OCSP standard is required to handle the basic 2183 * client conforming to the OCSP standard is required to handle the basic
2189 * response type.) The OIDs are not checked in any way. 2184 * response type.) The OIDs are not checked in any way.
2190 * RETURN: 2185 * RETURN:
2191 * SECSuccess if the extension is added; SECFailure if anything goes wrong. 2186 * SECSuccess if the extension is added; SECFailure if anything goes wrong.
2192 * All errors are internal or low-level problems (e.g. no memory). 2187 * All errors are internal or low-level problems (e.g. no memory).
2193 */ 2188 */
2194 2189
2195 void SetRequestExts(void *object, CERTCertExtension **exts) 2190 void
2191 SetRequestExts(void *object, CERTCertExtension **exts)
2196 { 2192 {
2197 CERTOCSPRequest *request = (CERTOCSPRequest *)object; 2193 CERTOCSPRequest *request = (CERTOCSPRequest *)object;
2198 2194
2199 request->tbsRequest->requestExtensions = exts; 2195 request->tbsRequest->requestExtensions = exts;
2200 } 2196 }
2201 2197
2202 SECStatus 2198 SECStatus
2203 CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request, 2199 CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
2204 » » » » SECOidTag responseType0, ...) 2200 SECOidTag responseType0, ...)
2205 { 2201 {
2206 void *extHandle; 2202 void *extHandle;
2207 va_list ap; 2203 va_list ap;
2208 int i, count; 2204 int i, count;
2209 SECOidTag responseType; 2205 SECOidTag responseType;
2210 SECOidData *responseOid; 2206 SECOidData *responseOid;
2211 SECItem **acceptableResponses = NULL; 2207 SECItem **acceptableResponses = NULL;
2212 SECStatus rv = SECFailure; 2208 SECStatus rv = SECFailure;
2213 2209
2214 extHandle = request->tbsRequest->extensionHandle; 2210 extHandle = request->tbsRequest->extensionHandle;
2215 if (extHandle == NULL) { 2211 if (extHandle == NULL) {
2216 » extHandle = cert_StartExtensions(request, request->arena, SetRequestExts ); 2212 extHandle = cert_StartExtensions(request, request->arena, SetRequestExts );
2217 » if (extHandle == NULL) 2213 if (extHandle == NULL)
2218 » goto loser; 2214 goto loser;
2219 } 2215 }
2220 2216
2221 /* Count number of OIDS going into the extension value. */ 2217 /* Count number of OIDS going into the extension value. */
2222 count = 1; 2218 count = 1;
2223 if (responseType0 != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) { 2219 if (responseType0 != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
2224 » va_start(ap, responseType0); 2220 va_start(ap, responseType0);
2225 » do { 2221 do {
2226 » count++; 2222 count++;
2227 » responseType = va_arg(ap, SECOidTag); 2223 responseType = va_arg(ap, SECOidTag);
2228 » } while (responseType != SEC_OID_PKIX_OCSP_BASIC_RESPONSE); 2224 } while (responseType != SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
2229 » va_end(ap); 2225 va_end(ap);
2230 } 2226 }
2231 2227
2232 acceptableResponses = PORT_NewArray(SECItem *, count + 1); 2228 acceptableResponses = PORT_NewArray(SECItem *, count + 1);
2233 if (acceptableResponses == NULL) 2229 if (acceptableResponses == NULL)
2234 » goto loser; 2230 goto loser;
2235 2231
2236 i = 0; 2232 i = 0;
2237 responseOid = SECOID_FindOIDByTag(responseType0); 2233 responseOid = SECOID_FindOIDByTag(responseType0);
2238 acceptableResponses[i++] = &(responseOid->oid); 2234 acceptableResponses[i++] = &(responseOid->oid);
2239 if (count > 1) { 2235 if (count > 1) {
2240 » va_start(ap, responseType0); 2236 va_start(ap, responseType0);
2241 » for ( ; i < count; i++) { 2237 for (; i < count; i++) {
2242 » responseType = va_arg(ap, SECOidTag); 2238 responseType = va_arg(ap, SECOidTag);
2243 » responseOid = SECOID_FindOIDByTag(responseType); 2239 responseOid = SECOID_FindOIDByTag(responseType);
2244 » acceptableResponses[i] = &(responseOid->oid); 2240 acceptableResponses[i] = &(responseOid->oid);
2245 » } 2241 }
2246 » va_end(ap); 2242 va_end(ap);
2247 } 2243 }
2248 acceptableResponses[i] = NULL; 2244 acceptableResponses[i] = NULL;
2249 2245
2250 rv = CERT_EncodeAndAddExtension(extHandle, SEC_OID_PKIX_OCSP_RESPONSE, 2246 rv = CERT_EncodeAndAddExtension(extHandle, SEC_OID_PKIX_OCSP_RESPONSE,
2251 &acceptableResponses, PR_FALSE, 2247 &acceptableResponses, PR_FALSE,
2252 SEC_ASN1_GET(SEC_SequenceOfObjectIDTemplate)); 2248 SEC_ASN1_GET(SEC_SequenceOfObjectIDTemplate) );
2253 if (rv != SECSuccess) 2249 if (rv != SECSuccess)
2254 » goto loser; 2250 goto loser;
2255 2251
2256 PORT_Free(acceptableResponses); 2252 PORT_Free(acceptableResponses);
2257 if (request->tbsRequest->extensionHandle == NULL) 2253 if (request->tbsRequest->extensionHandle == NULL)
2258 » request->tbsRequest->extensionHandle = extHandle; 2254 request->tbsRequest->extensionHandle = extHandle;
2259 return SECSuccess; 2255 return SECSuccess;
2260 2256
2261 loser: 2257 loser:
2262 if (acceptableResponses != NULL) 2258 if (acceptableResponses != NULL)
2263 » PORT_Free(acceptableResponses); 2259 PORT_Free(acceptableResponses);
2264 if (extHandle != NULL) 2260 if (extHandle != NULL)
2265 » (void) CERT_FinishExtensions(extHandle); 2261 (void)CERT_FinishExtensions(extHandle);
2266 return rv; 2262 return rv;
2267 } 2263 }
2268 2264
2269
2270 /* 2265 /*
2271 * FUNCTION: CERT_DestroyOCSPRequest 2266 * FUNCTION: CERT_DestroyOCSPRequest
2272 * Frees an OCSP Request structure. 2267 * Frees an OCSP Request structure.
2273 * INPUTS: 2268 * INPUTS:
2274 * CERTOCSPRequest *request 2269 * CERTOCSPRequest *request
2275 * Pointer to CERTOCSPRequest to be freed. 2270 * Pointer to CERTOCSPRequest to be freed.
2276 * RETURN: 2271 * RETURN:
2277 * No return value; no errors. 2272 * No return value; no errors.
2278 */ 2273 */
2279 void 2274 void
2280 CERT_DestroyOCSPRequest(CERTOCSPRequest *request) 2275 CERT_DestroyOCSPRequest(CERTOCSPRequest *request)
2281 { 2276 {
2282 if (request == NULL) 2277 if (request == NULL)
2283 » return; 2278 return;
2284 2279
2285 if (request->tbsRequest != NULL) { 2280 if (request->tbsRequest != NULL) {
2286 » if (request->tbsRequest->requestorName != NULL) 2281 if (request->tbsRequest->requestorName != NULL)
2287 » CERT_DestroyGeneralNameList(request->tbsRequest->requestorName); 2282 CERT_DestroyGeneralNameList(request->tbsRequest->requestorName);
2288 » if (request->tbsRequest->extensionHandle != NULL) 2283 if (request->tbsRequest->extensionHandle != NULL)
2289 » (void) CERT_FinishExtensions(request->tbsRequest->extensionHandle); 2284 (void)CERT_FinishExtensions(request->tbsRequest->extensionHandle);
2290 } 2285 }
2291 2286
2292 if (request->optionalSignature != NULL) { 2287 if (request->optionalSignature != NULL) {
2293 » if (request->optionalSignature->cert != NULL) 2288 if (request->optionalSignature->cert != NULL)
2294 » CERT_DestroyCertificate(request->optionalSignature->cert); 2289 CERT_DestroyCertificate(request->optionalSignature->cert);
2295 2290
2296 » /* 2291 /*
2297 * XXX Need to free derCerts? Or do they come out of arena? 2292 * XXX Need to free derCerts? Or do they come out of arena?
2298 * (Currently we never fill in derCerts, which is why the 2293 * (Currently we never fill in derCerts, which is why the
2299 * answer is not obvious. Once we do, add any necessary code 2294 * answer is not obvious. Once we do, add any necessary code
2300 * here and remove this comment.) 2295 * here and remove this comment.)
2301 */ 2296 */
2302 } 2297 }
2303 2298
2304 /* 2299 /*
2305 * We should actually never have a request without an arena, 2300 * We should actually never have a request without an arena,
2306 * but check just in case. (If there isn't one, there is not 2301 * but check just in case. (If there isn't one, there is not
2307 * much we can do about it...) 2302 * much we can do about it...)
2308 */ 2303 */
2309 PORT_Assert(request->arena != NULL); 2304 PORT_Assert(request->arena != NULL);
2310 if (request->arena != NULL) 2305 if (request->arena != NULL)
2311 » PORT_FreeArena(request->arena, PR_FALSE); 2306 PORT_FreeArena(request->arena, PR_FALSE);
2312 } 2307 }
2313 2308
2314
2315 /* 2309 /*
2316 * RESPONSE SUPPORT FUNCTIONS (encode/create/decode/destroy): 2310 * RESPONSE SUPPORT FUNCTIONS (encode/create/decode/destroy):
2317 */ 2311 */
2318 2312
2319 /* 2313 /*
2320 * Helper function for encoding or decoding a ResponderID -- based on the 2314 * Helper function for encoding or decoding a ResponderID -- based on the
2321 * given type, return the associated template for that choice. 2315 * given type, return the associated template for that choice.
2322 */ 2316 */
2323 static const SEC_ASN1Template * 2317 static const SEC_ASN1Template *
2324 ocsp_ResponderIDTemplateByType(CERTOCSPResponderIDType responderIDType) 2318 ocsp_ResponderIDTemplateByType(CERTOCSPResponderIDType responderIDType)
2325 { 2319 {
2326 const SEC_ASN1Template *responderIDTemplate; 2320 const SEC_ASN1Template *responderIDTemplate;
2327 2321
2328 switch (responderIDType) { 2322 switch (responderIDType) {
2329 » case ocspResponderID_byName: 2323 case ocspResponderID_byName:
2330 » responderIDTemplate = ocsp_ResponderIDByNameTemplate; 2324 responderIDTemplate = ocsp_ResponderIDByNameTemplate;
2331 » break; 2325 break;
2332 » case ocspResponderID_byKey: 2326 case ocspResponderID_byKey:
2333 » responderIDTemplate = ocsp_ResponderIDByKeyTemplate; 2327 responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
2334 » break; 2328 break;
2335 » case ocspResponderID_other: 2329 case ocspResponderID_other:
2336 » default: 2330 default:
2337 » PORT_Assert(responderIDType == ocspResponderID_other); 2331 PORT_Assert(responderIDType == ocspResponderID_other);
2338 » responderIDTemplate = ocsp_ResponderIDOtherTemplate; 2332 responderIDTemplate = ocsp_ResponderIDOtherTemplate;
2339 » break; 2333 break;
2340 } 2334 }
2341 2335
2342 return responderIDTemplate; 2336 return responderIDTemplate;
2343 } 2337 }
2344 2338
2345 /* 2339 /*
2346 * Helper function for encoding or decoding a CertStatus -- based on the 2340 * Helper function for encoding or decoding a CertStatus -- based on the
2347 * given type, return the associated template for that choice. 2341 * given type, return the associated template for that choice.
2348 */ 2342 */
2349 static const SEC_ASN1Template * 2343 static const SEC_ASN1Template *
2350 ocsp_CertStatusTemplateByType(ocspCertStatusType certStatusType) 2344 ocsp_CertStatusTemplateByType(ocspCertStatusType certStatusType)
2351 { 2345 {
2352 const SEC_ASN1Template *certStatusTemplate; 2346 const SEC_ASN1Template *certStatusTemplate;
2353 2347
2354 switch (certStatusType) { 2348 switch (certStatusType) {
2355 » case ocspCertStatus_good: 2349 case ocspCertStatus_good:
2356 » certStatusTemplate = ocsp_CertStatusGoodTemplate; 2350 certStatusTemplate = ocsp_CertStatusGoodTemplate;
2357 » break; 2351 break;
2358 » case ocspCertStatus_revoked: 2352 case ocspCertStatus_revoked:
2359 » certStatusTemplate = ocsp_CertStatusRevokedTemplate; 2353 certStatusTemplate = ocsp_CertStatusRevokedTemplate;
2360 » break; 2354 break;
2361 » case ocspCertStatus_unknown: 2355 case ocspCertStatus_unknown:
2362 » certStatusTemplate = ocsp_CertStatusUnknownTemplate; 2356 certStatusTemplate = ocsp_CertStatusUnknownTemplate;
2363 » break; 2357 break;
2364 » case ocspCertStatus_other: 2358 case ocspCertStatus_other:
2365 » default: 2359 default:
2366 » PORT_Assert(certStatusType == ocspCertStatus_other); 2360 PORT_Assert(certStatusType == ocspCertStatus_other);
2367 » certStatusTemplate = ocsp_CertStatusOtherTemplate; 2361 certStatusTemplate = ocsp_CertStatusOtherTemplate;
2368 » break; 2362 break;
2369 } 2363 }
2370 2364
2371 return certStatusTemplate; 2365 return certStatusTemplate;
2372 } 2366 }
2373 2367
2374 /* 2368 /*
2375 * Helper function for decoding a certStatus -- turn the actual DER tag 2369 * Helper function for decoding a certStatus -- turn the actual DER tag
2376 * into our local translation. 2370 * into our local translation.
2377 */ 2371 */
2378 static ocspCertStatusType 2372 static ocspCertStatusType
2379 ocsp_CertStatusTypeByTag(int derTag) 2373 ocsp_CertStatusTypeByTag(int derTag)
2380 { 2374 {
2381 ocspCertStatusType certStatusType; 2375 ocspCertStatusType certStatusType;
2382 2376
2383 switch (derTag) { 2377 switch (derTag) {
2384 » case 0: 2378 case 0:
2385 » certStatusType = ocspCertStatus_good; 2379 certStatusType = ocspCertStatus_good;
2386 » break; 2380 break;
2387 » case 1: 2381 case 1:
2388 » certStatusType = ocspCertStatus_revoked; 2382 certStatusType = ocspCertStatus_revoked;
2389 » break; 2383 break;
2390 » case 2: 2384 case 2:
2391 » certStatusType = ocspCertStatus_unknown; 2385 certStatusType = ocspCertStatus_unknown;
2392 » break; 2386 break;
2393 » default: 2387 default:
2394 » certStatusType = ocspCertStatus_other; 2388 certStatusType = ocspCertStatus_other;
2395 » break; 2389 break;
2396 } 2390 }
2397 2391
2398 return certStatusType; 2392 return certStatusType;
2399 } 2393 }
2400 2394
2401 /* 2395 /*
2402 * Helper function for decoding SingleResponses -- they each contain 2396 * Helper function for decoding SingleResponses -- they each contain
2403 * a status which is encoded as CHOICE, which needs to be decoded "by hand". 2397 * a status which is encoded as CHOICE, which needs to be decoded "by hand".
2404 * 2398 *
2405 * Note -- on error, this routine does not release the memory it may 2399 * Note -- on error, this routine does not release the memory it may
2406 * have allocated; it expects its caller to do that. 2400 * have allocated; it expects its caller to do that.
2407 */ 2401 */
2408 static SECStatus 2402 static SECStatus
2409 ocsp_FinishDecodingSingleResponses(PLArenaPool *reqArena, 2403 ocsp_FinishDecodingSingleResponses(PLArenaPool *reqArena,
2410 » » » » CERTOCSPSingleResponse **responses) 2404 CERTOCSPSingleResponse **responses)
2411 { 2405 {
2412 ocspCertStatus *certStatus; 2406 ocspCertStatus *certStatus;
2413 ocspCertStatusType certStatusType; 2407 ocspCertStatusType certStatusType;
2414 const SEC_ASN1Template *certStatusTemplate; 2408 const SEC_ASN1Template *certStatusTemplate;
2415 int derTag; 2409 int derTag;
2416 int i; 2410 int i;
2417 SECStatus rv = SECFailure; 2411 SECStatus rv = SECFailure;
2418 2412
2419 if (!reqArena) { 2413 if (!reqArena) {
2420 PORT_SetError(SEC_ERROR_INVALID_ARGS); 2414 PORT_SetError(SEC_ERROR_INVALID_ARGS);
2421 return SECFailure; 2415 return SECFailure;
2422 } 2416 }
2423 2417
2424 if (responses == NULL)» » » /* nothing to do */ 2418 if (responses == NULL) /* nothing to do */
2425 » return SECSuccess; 2419 return SECSuccess;
2426 2420
2427 for (i = 0; responses[i] != NULL; i++) { 2421 for (i = 0; responses[i] != NULL; i++) {
2428 SECItem* newStatus; 2422 SECItem *newStatus;
2429 » /* 2423 /*
2430 * The following assert points out internal errors (problems in 2424 * The following assert points out internal errors (problems in
2431 * the template definitions or in the ASN.1 decoder itself, etc.). 2425 * the template definitions or in the ASN.1 decoder itself, etc.).
2432 */ 2426 */
2433 » PORT_Assert(responses[i]->derCertStatus.data != NULL); 2427 PORT_Assert(responses[i]->derCertStatus.data != NULL);
2434 2428
2435 » derTag = responses[i]->derCertStatus.data[0] & SEC_ASN1_TAGNUM_MASK; 2429 derTag = responses[i]->derCertStatus.data[0] & SEC_ASN1_TAGNUM_MASK;
2436 » certStatusType = ocsp_CertStatusTypeByTag(derTag); 2430 certStatusType = ocsp_CertStatusTypeByTag(derTag);
2437 » certStatusTemplate = ocsp_CertStatusTemplateByType(certStatusType); 2431 certStatusTemplate = ocsp_CertStatusTemplateByType(certStatusType);
2438 2432
2439 » certStatus = PORT_ArenaZAlloc(reqArena, sizeof(ocspCertStatus)); 2433 certStatus = PORT_ArenaZAlloc(reqArena, sizeof(ocspCertStatus));
2440 » if (certStatus == NULL) { 2434 if (certStatus == NULL) {
2441 » goto loser; 2435 goto loser;
2442 » } 2436 }
2443 newStatus = SECITEM_ArenaDupItem(reqArena, &responses[i]->derCertStatus) ; 2437 newStatus = SECITEM_ArenaDupItem(reqArena, &responses[i]->derCertStatus) ;
2444 if (!newStatus) { 2438 if (!newStatus) {
2445 goto loser; 2439 goto loser;
2446 } 2440 }
2447 » rv = SEC_QuickDERDecodeItem(reqArena, certStatus, certStatusTemplate, 2441 rv = SEC_QuickDERDecodeItem(reqArena, certStatus, certStatusTemplate,
2448 » » » » newStatus); 2442 newStatus);
2449 » if (rv != SECSuccess) { 2443 if (rv != SECSuccess) {
2450 » if (PORT_GetError() == SEC_ERROR_BAD_DER) 2444 if (PORT_GetError() == SEC_ERROR_BAD_DER)
2451 » » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); 2445 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
2452 » goto loser; 2446 goto loser;
2453 » } 2447 }
2454 2448
2455 » certStatus->certStatusType = certStatusType; 2449 certStatus->certStatusType = certStatusType;
2456 » responses[i]->certStatus = certStatus; 2450 responses[i]->certStatus = certStatus;
2457 } 2451 }
2458 2452
2459 return SECSuccess; 2453 return SECSuccess;
2460 2454
2461 loser: 2455 loser:
2462 return rv; 2456 return rv;
2463 } 2457 }
2464 2458
2465 /* 2459 /*
2466 * Helper function for decoding a responderID -- turn the actual DER tag 2460 * Helper function for decoding a responderID -- turn the actual DER tag
2467 * into our local translation. 2461 * into our local translation.
2468 */ 2462 */
2469 static CERTOCSPResponderIDType 2463 static CERTOCSPResponderIDType
2470 ocsp_ResponderIDTypeByTag(int derTag) 2464 ocsp_ResponderIDTypeByTag(int derTag)
2471 { 2465 {
2472 CERTOCSPResponderIDType responderIDType; 2466 CERTOCSPResponderIDType responderIDType;
2473 2467
2474 switch (derTag) { 2468 switch (derTag) {
2475 » case 1: 2469 case 1:
2476 » responderIDType = ocspResponderID_byName; 2470 responderIDType = ocspResponderID_byName;
2477 » break; 2471 break;
2478 » case 2: 2472 case 2:
2479 » responderIDType = ocspResponderID_byKey; 2473 responderIDType = ocspResponderID_byKey;
2480 » break; 2474 break;
2481 » default: 2475 default:
2482 » responderIDType = ocspResponderID_other; 2476 responderIDType = ocspResponderID_other;
2483 » break; 2477 break;
2484 } 2478 }
2485 2479
2486 return responderIDType; 2480 return responderIDType;
2487 } 2481 }
2488 2482
2489 /* 2483 /*
2490 * Decode "src" as a BasicOCSPResponse, returning the result. 2484 * Decode "src" as a BasicOCSPResponse, returning the result.
2491 */ 2485 */
2492 static ocspBasicOCSPResponse * 2486 static ocspBasicOCSPResponse *
2493 ocsp_DecodeBasicOCSPResponse(PLArenaPool *arena, SECItem *src) 2487 ocsp_DecodeBasicOCSPResponse(PLArenaPool *arena, SECItem *src)
2494 { 2488 {
2495 void *mark; 2489 void *mark;
2496 ocspBasicOCSPResponse *basicResponse; 2490 ocspBasicOCSPResponse *basicResponse;
2497 ocspResponseData *responseData; 2491 ocspResponseData *responseData;
2498 ocspResponderID *responderID; 2492 ocspResponderID *responderID;
2499 CERTOCSPResponderIDType responderIDType; 2493 CERTOCSPResponderIDType responderIDType;
2500 const SEC_ASN1Template *responderIDTemplate; 2494 const SEC_ASN1Template *responderIDTemplate;
2501 int derTag; 2495 int derTag;
2502 SECStatus rv; 2496 SECStatus rv;
2503 SECItem newsrc; 2497 SECItem newsrc;
2504 2498
2505 mark = PORT_ArenaMark(arena); 2499 mark = PORT_ArenaMark(arena);
2506 2500
2507 basicResponse = PORT_ArenaZAlloc(arena, sizeof(ocspBasicOCSPResponse)); 2501 basicResponse = PORT_ArenaZAlloc(arena, sizeof(ocspBasicOCSPResponse));
2508 if (basicResponse == NULL) { 2502 if (basicResponse == NULL) {
2509 » goto loser; 2503 goto loser;
2510 } 2504 }
2511 2505
2512 /* copy the DER into the arena, since Quick DER returns data that points 2506 /* copy the DER into the arena, since Quick DER returns data that points
2513 into the DER input, which may get freed by the caller */ 2507 into the DER input, which may get freed by the caller */
2514 rv = SECITEM_CopyItem(arena, &newsrc, src); 2508 rv = SECITEM_CopyItem(arena, &newsrc, src);
2515 if ( rv != SECSuccess ) { 2509 if (rv != SECSuccess) {
2516 » goto loser; 2510 goto loser;
2517 } 2511 }
2518 2512
2519 rv = SEC_QuickDERDecodeItem(arena, basicResponse, 2513 rv = SEC_QuickDERDecodeItem(arena, basicResponse,
2520 » » » ocsp_BasicOCSPResponseTemplate, &newsrc); 2514 ocsp_BasicOCSPResponseTemplate, &newsrc);
2521 if (rv != SECSuccess) { 2515 if (rv != SECSuccess) {
2522 » if (PORT_GetError() == SEC_ERROR_BAD_DER) 2516 if (PORT_GetError() == SEC_ERROR_BAD_DER)
2523 » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); 2517 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
2524 » goto loser; 2518 goto loser;
2525 } 2519 }
2526 2520
2527 responseData = basicResponse->tbsResponseData; 2521 responseData = basicResponse->tbsResponseData;
2528 2522
2529 /* 2523 /*
2530 * The following asserts point out internal errors (problems in 2524 * The following asserts point out internal errors (problems in
2531 * the template definitions or in the ASN.1 decoder itself, etc.). 2525 * the template definitions or in the ASN.1 decoder itself, etc.).
2532 */ 2526 */
2533 PORT_Assert(responseData != NULL); 2527 PORT_Assert(responseData != NULL);
2534 PORT_Assert(responseData->derResponderID.data != NULL); 2528 PORT_Assert(responseData->derResponderID.data != NULL);
2535 2529
2536 /* 2530 /*
2537 * XXX Because responderID is a CHOICE, which is not currently handled 2531 * XXX Because responderID is a CHOICE, which is not currently handled
2538 * by our ASN.1 decoder, we have to decode it "by hand". 2532 * by our ASN.1 decoder, we have to decode it "by hand".
2539 */ 2533 */
2540 derTag = responseData->derResponderID.data[0] & SEC_ASN1_TAGNUM_MASK; 2534 derTag = responseData->derResponderID.data[0] & SEC_ASN1_TAGNUM_MASK;
2541 responderIDType = ocsp_ResponderIDTypeByTag(derTag); 2535 responderIDType = ocsp_ResponderIDTypeByTag(derTag);
2542 responderIDTemplate = ocsp_ResponderIDTemplateByType(responderIDType); 2536 responderIDTemplate = ocsp_ResponderIDTemplateByType(responderIDType);
2543 2537
2544 responderID = PORT_ArenaZAlloc(arena, sizeof(ocspResponderID)); 2538 responderID = PORT_ArenaZAlloc(arena, sizeof(ocspResponderID));
2545 if (responderID == NULL) { 2539 if (responderID == NULL) {
2546 » goto loser; 2540 goto loser;
2547 } 2541 }
2548 2542
2549 rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate, 2543 rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate,
2550 » » » &responseData->derResponderID); 2544 &responseData->derResponderID);
2551 if (rv != SECSuccess) { 2545 if (rv != SECSuccess) {
2552 » if (PORT_GetError() == SEC_ERROR_BAD_DER) 2546 if (PORT_GetError() == SEC_ERROR_BAD_DER)
2553 » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); 2547 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
2554 » goto loser; 2548 goto loser;
2555 } 2549 }
2556 2550
2557 responderID->responderIDType = responderIDType; 2551 responderID->responderIDType = responderIDType;
2558 responseData->responderID = responderID; 2552 responseData->responderID = responderID;
2559 2553
2560 /* 2554 /*
2561 * XXX Each SingleResponse also contains a CHOICE, which has to be 2555 * XXX Each SingleResponse also contains a CHOICE, which has to be
2562 * fixed up by hand. 2556 * fixed up by hand.
2563 */ 2557 */
2564 rv = ocsp_FinishDecodingSingleResponses(arena, responseData->responses); 2558 rv = ocsp_FinishDecodingSingleResponses(arena, responseData->responses);
2565 if (rv != SECSuccess) { 2559 if (rv != SECSuccess) {
2566 » goto loser; 2560 goto loser;
2567 } 2561 }
2568 2562
2569 PORT_ArenaUnmark(arena, mark); 2563 PORT_ArenaUnmark(arena, mark);
2570 return basicResponse; 2564 return basicResponse;
2571 2565
2572 loser: 2566 loser:
2573 PORT_ArenaRelease(arena, mark); 2567 PORT_ArenaRelease(arena, mark);
2574 return NULL; 2568 return NULL;
2575 } 2569 }
2576 2570
2577
2578 /* 2571 /*
2579 * Decode the responseBytes based on the responseType found in "rbytes", 2572 * Decode the responseBytes based on the responseType found in "rbytes",
2580 * leaving the resulting translated/decoded information in there as well. 2573 * leaving the resulting translated/decoded information in there as well.
2581 */ 2574 */
2582 static SECStatus 2575 static SECStatus
2583 ocsp_DecodeResponseBytes(PLArenaPool *arena, ocspResponseBytes *rbytes) 2576 ocsp_DecodeResponseBytes(PLArenaPool *arena, ocspResponseBytes *rbytes)
2584 { 2577 {
2585 if (rbytes == NULL) { 2578 if (rbytes == NULL) {
2586 » PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE); 2579 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
2587 » return SECFailure; 2580 return SECFailure;
2588 } 2581 }
2589 2582
2590 rbytes->responseTypeTag = SECOID_FindOIDTag(&rbytes->responseType); 2583 rbytes->responseTypeTag = SECOID_FindOIDTag(&rbytes->responseType);
2591 switch (rbytes->responseTypeTag) { 2584 switch (rbytes->responseTypeTag) {
2592 » case SEC_OID_PKIX_OCSP_BASIC_RESPONSE: 2585 case SEC_OID_PKIX_OCSP_BASIC_RESPONSE: {
2593 » { 2586 ocspBasicOCSPResponse *basicResponse;
2594 » » ocspBasicOCSPResponse *basicResponse;
2595 2587
2596 » » basicResponse = ocsp_DecodeBasicOCSPResponse(arena, 2588 basicResponse = ocsp_DecodeBasicOCSPResponse(arena,
2597 » » » » » » » &rbytes->response); 2589 &rbytes->response);
2598 » » if (basicResponse == NULL) 2590 if (basicResponse == NULL)
2599 » » return SECFailure; 2591 return SECFailure;
2600 2592
2601 » » rbytes->decodedResponse.basic = basicResponse; 2593 rbytes->decodedResponse.basic = basicResponse;
2602 » } 2594 } break;
2603 » break;
2604 2595
2605 » /* 2596 /*
2606 * Add new/future response types here. 2597 * Add new/future response types here.
2607 */ 2598 */
2608 2599
2609 » default: 2600 default:
2610 » PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE); 2601 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE);
2611 » return SECFailure; 2602 return SECFailure;
2612 } 2603 }
2613 2604
2614 return SECSuccess; 2605 return SECSuccess;
2615 } 2606 }
2616 2607
2617
2618 /* 2608 /*
2619 * FUNCTION: CERT_DecodeOCSPResponse 2609 * FUNCTION: CERT_DecodeOCSPResponse
2620 * Decode a DER encoded OCSP Response. 2610 * Decode a DER encoded OCSP Response.
2621 * INPUTS: 2611 * INPUTS:
2622 * SECItem *src 2612 * SECItem *src
2623 * Pointer to a SECItem holding DER encoded OCSP Response. 2613 * Pointer to a SECItem holding DER encoded OCSP Response.
2624 * RETURN: 2614 * RETURN:
2625 * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response); 2615 * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response);
2626 * the caller is responsible for destroying it. Or NULL if error (either 2616 * the caller is responsible for destroying it. Or NULL if error (either
2627 * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE), 2617 * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE),
2628 * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE), 2618 * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE),
2629 * or a low-level or internal error occurred). 2619 * or a low-level or internal error occurred).
2630 */ 2620 */
2631 CERTOCSPResponse * 2621 CERTOCSPResponse *
2632 CERT_DecodeOCSPResponse(const SECItem *src) 2622 CERT_DecodeOCSPResponse(const SECItem *src)
2633 { 2623 {
2634 PLArenaPool *arena = NULL; 2624 PLArenaPool *arena = NULL;
2635 CERTOCSPResponse *response = NULL; 2625 CERTOCSPResponse *response = NULL;
2636 SECStatus rv = SECFailure; 2626 SECStatus rv = SECFailure;
2637 ocspResponseStatus sv; 2627 ocspResponseStatus sv;
2638 SECItem newSrc; 2628 SECItem newSrc;
2639 2629
2640 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2630 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
2641 if (arena == NULL) { 2631 if (arena == NULL) {
2642 » goto loser; 2632 goto loser;
2643 } 2633 }
2644 response = (CERTOCSPResponse *) PORT_ArenaZAlloc(arena, 2634 response = (CERTOCSPResponse *)PORT_ArenaZAlloc(arena,
2645 » » » » » » sizeof(CERTOCSPResponse)); 2635 sizeof(CERTOCSPResponse));
2646 if (response == NULL) { 2636 if (response == NULL) {
2647 » goto loser; 2637 goto loser;
2648 } 2638 }
2649 response->arena = arena; 2639 response->arena = arena;
2650 2640
2651 /* copy the DER into the arena, since Quick DER returns data that points 2641 /* copy the DER into the arena, since Quick DER returns data that points
2652 into the DER input, which may get freed by the caller */ 2642 into the DER input, which may get freed by the caller */
2653 rv = SECITEM_CopyItem(arena, &newSrc, src); 2643 rv = SECITEM_CopyItem(arena, &newSrc, src);
2654 if ( rv != SECSuccess ) { 2644 if (rv != SECSuccess) {
2655 » goto loser; 2645 goto loser;
2656 } 2646 }
2657 2647
2658 rv = SEC_QuickDERDecodeItem(arena, response, ocsp_OCSPResponseTemplate, &new Src); 2648 rv = SEC_QuickDERDecodeItem(arena, response, ocsp_OCSPResponseTemplate, &new Src);
2659 if (rv != SECSuccess) { 2649 if (rv != SECSuccess) {
2660 » if (PORT_GetError() == SEC_ERROR_BAD_DER) 2650 if (PORT_GetError() == SEC_ERROR_BAD_DER)
2661 » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); 2651 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
2662 » goto loser; 2652 goto loser;
2663 } 2653 }
2664 2654
2665 sv = (ocspResponseStatus) DER_GetInteger(&response->responseStatus); 2655 sv = (ocspResponseStatus)DER_GetInteger(&response->responseStatus);
2666 response->statusValue = sv; 2656 response->statusValue = sv;
2667 if (sv != ocspResponse_successful) { 2657 if (sv != ocspResponse_successful) {
2668 » /* 2658 /*
2669 * If the response status is anything but successful, then we 2659 * If the response status is anything but successful, then we
2670 * are all done with decoding; the status is all there is. 2660 * are all done with decoding; the status is all there is.
2671 */ 2661 */
2672 » return response; 2662 return response;
2673 } 2663 }
2674 2664
2675 /* 2665 /*
2676 * A successful response contains much more information, still encoded. 2666 * A successful response contains much more information, still encoded.
2677 * Now we need to decode that. 2667 * Now we need to decode that.
2678 */ 2668 */
2679 rv = ocsp_DecodeResponseBytes(arena, response->responseBytes); 2669 rv = ocsp_DecodeResponseBytes(arena, response->responseBytes);
2680 if (rv != SECSuccess) { 2670 if (rv != SECSuccess) {
2681 » goto loser; 2671 goto loser;
2682 } 2672 }
2683 2673
2684 return response; 2674 return response;
2685 2675
2686 loser: 2676 loser:
2687 if (arena != NULL) { 2677 if (arena != NULL) {
2688 » PORT_FreeArena(arena, PR_FALSE); 2678 PORT_FreeArena(arena, PR_FALSE);
2689 } 2679 }
2690 return NULL; 2680 return NULL;
2691 } 2681 }
2692 2682
2693 /* 2683 /*
2694 * The way an OCSPResponse is defined, there are many levels to descend 2684 * The way an OCSPResponse is defined, there are many levels to descend
2695 * before getting to the actual response information. And along the way 2685 * before getting to the actual response information. And along the way
2696 * we need to check that the response *type* is recognizable, which for 2686 * we need to check that the response *type* is recognizable, which for
2697 * now means that it is a BasicOCSPResponse, because that is the only 2687 * now means that it is a BasicOCSPResponse, because that is the only
2698 * type currently defined. Rather than force all routines to perform 2688 * type currently defined. Rather than force all routines to perform
2699 * a bunch of sanity checking every time they want to work on a response, 2689 * a bunch of sanity checking every time they want to work on a response,
2700 * this function isolates that and gives back the interesting part. 2690 * this function isolates that and gives back the interesting part.
2701 * Note that no copying is done, this just returns a pointer into the 2691 * Note that no copying is done, this just returns a pointer into the
2702 * substructure of the response which is passed in. 2692 * substructure of the response which is passed in.
2703 * 2693 *
2704 * XXX This routine only works when a valid response structure is passed 2694 * XXX This routine only works when a valid response structure is passed
2705 * into it; this is checked with many assertions. Assuming the response 2695 * into it; this is checked with many assertions. Assuming the response
2706 * was creating by decoding, it wouldn't make it this far without being 2696 * was creating by decoding, it wouldn't make it this far without being
2707 * okay. That is a sufficient assumption since the entire OCSP interface 2697 * okay. That is a sufficient assumption since the entire OCSP interface
2708 * is only used internally. When this interface is officially exported, 2698 * is only used internally. When this interface is officially exported,
2709 * each assertion below will need to be followed-up with setting an error 2699 * each assertion below will need to be followed-up with setting an error
2710 * and returning (null). 2700 * and returning (null).
2711 * 2701 *
2712 * FUNCTION: ocsp_GetResponseData 2702 * FUNCTION: ocsp_GetResponseData
2713 * Returns ocspResponseData structure and a pointer to tbs response 2703 * Returns ocspResponseData structure and a pointer to tbs response
2714 * data DER from a valid ocsp response. 2704 * data DER from a valid ocsp response.
2715 * INPUTS: 2705 * INPUTS:
2716 * CERTOCSPResponse *response 2706 * CERTOCSPResponse *response
2717 * structure of a valid ocsp response 2707 * structure of a valid ocsp response
2718 * RETURN: 2708 * RETURN:
2719 * Returns a pointer to ocspResponseData structure: decoded OCSP response 2709 * Returns a pointer to ocspResponseData structure: decoded OCSP response
2720 * data, and a pointer(tbsResponseDataDER) to its undecoded data DER. 2710 * data, and a pointer(tbsResponseDataDER) to its undecoded data DER.
2721 */ 2711 */
2722 ocspResponseData * 2712 ocspResponseData *
2723 ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER) 2713 ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER)
2724 { 2714 {
2725 ocspBasicOCSPResponse *basic; 2715 ocspBasicOCSPResponse *basic;
2726 ocspResponseData *responseData; 2716 ocspResponseData *responseData;
2727 2717
2728 PORT_Assert(response != NULL); 2718 PORT_Assert(response != NULL);
2729 2719
2730 PORT_Assert(response->responseBytes != NULL); 2720 PORT_Assert(response->responseBytes != NULL);
2731 2721
2732 PORT_Assert(response->responseBytes->responseTypeTag 2722 PORT_Assert(response->responseBytes->responseTypeTag ==
2733 » » == SEC_OID_PKIX_OCSP_BASIC_RESPONSE); 2723 SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
2734 2724
2735 basic = response->responseBytes->decodedResponse.basic; 2725 basic = response->responseBytes->decodedResponse.basic;
2736 PORT_Assert(basic != NULL); 2726 PORT_Assert(basic != NULL);
2737 2727
2738 responseData = basic->tbsResponseData; 2728 responseData = basic->tbsResponseData;
2739 PORT_Assert(responseData != NULL); 2729 PORT_Assert(responseData != NULL);
2740 2730
2741 if (tbsResponseDataDER) { 2731 if (tbsResponseDataDER) {
2742 *tbsResponseDataDER = &basic->tbsResponseDataDER; 2732 *tbsResponseDataDER = &basic->tbsResponseDataDER;
2743 2733
(...skipping 10 matching lines...) Expand all
2754 */ 2744 */
2755 ocspSignature * 2745 ocspSignature *
2756 ocsp_GetResponseSignature(CERTOCSPResponse *response) 2746 ocsp_GetResponseSignature(CERTOCSPResponse *response)
2757 { 2747 {
2758 ocspBasicOCSPResponse *basic; 2748 ocspBasicOCSPResponse *basic;
2759 2749
2760 PORT_Assert(response != NULL); 2750 PORT_Assert(response != NULL);
2761 if (NULL == response->responseBytes) { 2751 if (NULL == response->responseBytes) {
2762 return NULL; 2752 return NULL;
2763 } 2753 }
2764 if (response->responseBytes->responseTypeTag 2754 if (response->responseBytes->responseTypeTag !=
2765 != SEC_OID_PKIX_OCSP_BASIC_RESPONSE) { 2755 SEC_OID_PKIX_OCSP_BASIC_RESPONSE) {
2766 return NULL; 2756 return NULL;
2767 } 2757 }
2768 basic = response->responseBytes->decodedResponse.basic; 2758 basic = response->responseBytes->decodedResponse.basic;
2769 PORT_Assert(basic != NULL); 2759 PORT_Assert(basic != NULL);
2770 2760
2771 return &(basic->responseSignature); 2761 return &(basic->responseSignature);
2772 } 2762 }
2773 2763
2774
2775 /* 2764 /*
2776 * FUNCTION: CERT_DestroyOCSPResponse 2765 * FUNCTION: CERT_DestroyOCSPResponse
2777 * Frees an OCSP Response structure. 2766 * Frees an OCSP Response structure.
2778 * INPUTS: 2767 * INPUTS:
2779 * CERTOCSPResponse *request 2768 * CERTOCSPResponse *request
2780 * Pointer to CERTOCSPResponse to be freed. 2769 * Pointer to CERTOCSPResponse to be freed.
2781 * RETURN: 2770 * RETURN:
2782 * No return value; no errors. 2771 * No return value; no errors.
2783 */ 2772 */
2784 void 2773 void
2785 CERT_DestroyOCSPResponse(CERTOCSPResponse *response) 2774 CERT_DestroyOCSPResponse(CERTOCSPResponse *response)
2786 { 2775 {
2787 if (response != NULL) { 2776 if (response != NULL) {
2788 » ocspSignature *signature = ocsp_GetResponseSignature(response); 2777 ocspSignature *signature = ocsp_GetResponseSignature(response);
2789 » if (signature && signature->cert != NULL) 2778 if (signature && signature->cert != NULL)
2790 » CERT_DestroyCertificate(signature->cert); 2779 CERT_DestroyCertificate(signature->cert);
2791 2780
2792 » /* 2781 /*
2793 * We should actually never have a response without an arena, 2782 * We should actually never have a response without an arena,
2794 * but check just in case. (If there isn't one, there is not 2783 * but check just in case. (If there isn't one, there is not
2795 * much we can do about it...) 2784 * much we can do about it...)
2796 */ 2785 */
2797 » PORT_Assert(response->arena != NULL); 2786 PORT_Assert(response->arena != NULL);
2798 » if (response->arena != NULL) { 2787 if (response->arena != NULL) {
2799 » PORT_FreeArena(response->arena, PR_FALSE); 2788 PORT_FreeArena(response->arena, PR_FALSE);
2800 » } 2789 }
2801 } 2790 }
2802 } 2791 }
2803 2792
2804
2805 /* 2793 /*
2806 * OVERALL OCSP CLIENT SUPPORT (make and send a request, verify a response): 2794 * OVERALL OCSP CLIENT SUPPORT (make and send a request, verify a response):
2807 */ 2795 */
2808 2796
2809
2810 /* 2797 /*
2811 * Pick apart a URL, saving the important things in the passed-in pointers. 2798 * Pick apart a URL, saving the important things in the passed-in pointers.
2812 * 2799 *
2813 * We expect to find "http://<hostname>[:<port>]/[path]", though we will 2800 * We expect to find "http://<hostname>[:<port>]/[path]", though we will
2814 * tolerate that final slash character missing, as well as beginning and 2801 * tolerate that final slash character missing, as well as beginning and
2815 * trailing whitespace, and any-case-characters for "http". All of that 2802 * trailing whitespace, and any-case-characters for "http". All of that
2816 * tolerance is what complicates this routine. What we want is just to 2803 * tolerance is what complicates this routine. What we want is just to
2817 * pick out the hostname, the port, and the path. 2804 * pick out the hostname, the port, and the path.
2818 * 2805 *
2819 * On a successful return, the caller will need to free the output pieces 2806 * On a successful return, the caller will need to free the output pieces
2820 * of hostname and path, which are copies of the values found in the url. 2807 * of hostname and path, which are copies of the values found in the url.
2821 */ 2808 */
2822 static SECStatus 2809 static SECStatus
2823 ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath) 2810 ocsp_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
2824 { 2811 {
2825 unsigned short port = 80;» » /* default, in case not in url */ 2812 unsigned short port = 80; /* default, in case not in url */
2826 char *hostname = NULL; 2813 char *hostname = NULL;
2827 char *path = NULL; 2814 char *path = NULL;
2828 const char *save; 2815 const char *save;
2829 char c; 2816 char c;
2830 int len; 2817 int len;
2831 2818
2832 if (url == NULL) 2819 if (url == NULL)
2833 » goto loser; 2820 goto loser;
2834 2821
2835 /* 2822 /*
2836 * Skip beginning whitespace. 2823 * Skip beginning whitespace.
2837 */ 2824 */
2838 c = *url; 2825 c = *url;
2839 while ((c == ' ' || c == '\t') && c != '\0') { 2826 while ((c == ' ' || c == '\t') && c != '\0') {
2840 » url++; 2827 url++;
2841 » c = *url; 2828 c = *url;
2842 } 2829 }
2843 if (c == '\0') 2830 if (c == '\0')
2844 » goto loser; 2831 goto loser;
2845 2832
2846 /* 2833 /*
2847 * Confirm, then skip, protocol. (Since we only know how to do http, 2834 * Confirm, then skip, protocol. (Since we only know how to do http,
2848 * that is all we will accept). 2835 * that is all we will accept).
2849 */ 2836 */
2850 if (PORT_Strncasecmp(url, "http://", 7) != 0) 2837 if (PORT_Strncasecmp(url, "http://", 7) != 0)
2851 » goto loser; 2838 goto loser;
2852 url += 7; 2839 url += 7;
2853 2840
2854 /* 2841 /*
2855 * Whatever comes next is the hostname (or host IP address). We just 2842 * Whatever comes next is the hostname (or host IP address). We just
2856 * save it aside and then search for its end so we can determine its 2843 * save it aside and then search for its end so we can determine its
2857 * length and copy it. 2844 * length and copy it.
2858 * 2845 *
2859 * XXX Note that because we treat a ':' as a terminator character 2846 * XXX Note that because we treat a ':' as a terminator character
2860 * (and below, we expect that to mean there is a port specification 2847 * (and below, we expect that to mean there is a port specification
2861 * immediately following), we will not handle IPv6 addresses. That is 2848 * immediately following), we will not handle IPv6 addresses. That is
2862 * apparently an acceptable limitation, for the time being. Some day, 2849 * apparently an acceptable limitation, for the time being. Some day,
2863 * when there is a clear way to specify a URL with an IPv6 address that 2850 * when there is a clear way to specify a URL with an IPv6 address that
2864 * can be parsed unambiguously, this code should be made to do that. 2851 * can be parsed unambiguously, this code should be made to do that.
2865 */ 2852 */
2866 save = url; 2853 save = url;
2867 c = *url; 2854 c = *url;
2868 while (c != '/' && c != ':' && c != '\0' && c != ' ' && c != '\t') { 2855 while (c != '/' && c != ':' && c != '\0' && c != ' ' && c != '\t') {
2869 » url++; 2856 url++;
2870 » c = *url; 2857 c = *url;
2871 } 2858 }
2872 len = url - save; 2859 len = url - save;
2873 hostname = PORT_Alloc(len + 1); 2860 hostname = PORT_Alloc(len + 1);
2874 if (hostname == NULL) 2861 if (hostname == NULL)
2875 » goto loser; 2862 goto loser;
2876 PORT_Memcpy(hostname, save, len); 2863 PORT_Memcpy(hostname, save, len);
2877 hostname[len] = '\0'; 2864 hostname[len] = '\0';
2878 2865
2879 /* 2866 /*
2880 * Now we figure out if there was a port specified or not. 2867 * Now we figure out if there was a port specified or not.
2881 * If so, we need to parse it (as a number) and skip it. 2868 * If so, we need to parse it (as a number) and skip it.
2882 */ 2869 */
2883 if (c == ':') { 2870 if (c == ':') {
2884 » url++; 2871 url++;
2885 » port = (unsigned short) PORT_Atoi(url); 2872 port = (unsigned short)PORT_Atoi(url);
2886 » c = *url; 2873 c = *url;
2887 » while (c != '/' && c != '\0' && c != ' ' && c != '\t') { 2874 while (c != '/' && c != '\0' && c != ' ' && c != '\t') {
2888 » if (c < '0' || c > '9') 2875 if (c < '0' || c > '9')
2889 » » goto loser; 2876 goto loser;
2890 » url++; 2877 url++;
2891 » c = *url; 2878 c = *url;
2892 » } 2879 }
2893 } 2880 }
2894 2881
2895 /* 2882 /*
2896 * Last thing to find is a path. There *should* be a slash, 2883 * Last thing to find is a path. There *should* be a slash,
2897 * if nothing else -- but if there is not we provide one. 2884 * if nothing else -- but if there is not we provide one.
2898 */ 2885 */
2899 if (c == '/') { 2886 if (c == '/') {
2900 » save = url; 2887 save = url;
2901 » while (c != '\0' && c != ' ' && c != '\t') { 2888 while (c != '\0' && c != ' ' && c != '\t') {
2902 » url++; 2889 url++;
2903 » c = *url; 2890 c = *url;
2904 » } 2891 }
2905 » len = url - save; 2892 len = url - save;
2906 » path = PORT_Alloc(len + 1); 2893 path = PORT_Alloc(len + 1);
2907 » if (path == NULL) 2894 if (path == NULL)
2908 » goto loser; 2895 goto loser;
2909 » PORT_Memcpy(path, save, len); 2896 PORT_Memcpy(path, save, len);
2910 » path[len] = '\0'; 2897 path[len] = '\0';
2911 } else { 2898 } else {
2912 » path = PORT_Strdup("/"); 2899 path = PORT_Strdup("/");
2913 » if (path == NULL) 2900 if (path == NULL)
2914 » goto loser; 2901 goto loser;
2915 } 2902 }
2916 2903
2917 *pHostname = hostname; 2904 *pHostname = hostname;
2918 *pPort = port; 2905 *pPort = port;
2919 *pPath = path; 2906 *pPath = path;
2920 return SECSuccess; 2907 return SECSuccess;
2921 2908
2922 loser: 2909 loser:
2923 if (hostname != NULL) 2910 if (hostname != NULL)
2924 » PORT_Free(hostname); 2911 PORT_Free(hostname);
2925 PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); 2912 PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
2926 return SECFailure; 2913 return SECFailure;
2927 } 2914 }
2928 2915
2929 /* 2916 /*
2930 * Open a socket to the specified host on the specified port, and return it. 2917 * Open a socket to the specified host on the specified port, and return it.
2931 * The host is either a hostname or an IP address. 2918 * The host is either a hostname or an IP address.
2932 */ 2919 */
2933 static PRFileDesc * 2920 static PRFileDesc *
2934 ocsp_ConnectToHost(const char *host, PRUint16 port) 2921 ocsp_ConnectToHost(const char *host, PRUint16 port)
2935 { 2922 {
2936 PRFileDesc *sock = NULL; 2923 PRFileDesc *sock = NULL;
2937 PRIntervalTime timeout; 2924 PRIntervalTime timeout;
2938 PRNetAddr addr; 2925 PRNetAddr addr;
2939 char *netdbbuf = NULL; 2926 char *netdbbuf = NULL;
2940 2927
2941 sock = PR_NewTCPSocket(); 2928 sock = PR_NewTCPSocket();
2942 if (sock == NULL) 2929 if (sock == NULL)
2943 » goto loser; 2930 goto loser;
2944 2931
2945 /* XXX Some day need a way to set (and get?) the following value */ 2932 /* XXX Some day need a way to set (and get?) the following value */
2946 timeout = PR_SecondsToInterval(30); 2933 timeout = PR_SecondsToInterval(30);
2947 2934
2948 /* 2935 /*
2949 * If the following converts an IP address string in "dot notation" 2936 * If the following converts an IP address string in "dot notation"
2950 * into a PRNetAddr. If it fails, we assume that is because we do not 2937 * into a PRNetAddr. If it fails, we assume that is because we do not
2951 * have such an address, but instead a host *name*. In that case we 2938 * have such an address, but instead a host *name*. In that case we
2952 * then lookup the host by name. Using the NSPR function this way 2939 * then lookup the host by name. Using the NSPR function this way
2953 * means we do not have to have our own logic for distinguishing a 2940 * means we do not have to have our own logic for distinguishing a
2954 * valid numerical IP address from a hostname. 2941 * valid numerical IP address from a hostname.
2955 */ 2942 */
2956 if (PR_StringToNetAddr(host, &addr) != PR_SUCCESS) { 2943 if (PR_StringToNetAddr(host, &addr) != PR_SUCCESS) {
2957 » PRIntn hostIndex; 2944 PRIntn hostIndex;
2958 » PRHostEnt hostEntry; 2945 PRHostEnt hostEntry;
2959 2946
2960 » netdbbuf = PORT_Alloc(PR_NETDB_BUF_SIZE); 2947 netdbbuf = PORT_Alloc(PR_NETDB_BUF_SIZE);
2961 » if (netdbbuf == NULL) 2948 if (netdbbuf == NULL)
2962 » goto loser; 2949 goto loser;
2963 2950
2964 » if (PR_GetHostByName(host, netdbbuf, PR_NETDB_BUF_SIZE, 2951 if (PR_GetHostByName(host, netdbbuf, PR_NETDB_BUF_SIZE,
2965 » » » &hostEntry) != PR_SUCCESS) 2952 &hostEntry) != PR_SUCCESS)
2966 » goto loser; 2953 goto loser;
2967 2954
2968 » hostIndex = 0; 2955 hostIndex = 0;
2969 » do { 2956 do {
2970 » hostIndex = PR_EnumerateHostEnt(hostIndex, &hostEntry, port, &addr); 2957 hostIndex = PR_EnumerateHostEnt(hostIndex, &hostEntry, port, &addr);
2971 » if (hostIndex <= 0) 2958 if (hostIndex <= 0)
2972 » » goto loser; 2959 goto loser;
2973 » } while (PR_Connect(sock, &addr, timeout) != PR_SUCCESS); 2960 } while (PR_Connect(sock, &addr, timeout) != PR_SUCCESS);
2974 2961
2975 » PORT_Free(netdbbuf); 2962 PORT_Free(netdbbuf);
2976 } else { 2963 } else {
2977 » /* 2964 /*
2978 * First put the port into the address, then connect. 2965 * First put the port into the address, then connect.
2979 */ 2966 */
2980 » if (PR_InitializeNetAddr(PR_IpAddrNull, port, &addr) != PR_SUCCESS) 2967 if (PR_InitializeNetAddr(PR_IpAddrNull, port, &addr) != PR_SUCCESS)
2981 » goto loser; 2968 goto loser;
2982 » if (PR_Connect(sock, &addr, timeout) != PR_SUCCESS) 2969 if (PR_Connect(sock, &addr, timeout) != PR_SUCCESS)
2983 » goto loser; 2970 goto loser;
2984 } 2971 }
2985 2972
2986 return sock; 2973 return sock;
2987 2974
2988 loser: 2975 loser:
2989 if (sock != NULL) 2976 if (sock != NULL)
2990 » PR_Close(sock); 2977 PR_Close(sock);
2991 if (netdbbuf != NULL) 2978 if (netdbbuf != NULL)
2992 » PORT_Free(netdbbuf); 2979 PORT_Free(netdbbuf);
2993 return NULL; 2980 return NULL;
2994 } 2981 }
2995 2982
2996 /* 2983 /*
2997 * Sends an encoded OCSP request to the server identified by "location", 2984 * Sends an encoded OCSP request to the server identified by "location",
2998 * and returns the socket on which it was sent (so can listen for the reply). 2985 * and returns the socket on which it was sent (so can listen for the reply).
2999 * "location" is expected to be a valid URL -- an error parsing it produces 2986 * "location" is expected to be a valid URL -- an error parsing it produces
3000 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION. Other errors are likely problems 2987 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION. Other errors are likely problems
3001 * connecting to it, or writing to it, or allocating memory, and the low-level 2988 * connecting to it, or writing to it, or allocating memory, and the low-level
3002 * errors appropriate to the problem will be set. 2989 * errors appropriate to the problem will be set.
(...skipping 14 matching lines...) Expand all
3017 PRFileDesc *sock = NULL; 3004 PRFileDesc *sock = NULL;
3018 PRFileDesc *returnSock = NULL; 3005 PRFileDesc *returnSock = NULL;
3019 char *header = NULL; 3006 char *header = NULL;
3020 char portstr[16]; 3007 char portstr[16];
3021 3008
3022 /* 3009 /*
3023 * Take apart the location, getting the hostname, port, and path. 3010 * Take apart the location, getting the hostname, port, and path.
3024 */ 3011 */
3025 rv = ocsp_ParseURL(location, &hostname, &port, &path); 3012 rv = ocsp_ParseURL(location, &hostname, &port, &path);
3026 if (rv != SECSuccess) 3013 if (rv != SECSuccess)
3027 » goto loser; 3014 goto loser;
3028 3015
3029 PORT_Assert(hostname != NULL); 3016 PORT_Assert(hostname != NULL);
3030 PORT_Assert(path != NULL); 3017 PORT_Assert(path != NULL);
3031 3018
3032 sock = ocsp_ConnectToHost(hostname, port); 3019 sock = ocsp_ConnectToHost(hostname, port);
3033 if (sock == NULL) 3020 if (sock == NULL)
3034 » goto loser; 3021 goto loser;
3035 3022
3036 portstr[0] = '\0'; 3023 portstr[0] = '\0';
3037 if (port != 80) { 3024 if (port != 80) {
3038 PR_snprintf(portstr, sizeof(portstr), ":%d", port); 3025 PR_snprintf(portstr, sizeof(portstr), ":%d", port);
3039 } 3026 }
3040 3027
3041 if (!encodedRequest) { 3028 if (!encodedRequest) {
3042 header = PR_smprintf("GET %s HTTP/1.0\r\n" 3029 header = PR_smprintf("GET %s HTTP/1.0\r\n"
3043 "Host: %s%s\r\n\r\n", 3030 "Host: %s%s\r\n\r\n",
3044 path, hostname, portstr); 3031 path, hostname, portstr);
3045 if (header == NULL) 3032 if (header == NULL)
3046 goto loser; 3033 goto loser;
3047 3034
3048 /* 3035 /*
3049 * The NSPR documentation promises that if it can, it will write the full 3036 * The NSPR documentation promises that if it can, it will write the ful l
3050 * amount; this will not return a partial value expecting us to loop. 3037 * amount; this will not return a partial value expecting us to loop.
3051 */ 3038 */
3052 if (PR_Write(sock, header, (PRInt32) PORT_Strlen(header)) < 0) 3039 if (PR_Write(sock, header, (PRInt32)PORT_Strlen(header)) < 0)
3053 goto loser; 3040 goto loser;
3054 } 3041 } else {
3055 else { 3042 header = PR_smprintf("POST %s HTTP/1.0\r\n"
3056 header = PR_smprintf("POST %s HTTP/1.0\r\n" 3043 "Host: %s%s\r\n"
3057 "Host: %s%s\r\n" 3044 "Content-Type: application/ocsp-request\r\n"
3058 "Content-Type: application/ocsp-request\r\n" 3045 "Content-Length: %u\r\n\r\n",
3059 "Content-Length: %u\r\n\r\n", 3046 path, hostname, portstr, encodedRequest->len);
3060 path, hostname, portstr, encodedRequest->len); 3047 if (header == NULL)
3061 if (header == NULL) 3048 goto loser;
3062 goto loser;
3063 3049
3064 /* 3050 /*
3065 * The NSPR documentation promises that if it can, it will write the full 3051 * The NSPR documentation promises that if it can, it will write the ful l
3066 * amount; this will not return a partial value expecting us to loop. 3052 * amount; this will not return a partial value expecting us to loop.
3067 */ 3053 */
3068 if (PR_Write(sock, header, (PRInt32) PORT_Strlen(header)) < 0) 3054 if (PR_Write(sock, header, (PRInt32)PORT_Strlen(header)) < 0)
3069 goto loser; 3055 goto loser;
3070 3056
3071 if (PR_Write(sock, encodedRequest->data, 3057 if (PR_Write(sock, encodedRequest->data,
3072 (PRInt32) encodedRequest->len) < 0) 3058 (PRInt32)encodedRequest->len) < 0)
3073 goto loser; 3059 goto loser;
3074 } 3060 }
3075 3061
3076 returnSock = sock; 3062 returnSock = sock;
3077 sock = NULL; 3063 sock = NULL;
3078 3064
3079 loser: 3065 loser:
3080 if (header != NULL) 3066 if (header != NULL)
3081 » PORT_Free(header); 3067 PORT_Free(header);
3082 if (sock != NULL) 3068 if (sock != NULL)
3083 » PR_Close(sock); 3069 PR_Close(sock);
3084 if (path != NULL) 3070 if (path != NULL)
3085 » PORT_Free(path); 3071 PORT_Free(path);
3086 if (hostname != NULL) 3072 if (hostname != NULL)
3087 » PORT_Free(hostname); 3073 PORT_Free(hostname);
3088 3074
3089 return returnSock; 3075 return returnSock;
3090 } 3076 }
3091 3077
3092 /* 3078 /*
3093 * Read from "fd" into "buf" -- expect/attempt to read a given number of bytes 3079 * Read from "fd" into "buf" -- expect/attempt to read a given number of bytes
3094 * Obviously, stop if hit end-of-stream. Timeout is passed in. 3080 * Obviously, stop if hit end-of-stream. Timeout is passed in.
3095 */ 3081 */
3096 3082
3097 static int 3083 static int
3098 ocsp_read(PRFileDesc *fd, char *buf, int toread, PRIntervalTime timeout) 3084 ocsp_read(PRFileDesc *fd, char *buf, int toread, PRIntervalTime timeout)
3099 { 3085 {
3100 int total = 0; 3086 int total = 0;
3101 3087
3102 while (total < toread) 3088 while (total < toread) {
3103 {
3104 PRInt32 got; 3089 PRInt32 got;
3105 3090
3106 got = PR_Recv(fd, buf + total, (PRInt32) (toread - total), 0, timeout); 3091 got = PR_Recv(fd, buf + total, (PRInt32)(toread - total), 0, timeout);
3107 if (got < 0) 3092 if (got < 0) {
3108 { 3093 if (0 == total) {
3109 if (0 == total)
3110 {
3111 total = -1; /* report the error if we didn't read anything yet * / 3094 total = -1; /* report the error if we didn't read anything yet * /
3112 } 3095 }
3113 break; 3096 break;
3114 } 3097 } else if (got == 0) { /* EOS */
3115 else
3116 if (got == 0)
3117 {» » » /* EOS */
3118 break; 3098 break;
3119 } 3099 }
3120 3100
3121 total += got; 3101 total += got;
3122 } 3102 }
3123 3103
3124 return total; 3104 return total;
3125 } 3105 }
3126 3106
3127 #define OCSP_BUFSIZE 1024 3107 #define OCSP_BUFSIZE 1024
3128 3108
3129 #define AbortHttpDecode(error) \ 3109 #define AbortHttpDecode(error) \
3130 { \ 3110 { \
3131 if (inBuffer) \ 3111 if (inBuffer) \
3132 PORT_Free(inBuffer); \ 3112 PORT_Free(inBuffer); \
3133 PORT_SetError(error); \ 3113 PORT_SetError(error); \
3134 return NULL; \ 3114 return NULL; \
3135 } 3115 }
3136
3137 3116
3138 /* 3117 /*
3139 * Reads on the given socket and returns an encoded response when received. 3118 * Reads on the given socket and returns an encoded response when received.
3140 * Properly formatted HTTP/1.0 response headers are expected to be read 3119 * Properly formatted HTTP/1.0 response headers are expected to be read
3141 * from the socket, preceding a binary-encoded OCSP response. Problems 3120 * from the socket, preceding a binary-encoded OCSP response. Problems
3142 * with parsing cause the error SEC_ERROR_OCSP_BAD_HTTP_RESPONSE to be 3121 * with parsing cause the error SEC_ERROR_OCSP_BAD_HTTP_RESPONSE to be
3143 * set; any other problems are likely low-level i/o or memory allocation 3122 * set; any other problems are likely low-level i/o or memory allocation
3144 * errors. 3123 * errors.
3145 */ 3124 */
3146 static SECItem * 3125 static SECItem *
3147 ocsp_GetEncodedResponse(PLArenaPool *arena, PRFileDesc *sock) 3126 ocsp_GetEncodedResponse(PLArenaPool *arena, PRFileDesc *sock)
3148 { 3127 {
3149 /* first read HTTP status line and headers */ 3128 /* first read HTTP status line and headers */
3150 3129
3151 char* inBuffer = NULL; 3130 char *inBuffer = NULL;
3152 PRInt32 offset = 0; 3131 PRInt32 offset = 0;
3153 PRInt32 inBufsize = 0; 3132 PRInt32 inBufsize = 0;
3154 const PRInt32 bufSizeIncrement = OCSP_BUFSIZE; /* 1 KB at a time */ 3133 const PRInt32 bufSizeIncrement = OCSP_BUFSIZE; /* 1 KB at a time */
3155 const PRInt32 maxBufSize = 8 * bufSizeIncrement ; /* 8 KB max */ 3134 const PRInt32 maxBufSize = 8 * bufSizeIncrement; /* 8 KB max */
3156 const char* CRLF = "\r\n"; 3135 const char *CRLF = "\r\n";
3157 const PRInt32 CRLFlen = strlen(CRLF); 3136 const PRInt32 CRLFlen = strlen(CRLF);
3158 const char* headerEndMark = "\r\n\r\n"; 3137 const char *headerEndMark = "\r\n\r\n";
3159 const PRInt32 markLen = strlen(headerEndMark); 3138 const PRInt32 markLen = strlen(headerEndMark);
3160 const PRIntervalTime ocsptimeout = 3139 const PRIntervalTime ocsptimeout =
3161 PR_SecondsToInterval(30); /* hardcoded to 30s for now */ 3140 PR_SecondsToInterval(30); /* hardcoded to 30s for now */
3162 char* headerEnd = NULL; 3141 char *headerEnd = NULL;
3163 PRBool EOS = PR_FALSE; 3142 PRBool EOS = PR_FALSE;
3164 const char* httpprotocol = "HTTP/"; 3143 const char *httpprotocol = "HTTP/";
3165 const PRInt32 httplen = strlen(httpprotocol); 3144 const PRInt32 httplen = strlen(httpprotocol);
3166 const char* httpcode = NULL; 3145 const char *httpcode = NULL;
3167 const char* contenttype = NULL; 3146 const char *contenttype = NULL;
3168 PRInt32 contentlength = 0; 3147 PRInt32 contentlength = 0;
3169 PRInt32 bytesRead = 0; 3148 PRInt32 bytesRead = 0;
3170 char* statusLineEnd = NULL; 3149 char *statusLineEnd = NULL;
3171 char* space = NULL; 3150 char *space = NULL;
3172 char* nextHeader = NULL; 3151 char *nextHeader = NULL;
3173 SECItem* result = NULL; 3152 SECItem *result = NULL;
3174 3153
3175 /* read up to at least the end of the HTTP headers */ 3154 /* read up to at least the end of the HTTP headers */
3176 do 3155 do {
3177 {
3178 inBufsize += bufSizeIncrement; 3156 inBufsize += bufSizeIncrement;
3179 inBuffer = PORT_Realloc(inBuffer, inBufsize+1); 3157 inBuffer = PORT_Realloc(inBuffer, inBufsize + 1);
3180 if (NULL == inBuffer) 3158 if (NULL == inBuffer) {
3181 {
3182 AbortHttpDecode(SEC_ERROR_NO_MEMORY); 3159 AbortHttpDecode(SEC_ERROR_NO_MEMORY);
3183 } 3160 }
3184 bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement, 3161 bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement,
3185 ocsptimeout); 3162 ocsptimeout);
3186 if (bytesRead > 0) 3163 if (bytesRead > 0) {
3187 { 3164 PRInt32 searchOffset = (offset - markLen) > 0 ? offset - markLen : 0 ;
3188 PRInt32 searchOffset = (offset - markLen) >0 ? offset-markLen : 0;
3189 offset += bytesRead; 3165 offset += bytesRead;
3190 *(inBuffer + offset) = '\0'; /* NULL termination */ 3166 *(inBuffer + offset) = '\0'; /* NULL termination */
3191 headerEnd = strstr((const char*)inBuffer + searchOffset, headerEndMa rk); 3167 headerEnd = strstr((const char *)inBuffer + searchOffset, headerEndM ark);
3192 if (bytesRead < bufSizeIncrement) 3168 if (bytesRead < bufSizeIncrement) {
3193 {
3194 /* we read less data than requested, therefore we are at 3169 /* we read less data than requested, therefore we are at
3195 EOS or there was a read error */ 3170 EOS or there was a read error */
3196 EOS = PR_TRUE; 3171 EOS = PR_TRUE;
3197 } 3172 }
3198 } 3173 } else {
3199 else
3200 {
3201 /* recv error or EOS */ 3174 /* recv error or EOS */
3202 EOS = PR_TRUE; 3175 EOS = PR_TRUE;
3203 } 3176 }
3204 } while ( (!headerEnd) && (PR_FALSE == EOS) && 3177 } while ((!headerEnd) && (PR_FALSE == EOS) &&
3205 (inBufsize < maxBufSize) ); 3178 (inBufsize < maxBufSize));
3206 3179
3207 if (!headerEnd) 3180 if (!headerEnd) {
3208 {
3209 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3181 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3210 } 3182 }
3211 3183
3212 /* parse the HTTP status line */ 3184 /* parse the HTTP status line */
3213 statusLineEnd = strstr((const char*)inBuffer, CRLF); 3185 statusLineEnd = strstr((const char *)inBuffer, CRLF);
3214 if (!statusLineEnd) 3186 if (!statusLineEnd) {
3215 {
3216 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3187 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3217 } 3188 }
3218 *statusLineEnd = '\0'; 3189 *statusLineEnd = '\0';
3219 3190
3220 /* check for HTTP/ response */ 3191 /* check for HTTP/ response */
3221 space = strchr((const char*)inBuffer, ' '); 3192 space = strchr((const char *)inBuffer, ' ');
3222 if (!space || PORT_Strncasecmp((const char*)inBuffer, httpprotocol, httplen) != 0 ) 3193 if (!space || PORT_Strncasecmp((const char *)inBuffer, httpprotocol, httplen ) != 0) {
3223 {
3224 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3194 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3225 } 3195 }
3226 3196
3227 /* check the HTTP status code of 200 */ 3197 /* check the HTTP status code of 200 */
3228 httpcode = space +1; 3198 httpcode = space + 1;
3229 space = strchr(httpcode, ' '); 3199 space = strchr(httpcode, ' ');
3230 if (!space) 3200 if (!space) {
3231 {
3232 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3201 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3233 } 3202 }
3234 *space = 0; 3203 *space = 0;
3235 if (0 != strcmp(httpcode, "200")) 3204 if (0 != strcmp(httpcode, "200")) {
3236 {
3237 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3205 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3238 } 3206 }
3239 3207
3240 /* parse the HTTP headers in the buffer . We only care about 3208 /* parse the HTTP headers in the buffer . We only care about
3241 content-type and content-length 3209 content-type and content-length
3242 */ 3210 */
3243 3211
3244 nextHeader = statusLineEnd + CRLFlen; 3212 nextHeader = statusLineEnd + CRLFlen;
3245 *headerEnd = '\0'; /* terminate */ 3213 *headerEnd = '\0'; /* terminate */
3246 do 3214 do {
3247 { 3215 char *thisHeaderEnd = NULL;
3248 char* thisHeaderEnd = NULL; 3216 char *value = NULL;
3249 char* value = NULL; 3217 char *colon = strchr(nextHeader, ':');
3250 char* colon = strchr(nextHeader, ':'); 3218
3251 3219 if (!colon) {
3252 if (!colon)
3253 {
3254 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3220 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3255 } 3221 }
3256 3222
3257 *colon = '\0'; 3223 *colon = '\0';
3258 value = colon + 1; 3224 value = colon + 1;
3259 3225
3260 /* jpierre - note : the following code will only handle the basic form 3226 /* jpierre - note : the following code will only handle the basic form
3261 of HTTP/1.0 response headers, of the form "name: value" . Headers 3227 of HTTP/1.0 response headers, of the form "name: value" . Headers
3262 split among multiple lines are not supported. This is not common 3228 split among multiple lines are not supported. This is not common
3263 and should not be an issue, but it could become one in the 3229 and should not be an issue, but it could become one in the
3264 future */ 3230 future */
3265 3231
3266 if (*value != ' ') 3232 if (*value != ' ') {
3267 {
3268 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3233 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3269 } 3234 }
3270 3235
3271 value++; 3236 value++;
3272 thisHeaderEnd = strstr(value, CRLF); 3237 thisHeaderEnd = strstr(value, CRLF);
3273 if (thisHeaderEnd ) 3238 if (thisHeaderEnd) {
3274 { 3239 *thisHeaderEnd = '\0';
3275 *thisHeaderEnd = '\0';
3276 } 3240 }
3277 3241
3278 if (0 == PORT_Strcasecmp(nextHeader, "content-type")) 3242 if (0 == PORT_Strcasecmp(nextHeader, "content-type")) {
3279 {
3280 contenttype = value; 3243 contenttype = value;
3281 } 3244 } else if (0 == PORT_Strcasecmp(nextHeader, "content-length")) {
3282 else
3283 if (0 == PORT_Strcasecmp(nextHeader, "content-length"))
3284 {
3285 contentlength = atoi(value); 3245 contentlength = atoi(value);
3286 } 3246 }
3287 3247
3288 if (thisHeaderEnd ) 3248 if (thisHeaderEnd) {
3289 {
3290 nextHeader = thisHeaderEnd + CRLFlen; 3249 nextHeader = thisHeaderEnd + CRLFlen;
3291 } 3250 } else {
3292 else
3293 {
3294 nextHeader = NULL; 3251 nextHeader = NULL;
3295 } 3252 }
3296 3253
3297 } while (nextHeader && (nextHeader < (headerEnd + CRLFlen) ) ); 3254 } while (nextHeader && (nextHeader < (headerEnd + CRLFlen)));
3298 3255
3299 /* check content-type */ 3256 /* check content-type */
3300 if (!contenttype || 3257 if (!contenttype ||
3301 (0 != PORT_Strcasecmp(contenttype, "application/ocsp-response")) ) 3258 (0 != PORT_Strcasecmp(contenttype, "application/ocsp-response"))) {
3302 {
3303 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3259 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3304 } 3260 }
3305 3261
3306 /* read the body of the OCSP response */ 3262 /* read the body of the OCSP response */
3307 offset = offset - (PRInt32) (headerEnd - (const char*)inBuffer) - markLen; 3263 offset = offset - (PRInt32)(headerEnd - (const char *)inBuffer) - markLen;
3308 if (offset) 3264 if (offset) {
3309 {
3310 /* move all data to the beginning of the buffer */ 3265 /* move all data to the beginning of the buffer */
3311 PORT_Memmove(inBuffer, headerEnd + markLen, offset); 3266 PORT_Memmove(inBuffer, headerEnd + markLen, offset);
3312 } 3267 }
3313 3268
3314 /* resize buffer to only what's needed to hold the current response */ 3269 /* resize buffer to only what's needed to hold the current response */
3315 inBufsize = (1 + (offset-1) / bufSizeIncrement ) * bufSizeIncrement ; 3270 inBufsize = (1 + (offset - 1) / bufSizeIncrement) * bufSizeIncrement;
3316 3271
3317 while ( (PR_FALSE == EOS) && 3272 while ((PR_FALSE == EOS) &&
3318 ( (contentlength == 0) || (offset < contentlength) ) && 3273 ((contentlength == 0) || (offset < contentlength)) &&
3319 (inBufsize < maxBufSize) 3274 (inBufsize < maxBufSize)) {
3320 )
3321 {
3322 /* we still need to receive more body data */ 3275 /* we still need to receive more body data */
3323 inBufsize += bufSizeIncrement; 3276 inBufsize += bufSizeIncrement;
3324 inBuffer = PORT_Realloc(inBuffer, inBufsize+1); 3277 inBuffer = PORT_Realloc(inBuffer, inBufsize + 1);
3325 if (NULL == inBuffer) 3278 if (NULL == inBuffer) {
3326 {
3327 AbortHttpDecode(SEC_ERROR_NO_MEMORY); 3279 AbortHttpDecode(SEC_ERROR_NO_MEMORY);
3328 } 3280 }
3329 bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement, 3281 bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement,
3330 ocsptimeout); 3282 ocsptimeout);
3331 if (bytesRead > 0) 3283 if (bytesRead > 0) {
3332 {
3333 offset += bytesRead; 3284 offset += bytesRead;
3334 if (bytesRead < bufSizeIncrement) 3285 if (bytesRead < bufSizeIncrement) {
3335 {
3336 /* we read less data than requested, therefore we are at 3286 /* we read less data than requested, therefore we are at
3337 EOS or there was a read error */ 3287 EOS or there was a read error */
3338 EOS = PR_TRUE; 3288 EOS = PR_TRUE;
3339 } 3289 }
3340 } 3290 } else {
3341 else
3342 {
3343 /* recv error or EOS */ 3291 /* recv error or EOS */
3344 EOS = PR_TRUE; 3292 EOS = PR_TRUE;
3345 } 3293 }
3346 } 3294 }
3347 3295
3348 if (0 == offset) 3296 if (0 == offset) {
3349 {
3350 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3297 AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3351 } 3298 }
3352 3299
3353 /* 3300 /*
3354 * Now allocate the item to hold the data. 3301 * Now allocate the item to hold the data.
3355 */ 3302 */
3356 result = SECITEM_AllocItem(arena, NULL, offset); 3303 result = SECITEM_AllocItem(arena, NULL, offset);
3357 if (NULL == result) 3304 if (NULL == result) {
3358 {
3359 AbortHttpDecode(SEC_ERROR_NO_MEMORY); 3305 AbortHttpDecode(SEC_ERROR_NO_MEMORY);
3360 } 3306 }
3361 3307
3362 /* 3308 /*
3363 * And copy the data left in the buffer. 3309 * And copy the data left in the buffer.
3364 */ 3310 */
3365 PORT_Memcpy(result->data, inBuffer, offset); 3311 PORT_Memcpy(result->data, inBuffer, offset);
3366 3312
3367 /* and free the temporary buffer */ 3313 /* and free the temporary buffer */
3368 PORT_Free(inBuffer); 3314 PORT_Free(inBuffer);
3369 return result; 3315 return result;
3370 } 3316 }
3371 3317
3372 SECStatus 3318 SECStatus
3373 CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath) 3319 CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath)
3374 { 3320 {
3375 return ocsp_ParseURL(url, pHostname, pPort, pPath); 3321 return ocsp_ParseURL(url, pHostname, pPort, pPath);
3376 } 3322 }
3377 3323
3378 /* 3324 /*
3379 * Limit the size of http responses we are willing to accept. 3325 * Limit the size of http responses we are willing to accept.
3380 */ 3326 */
3381 #define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024 3327 #define MAX_WANTED_OCSP_RESPONSE_LEN 64 * 1024
3382 3328
3383 /* if (encodedRequest == NULL) 3329 /* if (encodedRequest == NULL)
3384 * then location MUST already include the full request, 3330 * then location MUST already include the full request,
3385 * including base64 and urlencode, 3331 * including base64 and urlencode,
3386 * and the request will be sent with GET 3332 * and the request will be sent with GET
3387 * if (encodedRequest != NULL) 3333 * if (encodedRequest != NULL)
3388 * then the request will be sent with POST 3334 * then the request will be sent with POST
3389 */ 3335 */
3390 static SECItem * 3336 static SECItem *
3391 fetchOcspHttpClientV1(PLArenaPool *arena, 3337 fetchOcspHttpClientV1(PLArenaPool *arena,
3392 const SEC_HttpClientFcnV1 *hcv1, 3338 const SEC_HttpClientFcnV1 *hcv1,
3393 const char *location, 3339 const char *location,
3394 const SECItem *encodedRequest) 3340 const SECItem *encodedRequest)
3395 { 3341 {
3396 char *hostname = NULL; 3342 char *hostname = NULL;
3397 char *path = NULL; 3343 char *path = NULL;
3398 PRUint16 port; 3344 PRUint16 port;
3399 SECItem *encodedResponse = NULL; 3345 SECItem *encodedResponse = NULL;
3400 SEC_HTTP_SERVER_SESSION pServerSession = NULL; 3346 SEC_HTTP_SERVER_SESSION pServerSession = NULL;
3401 SEC_HTTP_REQUEST_SESSION pRequestSession = NULL; 3347 SEC_HTTP_REQUEST_SESSION pRequestSession = NULL;
3402 PRUint16 myHttpResponseCode; 3348 PRUint16 myHttpResponseCode;
3403 const char *myHttpResponseData; 3349 const char *myHttpResponseData;
3404 PRUint32 myHttpResponseDataLen; 3350 PRUint32 myHttpResponseDataLen;
3405 3351
3406 if (ocsp_ParseURL(location, &hostname, &port, &path) == SECFailure) { 3352 if (ocsp_ParseURL(location, &hostname, &port, &path) == SECFailure) {
3407 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); 3353 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
3408 goto loser; 3354 goto loser;
3409 } 3355 }
3410 3356
3411 PORT_Assert(hostname != NULL); 3357 PORT_Assert(hostname != NULL);
3412 PORT_Assert(path != NULL); 3358 PORT_Assert(path != NULL);
3413 3359
3414 if ((*hcv1->createSessionFcn)( 3360 if ((*hcv1->createSessionFcn)(
3415 hostname, 3361 hostname,
3416 port, 3362 port,
3417 &pServerSession) != SECSuccess) { 3363 &pServerSession) != SECSuccess) {
3418 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); 3364 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
3419 goto loser; 3365 goto loser;
3420 } 3366 }
3421 3367
3422 /* We use a non-zero timeout, which means: 3368 /* We use a non-zero timeout, which means:
3423 - the client will use blocking I/O 3369 - the client will use blocking I/O
3424 - TryFcn will not return WOULD_BLOCK nor a poll descriptor 3370 - TryFcn will not return WOULD_BLOCK nor a poll descriptor
3425 - it's sufficient to call TryFcn once 3371 - it's sufficient to call TryFcn once
3426 No lock for accessing OCSP_Global.timeoutSeconds, bug 406120 3372 No lock for accessing OCSP_Global.timeoutSeconds, bug 406120
3427 */ 3373 */
3428 3374
3429 if ((*hcv1->createFcn)( 3375 if ((*hcv1->createFcn)(
3430 pServerSession, 3376 pServerSession,
3431 "http", 3377 "http",
3432 path, 3378 path,
3433 encodedRequest ? "POST" : "GET", 3379 encodedRequest ? "POST" : "GET",
3434 PR_TicksPerSecond() * OCSP_Global.timeoutSeconds, 3380 PR_TicksPerSecond() * OCSP_Global.timeoutSeconds,
3435 &pRequestSession) != SECSuccess) { 3381 &pRequestSession) != SECSuccess) {
3436 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); 3382 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
3437 goto loser; 3383 goto loser;
3438 } 3384 }
3439 3385
3440 if (encodedRequest && 3386 if (encodedRequest &&
3441 (*hcv1->setPostDataFcn)( 3387 (*hcv1->setPostDataFcn)(
3442 pRequestSession, 3388 pRequestSession,
3443 (char*)encodedRequest->data, 3389 (char *)encodedRequest->data,
3444 encodedRequest->len, 3390 encodedRequest->len,
3445 "application/ocsp-request") != SECSuccess) { 3391 "application/ocsp-request") != SECSuccess) {
3446 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); 3392 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
3447 goto loser; 3393 goto loser;
3448 } 3394 }
3449 3395
3450 /* we don't want result objects larger than this: */ 3396 /* we don't want result objects larger than this: */
3451 myHttpResponseDataLen = MAX_WANTED_OCSP_RESPONSE_LEN; 3397 myHttpResponseDataLen = MAX_WANTED_OCSP_RESPONSE_LEN;
3452 3398
3453 OCSP_TRACE(("OCSP trySendAndReceive %s\n", location)); 3399 OCSP_TRACE(("OCSP trySendAndReceive %s\n", location));
3454 3400
3455 if ((*hcv1->trySendAndReceiveFcn)( 3401 if ((*hcv1->trySendAndReceiveFcn)(
3456 pRequestSession, 3402 pRequestSession,
3457 NULL, 3403 NULL,
3458 &myHttpResponseCode, 3404 &myHttpResponseCode,
3459 NULL, 3405 NULL,
3460 NULL, 3406 NULL,
3461 &myHttpResponseData, 3407 &myHttpResponseData,
3462 &myHttpResponseDataLen) != SECSuccess) { 3408 &myHttpResponseDataLen) != SECSuccess) {
3463 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); 3409 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
3464 goto loser; 3410 goto loser;
3465 } 3411 }
3466 3412
3467 OCSP_TRACE(("OCSP trySendAndReceive result http %d\n", myHttpResponseCode)); 3413 OCSP_TRACE(("OCSP trySendAndReceive result http %d\n", myHttpResponseCode));
3468 3414
3469 if (myHttpResponseCode != 200) { 3415 if (myHttpResponseCode != 200) {
3470 PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); 3416 PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE);
3471 goto loser; 3417 goto loser;
3472 } 3418 }
3473 3419
3474 encodedResponse = SECITEM_AllocItem(arena, NULL, myHttpResponseDataLen); 3420 encodedResponse = SECITEM_AllocItem(arena, NULL, myHttpResponseDataLen);
3475 3421
3476 if (!encodedResponse) { 3422 if (!encodedResponse) {
3477 PORT_SetError(SEC_ERROR_NO_MEMORY); 3423 PORT_SetError(SEC_ERROR_NO_MEMORY);
3478 goto loser; 3424 goto loser;
3479 } 3425 }
3480 3426
3481 PORT_Memcpy(encodedResponse->data, myHttpResponseData, myHttpResponseDataLen ); 3427 PORT_Memcpy(encodedResponse->data, myHttpResponseData, myHttpResponseDataLen );
3482 3428
3483 loser: 3429 loser:
3484 if (pRequestSession != NULL) 3430 if (pRequestSession != NULL)
3485 (*hcv1->freeFcn)(pRequestSession); 3431 (*hcv1->freeFcn)(pRequestSession);
3486 if (pServerSession != NULL) 3432 if (pServerSession != NULL)
3487 (*hcv1->freeSessionFcn)(pServerSession); 3433 (*hcv1->freeSessionFcn)(pServerSession);
3488 if (path != NULL) 3434 if (path != NULL)
3489 » PORT_Free(path); 3435 PORT_Free(path);
3490 if (hostname != NULL) 3436 if (hostname != NULL)
3491 » PORT_Free(hostname); 3437 PORT_Free(hostname);
3492 3438
3493 return encodedResponse; 3439 return encodedResponse;
3494 } 3440 }
3495 3441
3496 /* 3442 /*
3497 * FUNCTION: CERT_GetEncodedOCSPResponseByMethod 3443 * FUNCTION: CERT_GetEncodedOCSPResponseByMethod
3498 * Creates and sends a request to an OCSP responder, then reads and 3444 * Creates and sends a request to an OCSP responder, then reads and
3499 * returns the (encoded) response. 3445 * returns the (encoded) response.
3500 * INPUTS: 3446 * INPUTS:
3501 * PLArenaPool *arena 3447 * PLArenaPool *arena
3502 * Pointer to arena from which return value will be allocated. 3448 * Pointer to arena from which return value will be allocated.
3503 * If NULL, result will be allocated from the heap (and thus should 3449 * If NULL, result will be allocated from the heap (and thus should
3504 * be freed via SECITEM_FreeItem). 3450 * be freed via SECITEM_FreeItem).
3505 * CERTCertList *certList 3451 * CERTCertList *certList
3506 * A list of certs for which status will be requested. 3452 * A list of certs for which status will be requested.
3507 * Note that all of these certificates should have the same issuer, 3453 * Note that all of these certificates should have the same issuer,
3508 * or it's expected the response will be signed by a trusted responder. 3454 * or it's expected the response will be signed by a trusted responder.
3509 * If the certs need to be broken up into multiple requests, that 3455 * If the certs need to be broken up into multiple requests, that
3510 * must be handled by the caller (and thus by having multiple calls 3456 * must be handled by the caller (and thus by having multiple calls
3511 * to this routine), who knows about where the request(s) are being 3457 * to this routine), who knows about where the request(s) are being
3512 * sent and whether there are any trusted responders in place. 3458 * sent and whether there are any trusted responders in place.
3513 * const char *location 3459 * const char *location
3514 * The location of the OCSP responder (a URL). 3460 * The location of the OCSP responder (a URL).
3515 * const char *method 3461 * const char *method
3516 * The protocol method used when retrieving the OCSP response. 3462 * The protocol method used when retrieving the OCSP response.
3517 * Currently support: "GET" (http GET) and "POST" (http POST). 3463 * Currently support: "GET" (http GET) and "POST" (http POST).
3518 * Additionals methods for http or other protocols might be added 3464 * Additionals methods for http or other protocols might be added
3519 * in the future. 3465 * in the future.
3520 * PRTime time 3466 * PRTime time
3521 * Indicates the time for which the certificate status is to be 3467 * Indicates the time for which the certificate status is to be
3522 * determined -- this may be used in the search for the cert's issuer 3468 * determined -- this may be used in the search for the cert's issuer
3523 * but has no other bearing on the operation. 3469 * but has no other bearing on the operation.
3524 * PRBool addServiceLocator 3470 * PRBool addServiceLocator
3525 * If true, the Service Locator extension should be added to the 3471 * If true, the Service Locator extension should be added to the
3526 * single request(s) for each cert. 3472 * single request(s) for each cert.
3527 * CERTCertificate *signerCert 3473 * CERTCertificate *signerCert
3528 * If non-NULL, means sign the request using this cert. Otherwise, 3474 * If non-NULL, means sign the request using this cert. Otherwise,
3529 * do not sign. 3475 * do not sign.
3530 * void *pwArg 3476 * void *pwArg
3531 * Pointer to argument for password prompting, if needed. (Definitely 3477 * Pointer to argument for password prompting, if needed. (Definitely
3532 * not needed if not signing.) 3478 * not needed if not signing.)
3533 * OUTPUTS: 3479 * OUTPUTS:
3534 * CERTOCSPRequest **pRequest 3480 * CERTOCSPRequest **pRequest
3535 * Pointer in which to store the OCSP request created for the given 3481 * Pointer in which to store the OCSP request created for the given
3536 * list of certificates. It is only filled in if the entire operation 3482 * list of certificates. It is only filled in if the entire operation
3537 * is successful and the pointer is not null -- and in that case the 3483 * is successful and the pointer is not null -- and in that case the
3538 * caller is then reponsible for destroying it. 3484 * caller is then reponsible for destroying it.
3539 * RETURN: 3485 * RETURN:
3540 * Returns a pointer to the SECItem holding the response. 3486 * Returns a pointer to the SECItem holding the response.
3541 * On error, returns null with error set describing the reason: 3487 * On error, returns null with error set describing the reason:
3542 * SEC_ERROR_UNKNOWN_ISSUER 3488 * SEC_ERROR_UNKNOWN_ISSUER
3543 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION 3489 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION
3544 * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE 3490 * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE
3545 * Other errors are low-level problems (no memory, bad database, etc.). 3491 * Other errors are low-level problems (no memory, bad database, etc.).
3546 */ 3492 */
3547 SECItem * 3493 SECItem *
3548 CERT_GetEncodedOCSPResponseByMethod(PLArenaPool *arena, CERTCertList *certList, 3494 CERT_GetEncodedOCSPResponseByMethod(PLArenaPool *arena, CERTCertList *certList,
3549 » » » » const char *location, const char *method, 3495 const char *location, const char *method,
3550 » » » » PRTime time, PRBool addServiceLocator, 3496 PRTime time, PRBool addServiceLocator,
3551 » » » » CERTCertificate *signerCert, void *pwArg, 3497 CERTCertificate *signerCert, void *pwArg,
3552 » » » » CERTOCSPRequest **pRequest) 3498 CERTOCSPRequest **pRequest)
3553 { 3499 {
3554 CERTOCSPRequest *request; 3500 CERTOCSPRequest *request;
3555 request = CERT_CreateOCSPRequest(certList, time, addServiceLocator, 3501 request = CERT_CreateOCSPRequest(certList, time, addServiceLocator,
3556 signerCert); 3502 signerCert);
3557 if (!request) 3503 if (!request)
3558 return NULL; 3504 return NULL;
3559 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, 3505 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location,
3560 method, time, addServiceLocato r, 3506 method, time, addServiceLocato r,
3561 pwArg, pRequest); 3507 pwArg, pRequest);
3562 } 3508 }
3563 3509
3564 /* 3510 /*
3565 * FUNCTION: CERT_GetEncodedOCSPResponse 3511 * FUNCTION: CERT_GetEncodedOCSPResponse
3566 * Creates and sends a request to an OCSP responder, then reads and 3512 * Creates and sends a request to an OCSP responder, then reads and
3567 * returns the (encoded) response. 3513 * returns the (encoded) response.
3568 * 3514 *
3569 * This is a legacy API that behaves identically to 3515 * This is a legacy API that behaves identically to
3570 * CERT_GetEncodedOCSPResponseByMethod using the "POST" method. 3516 * CERT_GetEncodedOCSPResponseByMethod using the "POST" method.
3571 */ 3517 */
3572 SECItem * 3518 SECItem *
3573 CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList, 3519 CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
3574 » » » const char *location, PRTime time, 3520 const char *location, PRTime time,
3575 » » » PRBool addServiceLocator, 3521 PRBool addServiceLocator,
3576 » » » CERTCertificate *signerCert, void *pwArg, 3522 CERTCertificate *signerCert, void *pwArg,
3577 » » » CERTOCSPRequest **pRequest) 3523 CERTOCSPRequest **pRequest)
3578 { 3524 {
3579 return CERT_GetEncodedOCSPResponseByMethod(arena, certList, location, 3525 return CERT_GetEncodedOCSPResponseByMethod(arena, certList, location,
3580 » » » » » "POST", time, addServiceLocator, 3526 "POST", time, addServiceLocator,
3581 » » » » » signerCert, pwArg, pRequest); 3527 signerCert, pwArg, pRequest);
3582 } 3528 }
3583 3529
3584 /* URL encode a buffer that consists of base64-characters, only, 3530 /* URL encode a buffer that consists of base64-characters, only,
3585 * which means we can use a simple encoding logic. 3531 * which means we can use a simple encoding logic.
3586 * 3532 *
3587 * No output buffer size checking is performed. 3533 * No output buffer size checking is performed.
3588 * You should call the function twice, to calculate the required buffer size. 3534 * You should call the function twice, to calculate the required buffer size.
3589 * 3535 *
3590 * If the outpufBuf parameter is NULL, the function will calculate the 3536 * If the outpufBuf parameter is NULL, the function will calculate the
3591 * required size, including the trailing zero termination char. 3537 * required size, including the trailing zero termination char.
3592 * 3538 *
3593 * The function returns the number of bytes calculated or produced. 3539 * The function returns the number of bytes calculated or produced.
3594 */ 3540 */
3595 size_t 3541 size_t
3596 ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf) 3542 ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf)
3597 { 3543 {
3598 const char *walkInput = NULL; 3544 const char *walkInput = NULL;
3599 char *walkOutput = outputBuf; 3545 char *walkOutput = outputBuf;
3600 size_t count = 0; 3546 size_t count = 0;
3601 3547
3602 for (walkInput=base64Buf; *walkInput; ++walkInput) { 3548 for (walkInput = base64Buf; *walkInput; ++walkInput) {
3603 » char c = *walkInput; 3549 char c = *walkInput;
3604 » if (isspace(c)) 3550 if (isspace(c))
3605 » continue; 3551 continue;
3606 » switch (c) { 3552 switch (c) {
3607 » case '+': 3553 case '+':
3608 » if (outputBuf) { 3554 if (outputBuf) {
3609 » » strcpy(walkOutput, "%2B"); 3555 strcpy(walkOutput, "%2B");
3610 » » walkOutput += 3; 3556 walkOutput += 3;
3611 » } 3557 }
3612 » count += 3; 3558 count += 3;
3613 » break; 3559 break;
3614 » case '/': 3560 case '/':
3615 » if (outputBuf) { 3561 if (outputBuf) {
3616 » » strcpy(walkOutput, "%2F"); 3562 strcpy(walkOutput, "%2F");
3617 » » walkOutput += 3; 3563 walkOutput += 3;
3618 » } 3564 }
3619 » count += 3; 3565 count += 3;
3620 » break; 3566 break;
3621 » case '=': 3567 case '=':
3622 » if (outputBuf) { 3568 if (outputBuf) {
3623 » » strcpy(walkOutput, "%3D"); 3569 strcpy(walkOutput, "%3D");
3624 » » walkOutput += 3; 3570 walkOutput += 3;
3625 » } 3571 }
3626 » count += 3; 3572 count += 3;
3627 » break; 3573 break;
3628 » default: 3574 default:
3629 » if (outputBuf) { 3575 if (outputBuf) {
3630 » » *walkOutput = *walkInput; 3576 *walkOutput = *walkInput;
3631 » » ++walkOutput; 3577 ++walkOutput;
3632 » } 3578 }
3633 » ++count; 3579 ++count;
3634 » break; 3580 break;
3635 » } 3581 }
3636 } 3582 }
3637 if (outputBuf) { 3583 if (outputBuf) {
3638 » *walkOutput = 0; 3584 *walkOutput = 0;
3639 } 3585 }
3640 ++count; 3586 ++count;
3641 return count; 3587 return count;
3642 } 3588 }
3643 3589
3644 enum { max_get_request_size = 255 }; /* defined by RFC2560 */ 3590 enum { max_get_request_size = 255 }; /* defined by RFC2560 */
3645 3591
3646 static SECItem * 3592 static SECItem *
3647 cert_GetOCSPResponse(PLArenaPool *arena, const char *location, 3593 cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
3648 const SECItem *encodedRequest); 3594 const SECItem *encodedRequest);
3649 3595
3650 static SECItem * 3596 static SECItem *
3651 ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena, 3597 ocsp_GetEncodedOCSPResponseFromRequest(PLArenaPool *arena,
3652 CERTOCSPRequest *request, 3598 CERTOCSPRequest *request,
3653 const char *location, 3599 const char *location,
3654 » » » » const char *method, 3600 const char *method,
3655 » » » » PRTime time, 3601 PRTime time,
3656 PRBool addServiceLocator, 3602 PRBool addServiceLocator,
3657 void *pwArg, 3603 void *pwArg,
3658 CERTOCSPRequest **pRequest) 3604 CERTOCSPRequest **pRequest)
3659 { 3605 {
3660 SECItem *encodedRequest = NULL; 3606 SECItem *encodedRequest = NULL;
3661 SECItem *encodedResponse = NULL; 3607 SECItem *encodedResponse = NULL;
3662 SECStatus rv; 3608 SECStatus rv;
3663 3609
3664 if (!location || !*location) /* location should be at least one byte */ 3610 if (!location || !*location) /* location should be at least one byte */
3665 goto loser; 3611 goto loser;
3666 3612
3667 rv = CERT_AddOCSPAcceptableResponses(request, 3613 rv = CERT_AddOCSPAcceptableResponses(request,
3668 » » » » » SEC_OID_PKIX_OCSP_BASIC_RESPONSE); 3614 SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
3669 if (rv != SECSuccess) 3615 if (rv != SECSuccess)
3670 » goto loser; 3616 goto loser;
3671 3617
3672 encodedRequest = CERT_EncodeOCSPRequest(NULL, request, pwArg); 3618 encodedRequest = CERT_EncodeOCSPRequest(NULL, request, pwArg);
3673 if (encodedRequest == NULL) 3619 if (encodedRequest == NULL)
3674 » goto loser; 3620 goto loser;
3675 3621
3676 if (!strcmp(method, "GET")) { 3622 if (!strcmp(method, "GET")) {
3677 encodedResponse = cert_GetOCSPResponse(arena, location, encodedRequest); 3623 encodedResponse = cert_GetOCSPResponse(arena, location, encodedRequest);
3678 } 3624 } else if (!strcmp(method, "POST")) {
3679 else if (!strcmp(method, "POST")) {
3680 encodedResponse = CERT_PostOCSPRequest(arena, location, encodedRequest); 3625 encodedResponse = CERT_PostOCSPRequest(arena, location, encodedRequest);
3681 } 3626 } else {
3682 else { 3627 goto loser;
3683 » goto loser;
3684 } 3628 }
3685 3629
3686 if (encodedResponse != NULL && pRequest != NULL) { 3630 if (encodedResponse != NULL && pRequest != NULL) {
3687 » *pRequest = request; 3631 *pRequest = request;
3688 » request = NULL;»» » /* avoid destroying below */ 3632 request = NULL; /* avoid destroying below */
3689 } 3633 }
3690 3634
3691 loser: 3635 loser:
3692 if (request != NULL) 3636 if (request != NULL)
3693 » CERT_DestroyOCSPRequest(request); 3637 CERT_DestroyOCSPRequest(request);
3694 if (encodedRequest != NULL) 3638 if (encodedRequest != NULL)
3695 » SECITEM_FreeItem(encodedRequest, PR_TRUE); 3639 SECITEM_FreeItem(encodedRequest, PR_TRUE);
3696 return encodedResponse; 3640 return encodedResponse;
3697 } 3641 }
3698 3642
3699 static SECItem * 3643 static SECItem *
3700 cert_FetchOCSPResponse(PLArenaPool *arena, const char *location, 3644 cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
3701 const SECItem *encodedRequest); 3645 const SECItem *encodedRequest);
3702 3646
3703 /* using HTTP GET method */ 3647 /* using HTTP GET method */
3704 static SECItem * 3648 static SECItem *
3705 cert_GetOCSPResponse(PLArenaPool *arena, const char *location, 3649 cert_GetOCSPResponse(PLArenaPool *arena, const char *location,
3706 const SECItem *encodedRequest) 3650 const SECItem *encodedRequest)
3707 { 3651 {
3708 char *walkOutput = NULL; 3652 char *walkOutput = NULL;
3709 char *fullGetPath = NULL; 3653 char *fullGetPath = NULL;
3710 size_t pathLength; 3654 size_t pathLength;
3711 PRInt32 urlEncodedBufLength; 3655 PRInt32 urlEncodedBufLength;
3712 size_t base64size; 3656 size_t base64size;
3713 char b64ReqBuf[max_get_request_size+1]; 3657 char b64ReqBuf[max_get_request_size + 1];
3714 size_t slashLengthIfNeeded = 0; 3658 size_t slashLengthIfNeeded = 0;
3715 size_t getURLLength; 3659 size_t getURLLength;
3716 SECItem *item; 3660 SECItem *item;
3717 3661
3718 if (!location || !*location) { 3662 if (!location || !*location) {
3719 » return NULL; 3663 return NULL;
3720 } 3664 }
3721 3665
3722 pathLength = strlen(location); 3666 pathLength = strlen(location);
3723 if (location[pathLength-1] != '/') { 3667 if (location[pathLength - 1] != '/') {
3724 » slashLengthIfNeeded = 1; 3668 slashLengthIfNeeded = 1;
3725 } 3669 }
3726 3670
3727 /* Calculation as documented by PL_Base64Encode function. 3671 /* Calculation as documented by PL_Base64Encode function.
3728 * Use integer conversion to avoid having to use function ceil(). 3672 * Use integer conversion to avoid having to use function ceil().
3729 */ 3673 */
3730 base64size = (((encodedRequest->len +2)/3) * 4); 3674 base64size = (((encodedRequest->len + 2) / 3) * 4);
3731 if (base64size > max_get_request_size) { 3675 if (base64size > max_get_request_size) {
3732 » return NULL; 3676 return NULL;
3733 } 3677 }
3734 memset(b64ReqBuf, 0, sizeof(b64ReqBuf)); 3678 memset(b64ReqBuf, 0, sizeof(b64ReqBuf));
3735 PL_Base64Encode((const char*)encodedRequest->data, encodedRequest->len, 3679 PL_Base64Encode((const char *)encodedRequest->data, encodedRequest->len,
3736 » » b64ReqBuf); 3680 b64ReqBuf);
3737 3681
3738 urlEncodedBufLength = ocsp_UrlEncodeBase64Buf(b64ReqBuf, NULL); 3682 urlEncodedBufLength = ocsp_UrlEncodeBase64Buf(b64ReqBuf, NULL);
3739 getURLLength = pathLength + urlEncodedBufLength + slashLengthIfNeeded; 3683 getURLLength = pathLength + urlEncodedBufLength + slashLengthIfNeeded;
3740 3684
3741 /* urlEncodedBufLength already contains room for the zero terminator. 3685 /* urlEncodedBufLength already contains room for the zero terminator.
3742 * Add another if we must add the '/' char. 3686 * Add another if we must add the '/' char.
3743 */ 3687 */
3744 if (arena) { 3688 if (arena) {
3745 fullGetPath = (char*)PORT_ArenaAlloc(arena, getURLLength); 3689 fullGetPath = (char *)PORT_ArenaAlloc(arena, getURLLength);
3746 } else { 3690 } else {
3747 fullGetPath = (char*)PORT_Alloc(getURLLength); 3691 fullGetPath = (char *)PORT_Alloc(getURLLength);
3748 } 3692 }
3749 if (!fullGetPath) { 3693 if (!fullGetPath) {
3750 » return NULL; 3694 return NULL;
3751 } 3695 }
3752 3696
3753 strcpy(fullGetPath, location); 3697 strcpy(fullGetPath, location);
3754 walkOutput = fullGetPath + pathLength; 3698 walkOutput = fullGetPath + pathLength;
3755 3699
3756 if (walkOutput > fullGetPath && slashLengthIfNeeded) { 3700 if (walkOutput > fullGetPath && slashLengthIfNeeded) {
3757 strcpy(walkOutput, "/"); 3701 strcpy(walkOutput, "/");
3758 ++walkOutput; 3702 ++walkOutput;
3759 } 3703 }
3760 ocsp_UrlEncodeBase64Buf(b64ReqBuf, walkOutput); 3704 ocsp_UrlEncodeBase64Buf(b64ReqBuf, walkOutput);
3761 3705
3762 item = cert_FetchOCSPResponse(arena, fullGetPath, NULL); 3706 item = cert_FetchOCSPResponse(arena, fullGetPath, NULL);
3763 if (!arena) { 3707 if (!arena) {
3764 » PORT_Free(fullGetPath); 3708 PORT_Free(fullGetPath);
3765 } 3709 }
3766 return item; 3710 return item;
3767 } 3711 }
3768 3712
3769 SECItem * 3713 SECItem *
3770 CERT_PostOCSPRequest(PLArenaPool *arena, const char *location, 3714 CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
3771 const SECItem *encodedRequest) 3715 const SECItem *encodedRequest)
3772 { 3716 {
3773 return cert_FetchOCSPResponse(arena, location, encodedRequest); 3717 return cert_FetchOCSPResponse(arena, location, encodedRequest);
3774 } 3718 }
3775 3719
3776 SECItem * 3720 SECItem *
3777 cert_FetchOCSPResponse(PLArenaPool *arena, const char *location, 3721 cert_FetchOCSPResponse(PLArenaPool *arena, const char *location,
3778 const SECItem *encodedRequest) 3722 const SECItem *encodedRequest)
3779 { 3723 {
3780 const SEC_HttpClientFcn *registeredHttpClient; 3724 const SEC_HttpClientFcn *registeredHttpClient;
3781 SECItem *encodedResponse = NULL; 3725 SECItem *encodedResponse = NULL;
3782 3726
3783 registeredHttpClient = SEC_GetRegisteredHttpClient(); 3727 registeredHttpClient = SEC_GetRegisteredHttpClient();
3784 3728
3785 if (registeredHttpClient && registeredHttpClient->version == 1) { 3729 if (registeredHttpClient && registeredHttpClient->version == 1) {
3786 encodedResponse = fetchOcspHttpClientV1( 3730 encodedResponse = fetchOcspHttpClientV1(
3787 arena, 3731 arena,
3788 &registeredHttpClient->fcnTable.ftable1, 3732 &registeredHttpClient->fcnTable.ftable1,
3789 location, 3733 location,
3790 encodedRequest); 3734 encodedRequest);
3791 } else { 3735 } else {
3792 /* use internal http client */ 3736 /* use internal http client */
3793 PRFileDesc *sock = ocsp_SendEncodedRequest(location, encodedRequest); 3737 PRFileDesc *sock = ocsp_SendEncodedRequest(location, encodedRequest);
3794 if (sock) { 3738 if (sock) {
3795 encodedResponse = ocsp_GetEncodedResponse(arena, sock); 3739 encodedResponse = ocsp_GetEncodedResponse(arena, sock);
3796 PR_Close(sock); 3740 PR_Close(sock);
3797 } 3741 }
3798 } 3742 }
3799 3743
3800 return encodedResponse; 3744 return encodedResponse;
3801 } 3745 }
3802 3746
3803 static SECItem * 3747 static SECItem *
3804 ocsp_GetEncodedOCSPResponseForSingleCert(PLArenaPool *arena, 3748 ocsp_GetEncodedOCSPResponseForSingleCert(PLArenaPool *arena,
3805 CERTOCSPCertID *certID, 3749 CERTOCSPCertID *certID,
3806 CERTCertificate *singleCert, 3750 CERTCertificate *singleCert,
3807 const char *location, 3751 const char *location,
3808 » » » » » const char *method, 3752 const char *method,
3809 » » » » » PRTime time, 3753 PRTime time,
3810 PRBool addServiceLocator, 3754 PRBool addServiceLocator,
3811 void *pwArg, 3755 void *pwArg,
3812 CERTOCSPRequest **pRequest) 3756 CERTOCSPRequest **pRequest)
3813 { 3757 {
3814 CERTOCSPRequest *request; 3758 CERTOCSPRequest *request;
3815 request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time, 3759 request = cert_CreateSingleCertOCSPRequest(certID, singleCert, time,
3816 addServiceLocator, NULL); 3760 addServiceLocator, NULL);
3817 if (!request) 3761 if (!request)
3818 return NULL; 3762 return NULL;
3819 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location, 3763 return ocsp_GetEncodedOCSPResponseFromRequest(arena, request, location,
3820 method, time, addServiceLocato r, 3764 method, time, addServiceLocato r,
3821 pwArg, pRequest); 3765 pwArg, pRequest);
3822 } 3766 }
3823 3767
3824 /* Checks a certificate for the key usage extension of OCSP signer. */ 3768 /* Checks a certificate for the key usage extension of OCSP signer. */
3825 static PRBool 3769 static PRBool
3826 ocsp_CertIsOCSPDesignatedResponder(CERTCertificate *cert) 3770 ocsp_CertIsOCSPDesignatedResponder(CERTCertificate *cert)
3827 { 3771 {
3828 SECStatus rv; 3772 SECStatus rv;
3829 SECItem extItem; 3773 SECItem extItem;
3830 SECItem **oids; 3774 SECItem **oids;
3831 SECItem *oid; 3775 SECItem *oid;
3832 SECOidTag oidTag; 3776 SECOidTag oidTag;
3833 PRBool retval; 3777 PRBool retval;
3834 CERTOidSequence *oidSeq = NULL; 3778 CERTOidSequence *oidSeq = NULL;
3835 3779
3836
3837 extItem.data = NULL; 3780 extItem.data = NULL;
3838 rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem); 3781 rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem);
3839 if ( rv != SECSuccess ) { 3782 if (rv != SECSuccess) {
3840 » goto loser; 3783 goto loser;
3841 } 3784 }
3842 3785
3843 oidSeq = CERT_DecodeOidSequence(&extItem); 3786 oidSeq = CERT_DecodeOidSequence(&extItem);
3844 if ( oidSeq == NULL ) { 3787 if (oidSeq == NULL) {
3845 » goto loser; 3788 goto loser;
3846 } 3789 }
3847 3790
3848 oids = oidSeq->oids; 3791 oids = oidSeq->oids;
3849 while ( *oids != NULL ) { 3792 while (*oids != NULL) {
3850 » oid = *oids; 3793 oid = *oids;
3851 » 3794
3852 » oidTag = SECOID_FindOIDTag(oid); 3795 oidTag = SECOID_FindOIDTag(oid);
3853 » 3796
3854 » if ( oidTag == SEC_OID_OCSP_RESPONDER ) { 3797 if (oidTag == SEC_OID_OCSP_RESPONDER) {
3855 » goto success; 3798 goto success;
3856 » } 3799 }
3857 » 3800
3858 » oids++; 3801 oids++;
3859 } 3802 }
3860 3803
3861 loser: 3804 loser:
3862 retval = PR_FALSE; 3805 retval = PR_FALSE;
3863 PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT); 3806 PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
3864 goto done; 3807 goto done;
3865 success: 3808 success:
3866 retval = PR_TRUE; 3809 retval = PR_TRUE;
3867 done: 3810 done:
3868 if ( extItem.data != NULL ) { 3811 if (extItem.data != NULL) {
3869 » PORT_Free(extItem.data); 3812 PORT_Free(extItem.data);
3870 } 3813 }
3871 if ( oidSeq != NULL ) { 3814 if (oidSeq != NULL) {
3872 » CERT_DestroyOidSequence(oidSeq); 3815 CERT_DestroyOidSequence(oidSeq);
3873 } 3816 }
3874 3817
3875 return(retval); 3818 return (retval);
3876 } 3819 }
3877 3820
3878 3821 #ifdef LATER /*
3879 #ifdef LATER» /* 3822 * XXX This function is not currently used, but will
3880 » » * XXX This function is not currently used, but will 3823 * be needed later when we do revocation checking of
3881 » » * be needed later when we do revocation checking of 3824 * the responder certificate. Of course, it may need
3882 » » * the responder certificate. Of course, it may need 3825 * revising then, if the cert extension interface has
3883 » » * revising then, if the cert extension interface has 3826 * changed. (Hopefully it will!)
3884 » » * changed. (Hopefully it will!) 3827 */
3885 » » */
3886 3828
3887 /* Checks a certificate to see if it has the OCSP no check extension. */ 3829 /* Checks a certificate to see if it has the OCSP no check extension. */
3888 static PRBool 3830 static PRBool
3889 ocsp_CertHasNoCheckExtension(CERTCertificate *cert) 3831 ocsp_CertHasNoCheckExtension(CERTCertificate *cert)
3890 { 3832 {
3891 SECStatus rv; 3833 SECStatus rv;
3892 3834
3893 rv = CERT_FindCertExtension(cert, SEC_OID_PKIX_OCSP_NO_CHECK, 3835 rv = CERT_FindCertExtension(cert, SEC_OID_PKIX_OCSP_NO_CHECK,
3894 » » » » NULL); 3836 NULL);
3895 if (rv == SECSuccess) { 3837 if (rv == SECSuccess) {
3896 » return PR_TRUE; 3838 return PR_TRUE;
3897 } 3839 }
3898 return PR_FALSE; 3840 return PR_FALSE;
3899 } 3841 }
3900 #endif» /* LATER */ 3842 #endif /* LATER */
3901 3843
3902 static PRBool 3844 static PRBool
3903 ocsp_matchcert(SECItem *certIndex,CERTCertificate *testCert) 3845 ocsp_matchcert(SECItem *certIndex, CERTCertificate *testCert)
3904 { 3846 {
3905 SECItem item; 3847 SECItem item;
3906 unsigned char buf[HASH_LENGTH_MAX]; 3848 unsigned char buf[HASH_LENGTH_MAX];
3907 3849
3908 item.data = buf; 3850 item.data = buf;
3909 item.len = SHA1_LENGTH; 3851 item.len = SHA1_LENGTH;
3910 3852
3911 if (CERT_GetSubjectPublicKeyDigest(NULL,testCert,SEC_OID_SHA1, 3853 if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_SHA1,
3912 » » » » &item) == NULL) { 3854 &item) == NULL) {
3913 » return PR_FALSE; 3855 return PR_FALSE;
3914 } 3856 }
3915 if (SECITEM_ItemsAreEqual(certIndex,&item)) { 3857 if (SECITEM_ItemsAreEqual(certIndex, &item)) {
3916 » return PR_TRUE; 3858 return PR_TRUE;
3917 } 3859 }
3918 if (CERT_GetSubjectPublicKeyDigest(NULL,testCert,SEC_OID_MD5, 3860 if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_MD5,
3919 » » » » &item) == NULL) { 3861 &item) == NULL) {
3920 » return PR_FALSE; 3862 return PR_FALSE;
3921 } 3863 }
3922 if (SECITEM_ItemsAreEqual(certIndex,&item)) { 3864 if (SECITEM_ItemsAreEqual(certIndex, &item)) {
3923 » return PR_TRUE; 3865 return PR_TRUE;
3924 } 3866 }
3925 if (CERT_GetSubjectPublicKeyDigest(NULL,testCert,SEC_OID_MD2, 3867 if (CERT_GetSubjectPublicKeyDigest(NULL, testCert, SEC_OID_MD2,
3926 » » » » &item) == NULL) { 3868 &item) == NULL) {
3927 » return PR_FALSE; 3869 return PR_FALSE;
3928 } 3870 }
3929 if (SECITEM_ItemsAreEqual(certIndex,&item)) { 3871 if (SECITEM_ItemsAreEqual(certIndex, &item)) {
3930 » return PR_TRUE; 3872 return PR_TRUE;
3931 } 3873 }
3932 3874
3933 return PR_FALSE; 3875 return PR_FALSE;
3934 } 3876 }
3935 3877
3936 static CERTCertificate * 3878 static CERTCertificate *
3937 ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID); 3879 ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID);
3938 3880
3939 CERTCertificate * 3881 CERTCertificate *
3940 ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData, 3882 ocsp_GetSignerCertificate(CERTCertDBHandle *handle, ocspResponseData *tbsData,
3941 ocspSignature *signature, CERTCertificate *issuer) 3883 ocspSignature *signature, CERTCertificate *issuer)
3942 { 3884 {
3943 CERTCertificate **certs = NULL; 3885 CERTCertificate **certs = NULL;
3944 CERTCertificate *signerCert = NULL; 3886 CERTCertificate *signerCert = NULL;
3945 SECStatus rv = SECFailure; 3887 SECStatus rv = SECFailure;
3946 PRBool lookupByName = PR_TRUE; 3888 PRBool lookupByName = PR_TRUE;
3947 void *certIndex = NULL; 3889 void *certIndex = NULL;
3948 int certCount = 0; 3890 int certCount = 0;
3949 3891
3950 PORT_Assert(tbsData->responderID != NULL); 3892 PORT_Assert(tbsData->responderID != NULL);
3951 switch (tbsData->responderID->responderIDType) { 3893 switch (tbsData->responderID->responderIDType) {
3952 case ocspResponderID_byName: 3894 case ocspResponderID_byName:
3953 » lookupByName = PR_TRUE; 3895 lookupByName = PR_TRUE;
3954 » certIndex = &tbsData->derResponderID; 3896 certIndex = &tbsData->derResponderID;
3955 » break; 3897 break;
3956 case ocspResponderID_byKey: 3898 case ocspResponderID_byKey:
3957 » lookupByName = PR_FALSE; 3899 lookupByName = PR_FALSE;
3958 » certIndex = &tbsData->responderID->responderIDValue.keyHash; 3900 certIndex = &tbsData->responderID->responderIDValue.keyHash;
3959 » break; 3901 break;
3960 case ocspResponderID_other: 3902 case ocspResponderID_other:
3961 default: 3903 default:
3962 » PORT_Assert(0); 3904 PORT_Assert(0);
3963 » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); 3905 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
3964 » return NULL; 3906 return NULL;
3965 } 3907 }
3966 3908
3967 /* 3909 /*
3968 * If the signature contains some certificates as well, temporarily 3910 * If the signature contains some certificates as well, temporarily
3969 * import them in case they are needed for verification. 3911 * import them in case they are needed for verification.
3970 * 3912 *
3971 * Note that the result of this is that each cert in "certs" needs 3913 * Note that the result of this is that each cert in "certs" needs
3972 * to be destroyed. 3914 * to be destroyed.
3973 */ 3915 */
3974 if (signature->derCerts != NULL) { 3916 if (signature->derCerts != NULL) {
3975 » for (; signature->derCerts[certCount] != NULL; certCount++) { 3917 for (; signature->derCerts[certCount] != NULL; certCount++) {
3976 » /* just counting */ 3918 /* just counting */
3977 » } 3919 }
3978 » rv = CERT_ImportCerts(handle, certUsageStatusResponder, certCount, 3920 rv = CERT_ImportCerts(handle, certUsageStatusResponder, certCount,
3979 » signature->derCerts, &certs, 3921 signature->derCerts, &certs,
3980 » PR_FALSE, PR_FALSE, NULL); 3922 PR_FALSE, PR_FALSE, NULL);
3981 » if (rv != SECSuccess) 3923 if (rv != SECSuccess)
3982 » goto finish; 3924 goto finish;
3983 } 3925 }
3984 3926
3985 /* 3927 /*
3986 * Now look up the certificate that did the signing. 3928 * Now look up the certificate that did the signing.
3987 * The signer can be specified either by name or by key hash. 3929 * The signer can be specified either by name or by key hash.
3988 */ 3930 */
3989 if (lookupByName) { 3931 if (lookupByName) {
3990 » SECItem *crIndex = (SECItem*)certIndex; 3932 SECItem *crIndex = (SECItem *)certIndex;
3991 » SECItem encodedName; 3933 SECItem encodedName;
3992 » PLArenaPool *arena; 3934 PLArenaPool *arena;
3993 3935
3994 » arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 3936 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
3995 » if (arena != NULL) { 3937 if (arena != NULL) {
3996 3938
3997 » rv = SEC_QuickDERDecodeItem(arena, &encodedName, 3939 rv = SEC_QuickDERDecodeItem(arena, &encodedName,
3998 » ocsp_ResponderIDDerNameTemplate, 3940 ocsp_ResponderIDDerNameTemplate,
3999 » crIndex); 3941 crIndex);
4000 » if (rv != SECSuccess) { 3942 if (rv != SECSuccess) {
4001 » if (PORT_GetError() == SEC_ERROR_BAD_DER) 3943 if (PORT_GetError() == SEC_ERROR_BAD_DER)
4002 » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); 3944 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
4003 » } else { 3945 } else {
4004 » signerCert = CERT_FindCertByName(handle, &encodedName); 3946 signerCert = CERT_FindCertByName(handle, &encodedName);
4005 » } 3947 }
4006 » PORT_FreeArena(arena, PR_FALSE); 3948 PORT_FreeArena(arena, PR_FALSE);
4007 » } 3949 }
4008 } else { 3950 } else {
4009 » /* 3951 /*
4010 » * The signer is either 1) a known issuer CA we passed in, 3952 » * The signer is either 1) a known issuer CA we passed in,
4011 » * 2) the default OCSP responder, or 3) an intermediate CA 3953 » * 2) the default OCSP responder, or 3) an intermediate CA
4012 » * passed in the cert list to use. Figure out which it is. 3954 » * passed in the cert list to use. Figure out which it is.
4013 » */ 3955 » */
4014 » int i; 3956 int i;
4015 » CERTCertificate *responder = 3957 CERTCertificate *responder =
4016 ocsp_CertGetDefaultResponder(handle, NULL); 3958 ocsp_CertGetDefaultResponder(handle, NULL);
4017 » if (responder && ocsp_matchcert(certIndex,responder)) { 3959 if (responder && ocsp_matchcert(certIndex, responder)) {
4018 » signerCert = CERT_DupCertificate(responder); 3960 signerCert = CERT_DupCertificate(responder);
4019 » } else if (issuer && ocsp_matchcert(certIndex,issuer)) { 3961 } else if (issuer && ocsp_matchcert(certIndex, issuer)) {
4020 » signerCert = CERT_DupCertificate(issuer); 3962 signerCert = CERT_DupCertificate(issuer);
4021 » } 3963 }
4022 » for (i=0; (signerCert == NULL) && (i < certCount); i++) { 3964 for (i = 0; (signerCert == NULL) && (i < certCount); i++) {
4023 » if (ocsp_matchcert(certIndex,certs[i])) { 3965 if (ocsp_matchcert(certIndex, certs[i])) {
4024 » » signerCert = CERT_DupCertificate(certs[i]); 3966 signerCert = CERT_DupCertificate(certs[i]);
4025 » } 3967 }
4026 » } 3968 }
4027 » if (signerCert == NULL) { 3969 if (signerCert == NULL) {
4028 » PORT_SetError(SEC_ERROR_UNKNOWN_CERT); 3970 PORT_SetError(SEC_ERROR_UNKNOWN_CERT);
4029 » } 3971 }
4030 } 3972 }
4031 3973
4032 finish: 3974 finish:
4033 if (certs != NULL) { 3975 if (certs != NULL) {
4034 » CERT_DestroyCertArray(certs, certCount); 3976 CERT_DestroyCertArray(certs, certCount);
4035 } 3977 }
4036 3978
4037 return signerCert; 3979 return signerCert;
4038 } 3980 }
4039 3981
4040 SECStatus 3982 SECStatus
4041 ocsp_VerifyResponseSignature(CERTCertificate *signerCert, 3983 ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
4042 ocspSignature *signature, 3984 ocspSignature *signature,
4043 SECItem *tbsResponseDataDER, 3985 SECItem *tbsResponseDataDER,
4044 void *pwArg) 3986 void *pwArg)
(...skipping 15 matching lines...) Expand all
4060 * We copy the signature data *pointer* and length, so that we can 4002 * We copy the signature data *pointer* and length, so that we can
4061 * modify the length without damaging the original copy. This is a 4003 * modify the length without damaging the original copy. This is a
4062 * simple copy, not a dup, so no destroy/free is necessary. 4004 * simple copy, not a dup, so no destroy/free is necessary.
4063 */ 4005 */
4064 signedData.signature = signature->signature; 4006 signedData.signature = signature->signature;
4065 signedData.signatureAlgorithm = signature->signatureAlgorithm; 4007 signedData.signatureAlgorithm = signature->signatureAlgorithm;
4066 signedData.data = *tbsResponseDataDER; 4008 signedData.data = *tbsResponseDataDER;
4067 4009
4068 rv = CERT_VerifySignedDataWithPublicKey(&signedData, signerKey, pwArg); 4010 rv = CERT_VerifySignedDataWithPublicKey(&signedData, signerKey, pwArg);
4069 if (rv != SECSuccess && 4011 if (rv != SECSuccess &&
4070 (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE || 4012 (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE ||
4071 PORT_GetError() == SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)) { 4013 PORT_GetError() == SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)) {
4072 PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE); 4014 PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE);
4073 } 4015 }
4074 4016
4075 if (signerKey != NULL) { 4017 if (signerKey != NULL) {
4076 SECKEY_DestroyPublicKey(signerKey); 4018 SECKEY_DestroyPublicKey(signerKey);
4077 } 4019 }
4078 4020
4079 return rv; 4021 return rv;
4080 } 4022 }
4081 4023
4082
4083 /* 4024 /*
4084 * FUNCTION: CERT_VerifyOCSPResponseSignature 4025 * FUNCTION: CERT_VerifyOCSPResponseSignature
4085 * Check the signature on an OCSP Response. Will also perform a 4026 * Check the signature on an OCSP Response. Will also perform a
4086 * verification of the signer's certificate. Note, however, that a 4027 * verification of the signer's certificate. Note, however, that a
4087 * successful verification does not make any statement about the 4028 * successful verification does not make any statement about the
4088 * signer's *authority* to provide status for the certificate(s), 4029 * signer's *authority* to provide status for the certificate(s),
4089 * that must be checked individually for each certificate. 4030 * that must be checked individually for each certificate.
4090 * INPUTS: 4031 * INPUTS:
4091 * CERTOCSPResponse *response 4032 * CERTOCSPResponse *response
4092 * Pointer to response structure with signature to be checked. 4033 * Pointer to response structure with signature to be checked.
(...skipping 10 matching lines...) Expand all
4103 * Possible errors set: 4044 * Possible errors set:
4104 * SEC_ERROR_OCSP_MALFORMED_RESPONSE - unknown type of ResponderID 4045 * SEC_ERROR_OCSP_MALFORMED_RESPONSE - unknown type of ResponderID
4105 * SEC_ERROR_INVALID_TIME - bad format of "ProducedAt" time 4046 * SEC_ERROR_INVALID_TIME - bad format of "ProducedAt" time
4106 * SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found 4047 * SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found
4107 * SEC_ERROR_BAD_SIGNATURE - the signature did not verify 4048 * SEC_ERROR_BAD_SIGNATURE - the signature did not verify
4108 * Other errors are any of the many possible failures in cert verification 4049 * Other errors are any of the many possible failures in cert verification
4109 * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when 4050 * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
4110 * verifying the signer's cert, or low-level problems (no memory, etc.) 4051 * verifying the signer's cert, or low-level problems (no memory, etc.)
4111 */ 4052 */
4112 SECStatus 4053 SECStatus
4113 CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,» 4054 CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
4114 » » » » CERTCertDBHandle *handle, void *pwArg, 4055 CERTCertDBHandle *handle, void *pwArg,
4115 » » » » CERTCertificate **pSignerCert, 4056 CERTCertificate **pSignerCert,
4116 » » » » CERTCertificate *issuer) 4057 CERTCertificate *issuer)
4117 { 4058 {
4118 SECItem *tbsResponseDataDER; 4059 SECItem *tbsResponseDataDER;
4119 CERTCertificate *signerCert = NULL; 4060 CERTCertificate *signerCert = NULL;
4120 SECStatus rv = SECFailure; 4061 SECStatus rv = SECFailure;
4121 PRTime producedAt; 4062 PRTime producedAt;
4122 4063
4123 /* ocsp_DecodeBasicOCSPResponse will fail if asn1 decoder is unable 4064 /* ocsp_DecodeBasicOCSPResponse will fail if asn1 decoder is unable
4124 * to properly decode tbsData (see the function and 4065 * to properly decode tbsData (see the function and
4125 * ocsp_BasicOCSPResponseTemplate). Thus, tbsData can not be 4066 * ocsp_BasicOCSPResponseTemplate). Thus, tbsData can not be
4126 * equal to null */ 4067 * equal to null */
4127 ocspResponseData *tbsData = ocsp_GetResponseData(response, 4068 ocspResponseData *tbsData = ocsp_GetResponseData(response,
4128 &tbsResponseDataDER); 4069 &tbsResponseDataDER);
4129 ocspSignature *signature = ocsp_GetResponseSignature(response); 4070 ocspSignature *signature = ocsp_GetResponseSignature(response);
4130 4071
4131 if (!signature) { 4072 if (!signature) {
4132 PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE); 4073 PORT_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE);
4133 return SECFailure; 4074 return SECFailure;
4134 } 4075 }
4135 4076
4136 /* 4077 /*
4137 * If this signature has already gone through verification, just 4078 * If this signature has already gone through verification, just
4138 * return the cached result. 4079 * return the cached result.
4139 */ 4080 */
4140 if (signature->wasChecked) { 4081 if (signature->wasChecked) {
4141 » if (signature->status == SECSuccess) { 4082 if (signature->status == SECSuccess) {
4142 » if (pSignerCert != NULL) 4083 if (pSignerCert != NULL)
4143 » » *pSignerCert = CERT_DupCertificate(signature->cert); 4084 *pSignerCert = CERT_DupCertificate(signature->cert);
4144 » } else { 4085 } else {
4145 » PORT_SetError(signature->failureReason); 4086 PORT_SetError(signature->failureReason);
4146 » } 4087 }
4147 » return signature->status; 4088 return signature->status;
4148 } 4089 }
4149 4090
4150 signerCert = ocsp_GetSignerCertificate(handle, tbsData, 4091 signerCert = ocsp_GetSignerCertificate(handle, tbsData,
4151 signature, issuer); 4092 signature, issuer);
4152 if (signerCert == NULL) { 4093 if (signerCert == NULL) {
4153 » rv = SECFailure; 4094 rv = SECFailure;
4154 » if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) { 4095 if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) {
4155 » /* Make the error a little more specific. */ 4096 /* Make the error a little more specific. */
4156 » PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT); 4097 PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
4157 » } 4098 }
4158 » goto finish; 4099 goto finish;
4159 } 4100 }
4160 4101
4161 /* 4102 /*
4162 * We could mark this true at the top of this function, or always 4103 * We could mark this true at the top of this function, or always
4163 * below at "finish", but if the problem was just that we could not 4104 * below at "finish", but if the problem was just that we could not
4164 * find the signer's cert, leave that as if the signature hasn't 4105 * find the signer's cert, leave that as if the signature hasn't
4165 * been checked in case a subsequent call might have better luck. 4106 * been checked in case a subsequent call might have better luck.
4166 */ 4107 */
4167 signature->wasChecked = PR_TRUE; 4108 signature->wasChecked = PR_TRUE;
4168 4109
(...skipping 28 matching lines...) Expand all
4197 goto finish; 4138 goto finish;
4198 } 4139 }
4199 } 4140 }
4200 4141
4201 rv = ocsp_VerifyResponseSignature(signerCert, signature, 4142 rv = ocsp_VerifyResponseSignature(signerCert, signature,
4202 tbsResponseDataDER, 4143 tbsResponseDataDER,
4203 pwArg); 4144 pwArg);
4204 4145
4205 finish: 4146 finish:
4206 if (signature->wasChecked) 4147 if (signature->wasChecked)
4207 » signature->status = rv; 4148 signature->status = rv;
4208 4149
4209 if (rv != SECSuccess) { 4150 if (rv != SECSuccess) {
4210 » signature->failureReason = PORT_GetError(); 4151 signature->failureReason = PORT_GetError();
4211 » if (signerCert != NULL) 4152 if (signerCert != NULL)
4212 » CERT_DestroyCertificate(signerCert); 4153 CERT_DestroyCertificate(signerCert);
4213 } else { 4154 } else {
4214 » /* 4155 /*
4215 » * Save signer's certificate in signature. 4156 » * Save signer's certificate in signature.
4216 » */ 4157 » */
4217 » signature->cert = signerCert; 4158 signature->cert = signerCert;
4218 » if (pSignerCert != NULL) { 4159 if (pSignerCert != NULL) {
4219 » /* 4160 /*
4220 » * Pass pointer to signer's certificate back to our caller, 4161 » * Pass pointer to signer's certificate back to our caller,
4221 » * who is also now responsible for destroying it. 4162 » * who is also now responsible for destroying it.
4222 » */ 4163 » */
4223 » *pSignerCert = CERT_DupCertificate(signerCert); 4164 *pSignerCert = CERT_DupCertificate(signerCert);
4224 » } 4165 }
4225 } 4166 }
4226 4167
4227 return rv; 4168 return rv;
4228 } 4169 }
4229 4170
4230 /* 4171 /*
4231 * See if the request's certID and the single response's certID match. 4172 * See if the request's certID and the single response's certID match.
4232 * This can be easy or difficult, depending on whether the same hash 4173 * This can be easy or difficult, depending on whether the same hash
4233 * algorithm was used. 4174 * algorithm was used.
4234 */ 4175 */
4235 static PRBool 4176 static PRBool
4236 ocsp_CertIDsMatch(CERTOCSPCertID *requestCertID, 4177 ocsp_CertIDsMatch(CERTOCSPCertID *requestCertID,
4237 » » CERTOCSPCertID *responseCertID) 4178 CERTOCSPCertID *responseCertID)
4238 { 4179 {
4239 PRBool match = PR_FALSE; 4180 PRBool match = PR_FALSE;
4240 SECOidTag hashAlg; 4181 SECOidTag hashAlg;
4241 SECItem *keyHash = NULL; 4182 SECItem *keyHash = NULL;
4242 SECItem *nameHash = NULL; 4183 SECItem *nameHash = NULL;
4243 4184
4244 /* 4185 /*
4245 * In order to match, they must have the same issuer and the same 4186 * In order to match, they must have the same issuer and the same
4246 * serial number. 4187 * serial number.
4247 * 4188 *
4248 * We just compare the easier things first. 4189 * We just compare the easier things first.
4249 */ 4190 */
4250 if (SECITEM_CompareItem(&requestCertID->serialNumber, 4191 if (SECITEM_CompareItem(&requestCertID->serialNumber,
4251 » » » &responseCertID->serialNumber) != SECEqual) { 4192 &responseCertID->serialNumber) != SECEqual) {
4252 » goto done; 4193 goto done;
4253 } 4194 }
4254 4195
4255 /* 4196 /*
4256 * Make sure the "parameters" are not too bogus. Since we encoded 4197 * Make sure the "parameters" are not too bogus. Since we encoded
4257 * requestCertID->hashAlgorithm, we don't need to check it. 4198 * requestCertID->hashAlgorithm, we don't need to check it.
4258 */ 4199 */
4259 if (responseCertID->hashAlgorithm.parameters.len > 2) { 4200 if (responseCertID->hashAlgorithm.parameters.len > 2) {
4260 » goto done; 4201 goto done;
4261 } 4202 }
4262 if (SECITEM_CompareItem(&requestCertID->hashAlgorithm.algorithm, 4203 if (SECITEM_CompareItem(&requestCertID->hashAlgorithm.algorithm,
4263 » » &responseCertID->hashAlgorithm.algorithm) == SECEqual) { 4204 &responseCertID->hashAlgorithm.algorithm) ==
4264 » /* 4205 SECEqual) {
4265 » * If the hash algorithms match then we can do a simple compare 4206 /*
4266 » * of the hash values themselves. 4207 » * If the hash algorithms match then we can do a simple compare
4267 » */ 4208 » * of the hash values themselves.
4268 » if ((SECITEM_CompareItem(&requestCertID->issuerNameHash, 4209 » */
4269 » » » » &responseCertID->issuerNameHash) == SECEqual) 4210 if ((SECITEM_CompareItem(&requestCertID->issuerNameHash,
4270 » && (SECITEM_CompareItem(&requestCertID->issuerKeyHash, 4211 &responseCertID->issuerNameHash) == SECEqual) & &
4271 » » » » &responseCertID->issuerKeyHash) == SECEqual)) { 4212 (SECITEM_CompareItem(&requestCertID->issuerKeyHash,
4272 » match = PR_TRUE; 4213 &responseCertID->issuerKeyHash) == SECEqual)) {
4273 » } 4214 match = PR_TRUE;
4274 » goto done; 4215 }
4216 goto done;
4275 } 4217 }
4276 4218
4277 hashAlg = SECOID_FindOIDTag(&responseCertID->hashAlgorithm.algorithm); 4219 hashAlg = SECOID_FindOIDTag(&responseCertID->hashAlgorithm.algorithm);
4278 switch (hashAlg) { 4220 switch (hashAlg) {
4279 case SEC_OID_SHA1: 4221 case SEC_OID_SHA1:
4280 » keyHash = &requestCertID->issuerSHA1KeyHash; 4222 keyHash = &requestCertID->issuerSHA1KeyHash;
4281 » nameHash = &requestCertID->issuerSHA1NameHash; 4223 nameHash = &requestCertID->issuerSHA1NameHash;
4282 » break; 4224 break;
4283 case SEC_OID_MD5: 4225 case SEC_OID_MD5:
4284 » keyHash = &requestCertID->issuerMD5KeyHash; 4226 keyHash = &requestCertID->issuerMD5KeyHash;
4285 » nameHash = &requestCertID->issuerMD5NameHash; 4227 nameHash = &requestCertID->issuerMD5NameHash;
4286 » break; 4228 break;
4287 case SEC_OID_MD2: 4229 case SEC_OID_MD2:
4288 » keyHash = &requestCertID->issuerMD2KeyHash; 4230 keyHash = &requestCertID->issuerMD2KeyHash;
4289 » nameHash = &requestCertID->issuerMD2NameHash; 4231 nameHash = &requestCertID->issuerMD2NameHash;
4290 » break; 4232 break;
4291 default: 4233 default:
4292 » PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 4234 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
4293 » return PR_FALSE; 4235 return PR_FALSE;
4294 } 4236 }
4295 4237
4296 if ((keyHash != NULL) 4238 if ((keyHash != NULL) &&
4297 » && (SECITEM_CompareItem(nameHash, 4239 (SECITEM_CompareItem(nameHash,
4298 » » » » &responseCertID->issuerNameHash) == SECEqual) 4240 &responseCertID->issuerNameHash) == SECEqual) &&
4299 » && (SECITEM_CompareItem(keyHash, 4241 (SECITEM_CompareItem(keyHash,
4300 » » » » &responseCertID->issuerKeyHash) == SECEqual)) { 4242 &responseCertID->issuerKeyHash) == SECEqual)) {
4301 » match = PR_TRUE; 4243 match = PR_TRUE;
4302 } 4244 }
4303 4245
4304 done: 4246 done:
4305 return match; 4247 return match;
4306 } 4248 }
4307 4249
4308 /* 4250 /*
4309 * Find the single response for the cert specified by certID. 4251 * Find the single response for the cert specified by certID.
4310 * No copying is done; this just returns a pointer to the appropriate 4252 * No copying is done; this just returns a pointer to the appropriate
4311 * response within responses, if it is found (and null otherwise). 4253 * response within responses, if it is found (and null otherwise).
4312 * This is fine, of course, since this function is internal-use only. 4254 * This is fine, of course, since this function is internal-use only.
4313 */ 4255 */
4314 static CERTOCSPSingleResponse * 4256 static CERTOCSPSingleResponse *
4315 ocsp_GetSingleResponseForCertID(CERTOCSPSingleResponse **responses, 4257 ocsp_GetSingleResponseForCertID(CERTOCSPSingleResponse **responses,
4316 » » » » CERTCertDBHandle *handle, 4258 CERTCertDBHandle *handle,
4317 » » » » CERTOCSPCertID *certID) 4259 CERTOCSPCertID *certID)
4318 { 4260 {
4319 CERTOCSPSingleResponse *single; 4261 CERTOCSPSingleResponse *single;
4320 int i; 4262 int i;
4321 4263
4322 if (responses == NULL) 4264 if (responses == NULL)
4323 » return NULL; 4265 return NULL;
4324 4266
4325 for (i = 0; responses[i] != NULL; i++) { 4267 for (i = 0; responses[i] != NULL; i++) {
4326 » single = responses[i]; 4268 single = responses[i];
4327 » if (ocsp_CertIDsMatch(certID, single->certID)) { 4269 if (ocsp_CertIDsMatch(certID, single->certID)) {
4328 » return single; 4270 return single;
4329 » } 4271 }
4330 } 4272 }
4331 4273
4332 /* 4274 /*
4333 * The OCSP server should have included a response even if it knew 4275 * The OCSP server should have included a response even if it knew
4334 * nothing about the certificate in question. Since it did not, 4276 * nothing about the certificate in question. Since it did not,
4335 * this will make it look as if it had. 4277 * this will make it look as if it had.
4336 * 4278 *
4337 * XXX Should we make this a separate error to notice the server's 4279 * XXX Should we make this a separate error to notice the server's
4338 * bad behavior? 4280 * bad behavior?
4339 */ 4281 */
4340 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT); 4282 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT);
4341 return NULL; 4283 return NULL;
4342 } 4284 }
4343 4285
4344 static ocspCheckingContext * 4286 static ocspCheckingContext *
4345 ocsp_GetCheckingContext(CERTCertDBHandle *handle) 4287 ocsp_GetCheckingContext(CERTCertDBHandle *handle)
4346 { 4288 {
4347 CERTStatusConfig *statusConfig; 4289 CERTStatusConfig *statusConfig;
4348 ocspCheckingContext *ocspcx = NULL; 4290 ocspCheckingContext *ocspcx = NULL;
4349 4291
4350 statusConfig = CERT_GetStatusConfig(handle); 4292 statusConfig = CERT_GetStatusConfig(handle);
4351 if (statusConfig != NULL) { 4293 if (statusConfig != NULL) {
4352 » ocspcx = statusConfig->statusContext; 4294 ocspcx = statusConfig->statusContext;
4353 4295
4354 » /* 4296 /*
4355 » * This is actually an internal error, because we should never 4297 » * This is actually an internal error, because we should never
4356 » * have a good statusConfig without a good statusContext, too. 4298 » * have a good statusConfig without a good statusContext, too.
4357 » * For lack of anything better, though, we just assert and use 4299 » * For lack of anything better, though, we just assert and use
4358 » * the same error as if there were no statusConfig (set below). 4300 » * the same error as if there were no statusConfig (set below).
4359 » */ 4301 » */
4360 » PORT_Assert(ocspcx != NULL); 4302 PORT_Assert(ocspcx != NULL);
4361 } 4303 }
4362 4304
4363 if (ocspcx == NULL) 4305 if (ocspcx == NULL)
4364 » PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED); 4306 PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED);
4365 4307
4366 return ocspcx; 4308 return ocspcx;
4367 } 4309 }
4368 4310
4369 /* 4311 /*
4370 * Return cert reference if the given signerCert is the default responder for 4312 * Return cert reference if the given signerCert is the default responder for
4371 * the given certID. If not, or if any error, return NULL. 4313 * the given certID. If not, or if any error, return NULL.
4372 */ 4314 */
4373 static CERTCertificate * 4315 static CERTCertificate *
4374 ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID) 4316 ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle, CERTOCSPCertID *certID)
4375 { 4317 {
4376 ocspCheckingContext *ocspcx; 4318 ocspCheckingContext *ocspcx;
4377 4319
4378 ocspcx = ocsp_GetCheckingContext(handle); 4320 ocspcx = ocsp_GetCheckingContext(handle);
4379 if (ocspcx == NULL) 4321 if (ocspcx == NULL)
4380 » goto loser; 4322 goto loser;
4381 4323
4382 /* 4324 /*
4383 * Right now we have only one default responder. It applies to 4325 * Right now we have only one default responder. It applies to
4384 * all certs when it is used, so the check is simple and certID 4326 * all certs when it is used, so the check is simple and certID
4385 * has no bearing on the answer. Someday in the future we may 4327 * has no bearing on the answer. Someday in the future we may
4386 * allow configuration of different responders for different 4328 * allow configuration of different responders for different
4387 * issuers, and then we would have to use the issuer specified 4329 * issuers, and then we would have to use the issuer specified
4388 * in certID to determine if signerCert is the right one. 4330 * in certID to determine if signerCert is the right one.
4389 */ 4331 */
4390 if (ocspcx->useDefaultResponder) { 4332 if (ocspcx->useDefaultResponder) {
4391 » PORT_Assert(ocspcx->defaultResponderCert != NULL); 4333 PORT_Assert(ocspcx->defaultResponderCert != NULL);
4392 » return ocspcx->defaultResponderCert; 4334 return ocspcx->defaultResponderCert;
4393 } 4335 }
4394 4336
4395 loser: 4337 loser:
4396 return NULL; 4338 return NULL;
4397 } 4339 }
4398 4340
4399 /* 4341 /*
4400 * Return true if the cert is one of the default responders configured for 4342 * Return true if the cert is one of the default responders configured for
4401 * ocsp context. If not, or if any error, return false. 4343 * ocsp context. If not, or if any error, return false.
4402 */ 4344 */
4403 PRBool 4345 PRBool
4404 ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert) 4346 ocsp_CertIsOCSPDefaultResponder(CERTCertDBHandle *handle, CERTCertificate *cert)
4405 { 4347 {
4406 ocspCheckingContext *ocspcx; 4348 ocspCheckingContext *ocspcx;
4407 4349
4408 ocspcx = ocsp_GetCheckingContext(handle); 4350 ocspcx = ocsp_GetCheckingContext(handle);
4409 if (ocspcx == NULL) 4351 if (ocspcx == NULL)
4410 » return PR_FALSE; 4352 return PR_FALSE;
4411 4353
4412 /* 4354 /*
4413 * Right now we have only one default responder. It applies to 4355 * Right now we have only one default responder. It applies to
4414 * all certs when it is used, so the check is simple and certID 4356 * all certs when it is used, so the check is simple and certID
4415 * has no bearing on the answer. Someday in the future we may 4357 * has no bearing on the answer. Someday in the future we may
4416 * allow configuration of different responders for different 4358 * allow configuration of different responders for different
4417 * issuers, and then we would have to use the issuer specified 4359 * issuers, and then we would have to use the issuer specified
4418 * in certID to determine if signerCert is the right one. 4360 * in certID to determine if signerCert is the right one.
4419 */ 4361 */
4420 if (ocspcx->useDefaultResponder && 4362 if (ocspcx->useDefaultResponder &&
4421 CERT_CompareCerts(ocspcx->defaultResponderCert, cert)) { 4363 CERT_CompareCerts(ocspcx->defaultResponderCert, cert)) {
4422 » return PR_TRUE; 4364 return PR_TRUE;
4423 } 4365 }
4424 4366
4425 return PR_FALSE; 4367 return PR_FALSE;
4426 } 4368 }
4427 4369
4428 /* 4370 /*
4429 * Check that the given signer certificate is authorized to sign status 4371 * Check that the given signer certificate is authorized to sign status
4430 * information for the given certID. Return true if it is, false if not 4372 * information for the given certID. Return true if it is, false if not
4431 * (or if there is any error along the way). If false is returned because 4373 * (or if there is any error along the way). If false is returned because
4432 * the signer is not authorized, the following error will be set: 4374 * the signer is not authorized, the following error will be set:
4433 * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE 4375 * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
4434 * Other errors are low-level problems (no memory, bad database, etc.). 4376 * Other errors are low-level problems (no memory, bad database, etc.).
4435 * 4377 *
4436 * There are three ways to be authorized. In the order in which we check, 4378 * There are three ways to be authorized. In the order in which we check,
4437 * using the terms used in the OCSP spec, the signer must be one of: 4379 * using the terms used in the OCSP spec, the signer must be one of:
4438 * 1. A "trusted responder" -- it matches a local configuration 4380 * 1. A "trusted responder" -- it matches a local configuration
4439 * of OCSP signing authority for the certificate in question. 4381 * of OCSP signing authority for the certificate in question.
4440 * 2. The CA who issued the certificate in question. 4382 * 2. The CA who issued the certificate in question.
4441 * 3. A "CA designated responder", aka an "authorized responder" -- it 4383 * 3. A "CA designated responder", aka an "authorized responder" -- it
4442 * must be represented by a special cert issued by the CA who issued 4384 * must be represented by a special cert issued by the CA who issued
4443 * the certificate in question. 4385 * the certificate in question.
4444 */ 4386 */
4445 static PRBool 4387 static PRBool
4446 ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle, 4388 ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle,
4447 » » » » CERTCertificate *signerCert, 4389 CERTCertificate *signerCert,
4448 » » » » CERTOCSPCertID *certID, 4390 CERTOCSPCertID *certID,
4449 » » » » PRTime thisUpdate) 4391 PRTime thisUpdate)
4450 { 4392 {
4451 CERTCertificate *issuerCert = NULL, *defRespCert; 4393 CERTCertificate *issuerCert = NULL, *defRespCert;
4452 SECItem *keyHash = NULL; 4394 SECItem *keyHash = NULL;
4453 SECItem *nameHash = NULL; 4395 SECItem *nameHash = NULL;
4454 SECOidTag hashAlg; 4396 SECOidTag hashAlg;
4455 PRBool keyHashEQ = PR_FALSE, nameHashEQ = PR_FALSE; 4397 PRBool keyHashEQ = PR_FALSE, nameHashEQ = PR_FALSE;
4456 4398
4457 /* 4399 /*
4458 * Check first for a trusted responder, which overrides everything else. 4400 * Check first for a trusted responder, which overrides everything else.
4459 */ 4401 */
(...skipping 23 matching lines...) Expand all
4483 (SECITEM_CompareItem(keyHash, 4425 (SECITEM_CompareItem(keyHash,
4484 &certID->issuerKeyHash) == SECEqual); 4426 &certID->issuerKeyHash) == SECEqual);
4485 SECITEM_FreeItem(keyHash, PR_TRUE); 4427 SECITEM_FreeItem(keyHash, PR_TRUE);
4486 } 4428 }
4487 if (keyHashEQ && 4429 if (keyHashEQ &&
4488 (nameHash = CERT_GetSubjectNameDigest(NULL, signerCert, 4430 (nameHash = CERT_GetSubjectNameDigest(NULL, signerCert,
4489 hashAlg, NULL))) { 4431 hashAlg, NULL))) {
4490 nameHashEQ = 4432 nameHashEQ =
4491 (SECITEM_CompareItem(nameHash, 4433 (SECITEM_CompareItem(nameHash,
4492 &certID->issuerNameHash) == SECEqual); 4434 &certID->issuerNameHash) == SECEqual);
4493 4435
4494 SECITEM_FreeItem(nameHash, PR_TRUE); 4436 SECITEM_FreeItem(nameHash, PR_TRUE);
4495 if (nameHashEQ) { 4437 if (nameHashEQ) {
4496 /* The issuer of the cert is the the signer of the response */ 4438 /* The issuer of the cert is the the signer of the response */
4497 return PR_TRUE; 4439 return PR_TRUE;
4498 } 4440 }
4499 } 4441 }
4500 4442
4501
4502 keyHashEQ = PR_FALSE; 4443 keyHashEQ = PR_FALSE;
4503 nameHashEQ = PR_FALSE; 4444 nameHashEQ = PR_FALSE;
4504 4445
4505 if (!ocsp_CertIsOCSPDesignatedResponder(signerCert)) { 4446 if (!ocsp_CertIsOCSPDesignatedResponder(signerCert)) {
4506 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE); 4447 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
4507 return PR_FALSE; 4448 return PR_FALSE;
4508 } 4449 }
4509 4450
4510 /* 4451 /*
4511 * The signer is a designated responder. Its issuer must match 4452 * The signer is a designated responder. Its issuer must match
(...skipping 10 matching lines...) Expand all
4522 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE); 4463 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE);
4523 return PR_FALSE; 4464 return PR_FALSE;
4524 } 4465 }
4525 4466
4526 keyHash = CERT_GetSubjectPublicKeyDigest(NULL, issuerCert, hashAlg, NULL); 4467 keyHash = CERT_GetSubjectPublicKeyDigest(NULL, issuerCert, hashAlg, NULL);
4527 nameHash = CERT_GetSubjectNameDigest(NULL, issuerCert, hashAlg, NULL); 4468 nameHash = CERT_GetSubjectNameDigest(NULL, issuerCert, hashAlg, NULL);
4528 4469
4529 CERT_DestroyCertificate(issuerCert); 4470 CERT_DestroyCertificate(issuerCert);
4530 4471
4531 if (keyHash != NULL && nameHash != NULL) { 4472 if (keyHash != NULL && nameHash != NULL) {
4532 keyHashEQ = 4473 keyHashEQ =
4533 (SECITEM_CompareItem(keyHash, 4474 (SECITEM_CompareItem(keyHash,
4534 &certID->issuerKeyHash) == SECEqual); 4475 &certID->issuerKeyHash) == SECEqual);
4535 4476
4536 nameHashEQ = 4477 nameHashEQ =
4537 (SECITEM_CompareItem(nameHash, 4478 (SECITEM_CompareItem(nameHash,
4538 &certID->issuerNameHash) == SECEqual); 4479 &certID->issuerNameHash) == SECEqual);
4539 } 4480 }
4540 4481
4541 if (keyHash) { 4482 if (keyHash) {
4542 SECITEM_FreeItem(keyHash, PR_TRUE); 4483 SECITEM_FreeItem(keyHash, PR_TRUE);
(...skipping 15 matching lines...) Expand all
4558 * Since a responder can pre-package responses, we need to pick an amount 4499 * Since a responder can pre-package responses, we need to pick an amount
4559 * of time that is acceptable to us, and reject any response that is 4500 * of time that is acceptable to us, and reject any response that is
4560 * older than that. 4501 * older than that.
4561 * 4502 *
4562 * XXX This *should* be based on some configuration parameter, so that 4503 * XXX This *should* be based on some configuration parameter, so that
4563 * different usages could specify exactly what constitutes "sufficiently 4504 * different usages could specify exactly what constitutes "sufficiently
4564 * recent". But that is not going to happen right away. For now, we 4505 * recent". But that is not going to happen right away. For now, we
4565 * want something from within the last 24 hours. This macro defines that 4506 * want something from within the last 24 hours. This macro defines that
4566 * number in seconds. 4507 * number in seconds.
4567 */ 4508 */
4568 #define OCSP_ALLOWABLE_LAPSE_SECONDS» (24L * 60L * 60L) 4509 #define OCSP_ALLOWABLE_LAPSE_SECONDS (24L * 60L * 60L)
4569 4510
4570 static PRBool 4511 static PRBool
4571 ocsp_TimeIsRecent(PRTime checkTime) 4512 ocsp_TimeIsRecent(PRTime checkTime)
4572 { 4513 {
4573 PRTime now = PR_Now(); 4514 PRTime now = PR_Now();
4574 PRTime lapse, tmp; 4515 PRTime lapse, tmp;
4575 4516
4576 LL_I2L(lapse, OCSP_ALLOWABLE_LAPSE_SECONDS); 4517 LL_I2L(lapse, OCSP_ALLOWABLE_LAPSE_SECONDS);
4577 LL_I2L(tmp, PR_USEC_PER_SEC); 4518 LL_I2L(tmp, PR_USEC_PER_SEC);
4578 LL_MUL(lapse, lapse, tmp);» » /* allowable lapse in microseconds */ 4519 LL_MUL(lapse, lapse, tmp); /* allowable lapse in microseconds */
4579 4520
4580 LL_ADD(checkTime, checkTime, lapse); 4521 LL_ADD(checkTime, checkTime, lapse);
4581 if (LL_CMP(now, >, checkTime)) 4522 if (LL_CMP(now, >, checkTime))
4582 » return PR_FALSE; 4523 return PR_FALSE;
4583 4524
4584 return PR_TRUE; 4525 return PR_TRUE;
4585 } 4526 }
4586 4527
4587 #define OCSP_SLOP (5L*60L) /* OCSP responses are allowed to be 5 minutes 4528 #define OCSP_SLOP (5L * 60L) /* OCSP responses are allowed to be 5 minutes \
4588 in the future by default */ 4529 in the future by default */
4589 4530
4590 static PRUint32 ocspsloptime = OCSP_SLOP;» /* seconds */ 4531 static PRUint32 ocspsloptime = OCSP_SLOP; /* seconds */
4591 4532
4592 /* 4533 /*
4593 * If an old response contains the revoked certificate status, we want 4534 * If an old response contains the revoked certificate status, we want
4594 * to return SECSuccess so the response will be used. 4535 * to return SECSuccess so the response will be used.
4595 */ 4536 */
4596 static SECStatus 4537 static SECStatus
4597 ocsp_HandleOldSingleResponse(CERTOCSPSingleResponse *single, PRTime time) 4538 ocsp_HandleOldSingleResponse(CERTOCSPSingleResponse *single, PRTime time)
4598 { 4539 {
4599 SECStatus rv; 4540 SECStatus rv;
4600 ocspCertStatus *status = single->certStatus; 4541 ocspCertStatus *status = single->certStatus;
4601 if (status->certStatusType == ocspCertStatus_revoked) { 4542 if (status->certStatusType == ocspCertStatus_revoked) {
4602 rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time); 4543 rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time);
4603 if (rv != SECSuccess && 4544 if (rv != SECSuccess &&
4604 PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE) { 4545 PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE) {
4605 /* 4546 /*
4606 * Return SECSuccess now. The subsequent ocsp_CertRevokedAfter 4547 * Return SECSuccess now. The subsequent ocsp_CertRevokedAfter
4607 * call in ocsp_CertHasGoodStatus will cause 4548 * call in ocsp_CertHasGoodStatus will cause
4608 * ocsp_CertHasGoodStatus to fail with 4549 * ocsp_CertHasGoodStatus to fail with
4609 * SEC_ERROR_REVOKED_CERTIFICATE. 4550 * SEC_ERROR_REVOKED_CERTIFICATE.
4610 */ 4551 */
4611 return SECSuccess; 4552 return SECSuccess;
4612 } 4553 }
4613
4614 } 4554 }
4615 PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE); 4555 PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE);
4616 return SECFailure; 4556 return SECFailure;
4617 } 4557 }
4618 4558
4619 /* 4559 /*
4620 * Check that this single response is okay. A return of SECSuccess means: 4560 * Check that this single response is okay. A return of SECSuccess means:
4621 * 1. The signer (represented by "signerCert") is authorized to give status 4561 * 1. The signer (represented by "signerCert") is authorized to give status
4622 * for the cert represented by the individual response in "single". 4562 * for the cert represented by the individual response in "single".
4623 * 2. The value of thisUpdate is earlier than now. 4563 * 2. The value of thisUpdate is earlier than now.
4624 * 3. The value of producedAt is later than or the same as thisUpdate. 4564 * 3. The value of producedAt is later than or the same as thisUpdate.
4625 * 4. If nextUpdate is given: 4565 * 4. If nextUpdate is given:
4626 * - The value of nextUpdate is later than now. 4566 * - The value of nextUpdate is later than now.
4627 * - The value of producedAt is earlier than nextUpdate. 4567 * - The value of producedAt is earlier than nextUpdate.
4628 * Else if no nextUpdate: 4568 * Else if no nextUpdate:
4629 * - The value of thisUpdate is fairly recent. 4569 * - The value of thisUpdate is fairly recent.
4630 * - The value of producedAt is fairly recent. 4570 * - The value of producedAt is fairly recent.
4631 * However we do not need to perform an explicit check for this last 4571 * However we do not need to perform an explicit check for this last
4632 * constraint because it is already guaranteed by checking that 4572 * constraint because it is already guaranteed by checking that
4633 * producedAt is later than thisUpdate and thisUpdate is recent. 4573 * producedAt is later than thisUpdate and thisUpdate is recent.
4634 * Oh, and any responder is "authorized" to say that a cert is unknown to it. 4574 * Oh, and any responder is "authorized" to say that a cert is unknown to it.
4635 * 4575 *
4636 * If any of those checks fail, SECFailure is returned and an error is set: 4576 * If any of those checks fail, SECFailure is returned and an error is set:
4637 * SEC_ERROR_OCSP_FUTURE_RESPONSE 4577 * SEC_ERROR_OCSP_FUTURE_RESPONSE
4638 * SEC_ERROR_OCSP_OLD_RESPONSE 4578 * SEC_ERROR_OCSP_OLD_RESPONSE
4639 * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE 4579 * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
4640 * Other errors are low-level problems (no memory, bad database, etc.). 4580 * Other errors are low-level problems (no memory, bad database, etc.).
4641 */ 4581 */
4642 static SECStatus 4582 static SECStatus
4643 ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single, 4583 ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
4644 » » » CERTCertDBHandle *handle, 4584 CERTCertDBHandle *handle,
4645 » » » CERTCertificate *signerCert, 4585 CERTCertificate *signerCert,
4646 » » » PRTime producedAt) 4586 PRTime producedAt)
4647 { 4587 {
4648 CERTOCSPCertID *certID = single->certID; 4588 CERTOCSPCertID *certID = single->certID;
4649 PRTime now, thisUpdate, nextUpdate, tmstamp, tmp; 4589 PRTime now, thisUpdate, nextUpdate, tmstamp, tmp;
4650 SECStatus rv; 4590 SECStatus rv;
4651 4591
4652 OCSP_TRACE(("OCSP ocsp_VerifySingleResponse, nextUpdate: %d\n", 4592 OCSP_TRACE(("OCSP ocsp_VerifySingleResponse, nextUpdate: %d\n",
4653 ((single->nextUpdate) != 0))); 4593 ((single->nextUpdate) != 0)));
4654 /* 4594 /*
4655 * If all the responder said was that the given cert was unknown to it, 4595 * If all the responder said was that the given cert was unknown to it,
4656 * that is a valid response. Not very interesting to us, of course, 4596 * that is a valid response. Not very interesting to us, of course,
4657 * but all this function is concerned with is validity of the response, 4597 * but all this function is concerned with is validity of the response,
4658 * not the status of the cert. 4598 * not the status of the cert.
4659 */ 4599 */
4660 PORT_Assert(single->certStatus != NULL); 4600 PORT_Assert(single->certStatus != NULL);
4661 if (single->certStatus->certStatusType == ocspCertStatus_unknown) 4601 if (single->certStatus->certStatusType == ocspCertStatus_unknown)
4662 » return SECSuccess; 4602 return SECSuccess;
4663 4603
4664 /* 4604 /*
4665 * We need to extract "thisUpdate" for use below and to pass along 4605 * We need to extract "thisUpdate" for use below and to pass along
4666 * to AuthorizedResponderForCertID in case it needs it for doing an 4606 * to AuthorizedResponderForCertID in case it needs it for doing an
4667 * issuer look-up. 4607 * issuer look-up.
4668 */ 4608 */
4669 rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate); 4609 rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate);
4670 if (rv != SECSuccess) 4610 if (rv != SECSuccess)
4671 » return rv; 4611 return rv;
4672 4612
4673 /* 4613 /*
4674 * First confirm that signerCert is authorized to give this status. 4614 * First confirm that signerCert is authorized to give this status.
4675 */ 4615 */
4676 if (ocsp_AuthorizedResponderForCertID(handle, signerCert, certID, 4616 if (ocsp_AuthorizedResponderForCertID(handle, signerCert, certID,
4677 » » » » » thisUpdate) != PR_TRUE) 4617 thisUpdate) != PR_TRUE)
4678 » return SECFailure; 4618 return SECFailure;
4679 4619
4680 /* 4620 /*
4681 * Now check the time stuff, as described above. 4621 * Now check the time stuff, as described above.
4682 */ 4622 */
4683 now = PR_Now(); 4623 now = PR_Now();
4684 /* allow slop time for future response */ 4624 /* allow slop time for future response */
4685 LL_UI2L(tmstamp, ocspsloptime); /* get slop time in seconds */ 4625 LL_UI2L(tmstamp, ocspsloptime); /* get slop time in seconds */
4686 LL_UI2L(tmp, PR_USEC_PER_SEC); 4626 LL_UI2L(tmp, PR_USEC_PER_SEC);
4687 LL_MUL(tmp, tmstamp, tmp); /* convert the slop time to PRTime */ 4627 LL_MUL(tmp, tmstamp, tmp); /* convert the slop time to PRTime */
4688 LL_ADD(tmstamp, tmp, now); /* add current time to it */ 4628 LL_ADD(tmstamp, tmp, now); /* add current time to it */
4689 4629
4690 if (LL_CMP(thisUpdate, >, tmstamp) || LL_CMP(producedAt, <, thisUpdate)) { 4630 if (LL_CMP(thisUpdate, >, tmstamp) || LL_CMP(producedAt, <, thisUpdate)) {
4691 » PORT_SetError(SEC_ERROR_OCSP_FUTURE_RESPONSE); 4631 PORT_SetError(SEC_ERROR_OCSP_FUTURE_RESPONSE);
4692 » return SECFailure; 4632 return SECFailure;
4693 } 4633 }
4694 if (single->nextUpdate != NULL) { 4634 if (single->nextUpdate != NULL) {
4695 » rv = DER_GeneralizedTimeToTime(&nextUpdate, single->nextUpdate); 4635 rv = DER_GeneralizedTimeToTime(&nextUpdate, single->nextUpdate);
4696 » if (rv != SECSuccess) 4636 if (rv != SECSuccess)
4697 » return rv; 4637 return rv;
4698 4638
4699 » LL_ADD(tmp, tmp, nextUpdate); 4639 LL_ADD(tmp, tmp, nextUpdate);
4700 » if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate)) 4640 if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate))
4701 » return ocsp_HandleOldSingleResponse(single, now); 4641 return ocsp_HandleOldSingleResponse(single, now);
4702 } else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) { 4642 } else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) {
4703 » return ocsp_HandleOldSingleResponse(single, now); 4643 return ocsp_HandleOldSingleResponse(single, now);
4704 } 4644 }
4705 4645
4706 return SECSuccess; 4646 return SECSuccess;
4707 } 4647 }
4708 4648
4709
4710 /* 4649 /*
4711 * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation 4650 * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
4712 * Get the value of the URI of the OCSP responder for the given cert. 4651 * Get the value of the URI of the OCSP responder for the given cert.
4713 * This is found in the (optional) Authority Information Access extension 4652 * This is found in the (optional) Authority Information Access extension
4714 * in the cert. 4653 * in the cert.
4715 * INPUTS: 4654 * INPUTS:
4716 * CERTCertificate *cert 4655 * CERTCertificate *cert
4717 * The certificate being examined. 4656 * The certificate being examined.
4718 * RETURN: 4657 * RETURN:
4719 * char * 4658 * char *
4720 * A copy of the URI for the OCSP method, if found. If either the 4659 * A copy of the URI for the OCSP method, if found. If either the
4721 * extension is not present or it does not contain an entry for OCSP, 4660 * extension is not present or it does not contain an entry for OCSP,
4722 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION will be set and a NULL returned. 4661 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION will be set and a NULL returned.
4723 * Any other error will also result in a NULL being returned. 4662 * Any other error will also result in a NULL being returned.
4724 * 4663 *
4725 * This result should be freed (via PORT_Free) when no longer in use. 4664 * This result should be freed (via PORT_Free) when no longer in use.
4726 */ 4665 */
4727 char * 4666 char *
4728 CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert) 4667 CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert)
4729 { 4668 {
4730 CERTGeneralName *locname = NULL; 4669 CERTGeneralName *locname = NULL;
4731 SECItem *location = NULL; 4670 SECItem *location = NULL;
4732 SECItem *encodedAuthInfoAccess = NULL; 4671 SECItem *encodedAuthInfoAccess = NULL;
4733 CERTAuthInfoAccess **authInfoAccess = NULL; 4672 CERTAuthInfoAccess **authInfoAccess = NULL;
4734 char *locURI = NULL; 4673 char *locURI = NULL;
4735 PLArenaPool *arena = NULL; 4674 PLArenaPool *arena = NULL;
4736 SECStatus rv; 4675 SECStatus rv;
4737 int i; 4676 int i;
4738 4677
4739 /* 4678 /*
4740 * Allocate this one from the heap because it will get filled in 4679 * Allocate this one from the heap because it will get filled in
4741 * by CERT_FindCertExtension which will also allocate from the heap, 4680 * by CERT_FindCertExtension which will also allocate from the heap,
4742 * and we can free the entire thing on our way out. 4681 * and we can free the entire thing on our way out.
4743 */ 4682 */
4744 encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0); 4683 encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0);
4745 if (encodedAuthInfoAccess == NULL) 4684 if (encodedAuthInfoAccess == NULL)
4746 » goto loser; 4685 goto loser;
4747 4686
4748 rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS, 4687 rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS,
4749 » » » » encodedAuthInfoAccess); 4688 encodedAuthInfoAccess);
4750 if (rv == SECFailure) { 4689 if (rv == SECFailure) {
4751 » PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); 4690 PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
4752 » goto loser; 4691 goto loser;
4753 } 4692 }
4754 4693
4755 /* 4694 /*
4756 * The rest of the things allocated in the routine will come out of 4695 * The rest of the things allocated in the routine will come out of
4757 * this arena, which is temporary just for us to decode and get at the 4696 * this arena, which is temporary just for us to decode and get at the
4758 * AIA extension. The whole thing will be destroyed on our way out, 4697 * AIA extension. The whole thing will be destroyed on our way out,
4759 * after we have copied the location string (url) itself (if found). 4698 * after we have copied the location string (url) itself (if found).
4760 */ 4699 */
4761 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 4700 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
4762 if (arena == NULL) 4701 if (arena == NULL)
4763 » goto loser; 4702 goto loser;
4764 4703
4765 authInfoAccess = CERT_DecodeAuthInfoAccessExtension(arena, 4704 authInfoAccess = CERT_DecodeAuthInfoAccessExtension(arena,
4766 » » » » » » » encodedAuthInfoAccess); 4705 encodedAuthInfoAccess);
4767 if (authInfoAccess == NULL) 4706 if (authInfoAccess == NULL)
4768 » goto loser; 4707 goto loser;
4769 4708
4770 for (i = 0; authInfoAccess[i] != NULL; i++) { 4709 for (i = 0; authInfoAccess[i] != NULL; i++) {
4771 » if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == SEC_OID_PKIX_OCSP) 4710 if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == SEC_OID_PKIX_OCSP)
4772 » locname = authInfoAccess[i]->location; 4711 locname = authInfoAccess[i]->location;
4773 } 4712 }
4774 4713
4775 /* 4714 /*
4776 * If we found an AIA extension, but it did not include an OCSP method, 4715 * If we found an AIA extension, but it did not include an OCSP method,
4777 * that should look to our caller as if we did not find the extension 4716 * that should look to our caller as if we did not find the extension
4778 * at all, because it is only an OCSP method that we care about. 4717 * at all, because it is only an OCSP method that we care about.
4779 * So set the same error that would be set if the AIA extension was 4718 * So set the same error that would be set if the AIA extension was
4780 * not there at all. 4719 * not there at all.
4781 */ 4720 */
4782 if (locname == NULL) { 4721 if (locname == NULL) {
4783 » PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); 4722 PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
4784 » goto loser; 4723 goto loser;
4785 } 4724 }
4786 4725
4787 /* 4726 /*
4788 * The following is just a pointer back into locname (i.e. not a copy); 4727 * The following is just a pointer back into locname (i.e. not a copy);
4789 * thus it should not be freed. 4728 * thus it should not be freed.
4790 */ 4729 */
4791 location = CERT_GetGeneralNameByType(locname, certURI, PR_FALSE); 4730 location = CERT_GetGeneralNameByType(locname, certURI, PR_FALSE);
4792 if (location == NULL) { 4731 if (location == NULL) {
4793 » /* 4732 /*
4794 » * XXX Appears that CERT_GetGeneralNameByType does not set an 4733 » * XXX Appears that CERT_GetGeneralNameByType does not set an
4795 » * error if there is no name by that type. For lack of anything 4734 » * error if there is no name by that type. For lack of anything
4796 » * better, act as if the extension was not found. In the future 4735 » * better, act as if the extension was not found. In the future
4797 » * this should probably be something more like the extension was 4736 » * this should probably be something more like the extension was
4798 » * badly formed. 4737 » * badly formed.
4799 » */ 4738 » */
4800 » PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); 4739 PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION);
4801 » goto loser; 4740 goto loser;
4802 } 4741 }
4803 4742
4804 /* 4743 /*
4805 * That location is really a string, but it has a specified length 4744 * That location is really a string, but it has a specified length
4806 * without a null-terminator. We need a real string that does have 4745 * without a null-terminator. We need a real string that does have
4807 * a null-terminator, and we need a copy of it anyway to return to 4746 * a null-terminator, and we need a copy of it anyway to return to
4808 * our caller -- so allocate and copy. 4747 * our caller -- so allocate and copy.
4809 */ 4748 */
4810 locURI = PORT_Alloc(location->len + 1); 4749 locURI = PORT_Alloc(location->len + 1);
4811 if (locURI == NULL) { 4750 if (locURI == NULL) {
4812 » goto loser; 4751 goto loser;
4813 } 4752 }
4814 PORT_Memcpy(locURI, location->data, location->len); 4753 PORT_Memcpy(locURI, location->data, location->len);
4815 locURI[location->len] = '\0'; 4754 locURI[location->len] = '\0';
4816 4755
4817 loser: 4756 loser:
4818 if (arena != NULL) 4757 if (arena != NULL)
4819 » PORT_FreeArena(arena, PR_FALSE); 4758 PORT_FreeArena(arena, PR_FALSE);
4820 4759
4821 if (encodedAuthInfoAccess != NULL) 4760 if (encodedAuthInfoAccess != NULL)
4822 » SECITEM_FreeItem(encodedAuthInfoAccess, PR_TRUE); 4761 SECITEM_FreeItem(encodedAuthInfoAccess, PR_TRUE);
4823 4762
4824 return locURI; 4763 return locURI;
4825 } 4764 }
4826 4765
4827
4828 /* 4766 /*
4829 * Figure out where we should go to find out the status of the given cert 4767 * Figure out where we should go to find out the status of the given cert
4830 * via OCSP. If allowed to use a default responder uri and a default 4768 * via OCSP. If allowed to use a default responder uri and a default
4831 * responder is set up, then that is our answer. 4769 * responder is set up, then that is our answer.
4832 * If not, see if the certificate has an Authority Information Access (AIA) 4770 * If not, see if the certificate has an Authority Information Access (AIA)
4833 * extension for OCSP, and return the value of that. Otherwise return NULL. 4771 * extension for OCSP, and return the value of that. Otherwise return NULL.
4834 * We also let our caller know whether or not the responder chosen was 4772 * We also let our caller know whether or not the responder chosen was
4835 * a default responder or not through the output variable isDefault; 4773 * a default responder or not through the output variable isDefault;
4836 * its value has no meaning unless a good (non-null) value is returned 4774 * its value has no meaning unless a good (non-null) value is returned
4837 * for the location. 4775 * for the location.
4838 * 4776 *
4839 * The result needs to be freed (PORT_Free) when no longer in use. 4777 * The result needs to be freed (PORT_Free) when no longer in use.
4840 */ 4778 */
4841 char * 4779 char *
4842 ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert, 4780 ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
4843 » » » PRBool canUseDefault, PRBool *isDefault) 4781 PRBool canUseDefault, PRBool *isDefault)
4844 { 4782 {
4845 ocspCheckingContext *ocspcx = NULL; 4783 ocspCheckingContext *ocspcx = NULL;
4846 char *ocspUrl = NULL; 4784 char *ocspUrl = NULL;
4847 4785
4848 if (canUseDefault) { 4786 if (canUseDefault) {
4849 ocspcx = ocsp_GetCheckingContext(handle); 4787 ocspcx = ocsp_GetCheckingContext(handle);
4850 } 4788 }
4851 if (ocspcx != NULL && ocspcx->useDefaultResponder) { 4789 if (ocspcx != NULL && ocspcx->useDefaultResponder) {
4852 » /* 4790 /*
4853 » * A default responder wins out, if specified. 4791 » * A default responder wins out, if specified.
4854 » * XXX Someday this may be a more complicated determination based 4792 » * XXX Someday this may be a more complicated determination based
4855 » * on the cert's issuer. (That is, we could have different default 4793 » * on the cert's issuer. (That is, we could have different default
4856 » * responders configured for different issuers.) 4794 » * responders configured for different issuers.)
4857 » */ 4795 » */
4858 » PORT_Assert(ocspcx->defaultResponderURI != NULL); 4796 PORT_Assert(ocspcx->defaultResponderURI != NULL);
4859 » *isDefault = PR_TRUE; 4797 *isDefault = PR_TRUE;
4860 » return (PORT_Strdup(ocspcx->defaultResponderURI)); 4798 return (PORT_Strdup(ocspcx->defaultResponderURI));
4861 } 4799 }
4862 4800
4863 /* 4801 /*
4864 * No default responder set up, so go see if we can find an AIA 4802 * No default responder set up, so go see if we can find an AIA
4865 * extension that has a value for OCSP, and get the url from that. 4803 * extension that has a value for OCSP, and get the url from that.
4866 */ 4804 */
4867 *isDefault = PR_FALSE; 4805 *isDefault = PR_FALSE;
4868 ocspUrl = CERT_GetOCSPAuthorityInfoAccessLocation(cert); 4806 ocspUrl = CERT_GetOCSPAuthorityInfoAccessLocation(cert);
4869 if (!ocspUrl) { 4807 if (!ocspUrl) {
4870 » CERT_StringFromCertFcn altFcn; 4808 CERT_StringFromCertFcn altFcn;
4871 4809
4872 » PR_EnterMonitor(OCSP_Global.monitor); 4810 PR_EnterMonitor(OCSP_Global.monitor);
4873 » altFcn = OCSP_Global.alternateOCSPAIAFcn; 4811 altFcn = OCSP_Global.alternateOCSPAIAFcn;
4874 » PR_ExitMonitor(OCSP_Global.monitor); 4812 PR_ExitMonitor(OCSP_Global.monitor);
4875 » if (altFcn) { 4813 if (altFcn) {
4876 » ocspUrl = (*altFcn)(cert); 4814 ocspUrl = (*altFcn)(cert);
4877 » if (ocspUrl) 4815 if (ocspUrl)
4878 » » *isDefault = PR_TRUE; 4816 *isDefault = PR_TRUE;
4879 » } 4817 }
4880 } 4818 }
4881 return ocspUrl; 4819 return ocspUrl;
4882 } 4820 }
4883 4821
4884 /* 4822 /*
4885 * Return SECSuccess if the cert was revoked *after* "time", 4823 * Return SECSuccess if the cert was revoked *after* "time",
4886 * SECFailure otherwise. 4824 * SECFailure otherwise.
4887 */ 4825 */
4888 static SECStatus 4826 static SECStatus
4889 ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time) 4827 ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, PRTime time)
4890 { 4828 {
4891 PRTime revokedTime; 4829 PRTime revokedTime;
4892 SECStatus rv; 4830 SECStatus rv;
4893 4831
4894 rv = DER_GeneralizedTimeToTime(&revokedTime, &revokedInfo->revocationTime); 4832 rv = DER_GeneralizedTimeToTime(&revokedTime, &revokedInfo->revocationTime);
4895 if (rv != SECSuccess) 4833 if (rv != SECSuccess)
4896 » return rv; 4834 return rv;
4897 4835
4898 /* 4836 /*
4899 * Set the error even if we will return success; someone might care. 4837 * Set the error even if we will return success; someone might care.
4900 */ 4838 */
4901 PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); 4839 PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
4902 4840
4903 if (LL_CMP(revokedTime, >, time)) 4841 if (LL_CMP(revokedTime, >, time))
4904 » return SECSuccess; 4842 return SECSuccess;
4905 4843
4906 return SECFailure; 4844 return SECFailure;
4907 } 4845 }
4908 4846
4909 /* 4847 /*
4910 * See if the cert represented in the single response had a good status 4848 * See if the cert represented in the single response had a good status
4911 * at the specified time. 4849 * at the specified time.
4912 */ 4850 */
4913 SECStatus 4851 SECStatus
4914 ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time) 4852 ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time)
4915 { 4853 {
4916 SECStatus rv; 4854 SECStatus rv;
4917 switch (status->certStatusType) { 4855 switch (status->certStatusType) {
4918 case ocspCertStatus_good: 4856 case ocspCertStatus_good:
4919 rv = SECSuccess; 4857 rv = SECSuccess;
4920 break; 4858 break;
4921 case ocspCertStatus_revoked: 4859 case ocspCertStatus_revoked:
4922 rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time); 4860 rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time) ;
4923 break; 4861 break;
4924 case ocspCertStatus_unknown: 4862 case ocspCertStatus_unknown:
4925 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT); 4863 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT);
4926 rv = SECFailure; 4864 rv = SECFailure;
4927 break; 4865 break;
4928 case ocspCertStatus_other: 4866 case ocspCertStatus_other:
4929 default: 4867 default:
4930 PORT_Assert(0); 4868 PORT_Assert(0);
4931 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); 4869 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
4932 rv = SECFailure; 4870 rv = SECFailure;
4933 break; 4871 break;
4934 } 4872 }
4935 return rv; 4873 return rv;
4936 } 4874 }
4937 4875
4938 static SECStatus 4876 static SECStatus
4939 ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single, 4877 ocsp_SingleResponseCertHasGoodStatus(CERTOCSPSingleResponse *single,
4940 PRTime time) 4878 PRTime time)
4941 { 4879 {
4942 return ocsp_CertHasGoodStatus(single->certStatus, time); 4880 return ocsp_CertHasGoodStatus(single->certStatus, time);
4943 } 4881 }
4944 4882
4945 /* SECFailure means the arguments were invalid. 4883 /* SECFailure means the arguments were invalid.
4946 * On SECSuccess, the out parameters contain the OCSP status. 4884 * On SECSuccess, the out parameters contain the OCSP status.
4947 * rvOcsp contains the overall result of the OCSP operation. 4885 * rvOcsp contains the overall result of the OCSP operation.
4948 * Depending on input parameter ignoreGlobalOcspFailureSetting, 4886 * Depending on input parameter ignoreGlobalOcspFailureSetting,
4949 * a soft failure might be converted into *rvOcsp=SECSuccess. 4887 * a soft failure might be converted into *rvOcsp=SECSuccess.
4950 * If the cached attempt to obtain OCSP information had resulted 4888 * If the cached attempt to obtain OCSP information had resulted
4951 * in a failure, missingResponseError shows the error code of 4889 * in a failure, missingResponseError shows the error code of
4952 * that failure. 4890 * that failure.
4953 * cacheFreshness is ocspMissing if no entry was found, 4891 * cacheFreshness is ocspMissing if no entry was found,
4954 * ocspFresh if a fresh entry was found, or 4892 * ocspFresh if a fresh entry was found, or
4955 * ocspStale if a stale entry was found. 4893 * ocspStale if a stale entry was found.
4956 */ 4894 */
4957 SECStatus 4895 SECStatus
4958 ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID, 4896 ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
4959 PRTime time, 4897 PRTime time,
4960 PRBool ignoreGlobalOcspFailureSetting, 4898 PRBool ignoreGlobalOcspFailureSetting,
4961 SECStatus *rvOcsp, 4899 SECStatus *rvOcsp,
4962 SECErrorCodes *missingResponseError, 4900 SECErrorCodes *missingResponseError,
4963 OCSPFreshness *cacheFreshness) 4901 OCSPFreshness *cacheFreshness)
4964 { 4902 {
4965 OCSPCacheItem *cacheItem = NULL; 4903 OCSPCacheItem *cacheItem = NULL;
4966 4904
4967 if (!certID || !missingResponseError || !rvOcsp || !cacheFreshness) { 4905 if (!certID || !missingResponseError || !rvOcsp || !cacheFreshness) {
4968 PORT_SetError(SEC_ERROR_INVALID_ARGS); 4906 PORT_SetError(SEC_ERROR_INVALID_ARGS);
4969 return SECFailure; 4907 return SECFailure;
4970 } 4908 }
4971 *rvOcsp = SECFailure; 4909 *rvOcsp = SECFailure;
4972 *missingResponseError = 0; 4910 *missingResponseError = 0;
4973 *cacheFreshness = ocspMissing; 4911 *cacheFreshness = ocspMissing;
4974 4912
4975 PR_EnterMonitor(OCSP_Global.monitor); 4913 PR_EnterMonitor(OCSP_Global.monitor);
4976 cacheItem = ocsp_FindCacheEntry(&OCSP_Global.cache, certID); 4914 cacheItem = ocsp_FindCacheEntry(&OCSP_Global.cache, certID);
4977 if (cacheItem) { 4915 if (cacheItem) {
4978 *cacheFreshness = ocsp_IsCacheItemFresh(cacheItem) ? ocspFresh 4916 *cacheFreshness = ocsp_IsCacheItemFresh(cacheItem) ? ocspFresh
4979 : ocspStale; 4917 : ocspStale;
4980 /* having an arena means, we have a cached certStatus */ 4918 /* having an arena means, we have a cached certStatus */
4981 if (cacheItem->certStatusArena) { 4919 if (cacheItem->certStatusArena) {
4982 *rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time); 4920 *rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time);
4983 if (*rvOcsp != SECSuccess) { 4921 if (*rvOcsp != SECSuccess) {
4984 *missingResponseError = PORT_GetError(); 4922 *missingResponseError = PORT_GetError();
4985 } 4923 }
4986 } else { 4924 } else {
4987 /* 4925 /*
4988 * No status cached, the previous attempt failed. 4926 * No status cached, the previous attempt failed.
4989 * If OCSP is required, we never decide based on a failed attempt 4927 * If OCSP is required, we never decide based on a failed attempt
4990 * However, if OCSP is optional, a recent OCSP failure is 4928 * However, if OCSP is optional, a recent OCSP failure is
4991 * an allowed good state. 4929 * an allowed good state.
4992 */ 4930 */
4993 if (*cacheFreshness == ocspFresh && 4931 if (*cacheFreshness == ocspFresh &&
4994 !ignoreGlobalOcspFailureSetting && 4932 !ignoreGlobalOcspFailureSetting &&
4995 OCSP_Global.ocspFailureMode == 4933 OCSP_Global.ocspFailureMode ==
4996 ocspMode_FailureIsNotAVerificationFailure) { 4934 ocspMode_FailureIsNotAVerificationFailure) {
4997 *rvOcsp = SECSuccess; 4935 *rvOcsp = SECSuccess;
4998 } 4936 }
4999 *missingResponseError = cacheItem->missingResponseError; 4937 *missingResponseError = cacheItem->missingResponseError;
5000 } 4938 }
5001 } 4939 }
5002 PR_ExitMonitor(OCSP_Global.monitor); 4940 PR_ExitMonitor(OCSP_Global.monitor);
5003 return SECSuccess; 4941 return SECSuccess;
5004 } 4942 }
5005 4943
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
5057 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION 4995 * SEC_ERROR_CERT_BAD_ACCESS_LOCATION
5058 * SEC_ERROR_INVALID_TIME 4996 * SEC_ERROR_INVALID_TIME
5059 * SEC_ERROR_REVOKED_CERTIFICATE 4997 * SEC_ERROR_REVOKED_CERTIFICATE
5060 * SEC_ERROR_UNKNOWN_ISSUER 4998 * SEC_ERROR_UNKNOWN_ISSUER
5061 * SEC_ERROR_UNKNOWN_SIGNER 4999 * SEC_ERROR_UNKNOWN_SIGNER
5062 * 5000 *
5063 * Other errors are any of the many possible failures in cert verification 5001 * Other errors are any of the many possible failures in cert verification
5064 * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when 5002 * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
5065 * verifying the signer's cert, or low-level problems (error allocating 5003 * verifying the signer's cert, or low-level problems (error allocating
5066 * memory, error performing ASN.1 decoding, etc.). 5004 * memory, error performing ASN.1 decoding, etc.).
5067 */ 5005 */
5068 SECStatus 5006 SECStatus
5069 CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, 5007 CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
5070 » » PRTime time, void *pwArg) 5008 PRTime time, void *pwArg)
5071 { 5009 {
5072 CERTOCSPCertID *certID; 5010 CERTOCSPCertID *certID;
5073 PRBool certIDWasConsumed = PR_FALSE; 5011 PRBool certIDWasConsumed = PR_FALSE;
5074 SECStatus rv; 5012 SECStatus rv;
5075 SECStatus rvOcsp; 5013 SECStatus rvOcsp;
5076 SECErrorCodes cachedErrorCode; 5014 SECErrorCodes cachedErrorCode;
5077 OCSPFreshness cachedResponseFreshness; 5015 OCSPFreshness cachedResponseFreshness;
5078 5016
5079 OCSP_TRACE_CERT(cert); 5017 OCSP_TRACE_CERT(cert);
5080 OCSP_TRACE_TIME("## requested validity time:", time); 5018 OCSP_TRACE_TIME("## requested validity time:", time);
5081 5019
5082 certID = CERT_CreateOCSPCertID(cert, time); 5020 certID = CERT_CreateOCSPCertID(cert, time);
5083 if (!certID) 5021 if (!certID)
5084 return SECFailure; 5022 return SECFailure;
5085 rv = ocsp_GetCachedOCSPResponseStatus( 5023 rv = ocsp_GetCachedOCSPResponseStatus(
5086 certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */ 5024 certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
5087 &rvOcsp, &cachedErrorCode, &cachedResponseFreshness); 5025 &rvOcsp, &cachedErrorCode, &cachedResponseFreshness);
5088 if (rv != SECSuccess) { 5026 if (rv != SECSuccess) {
5089 CERT_DestroyOCSPCertID(certID); 5027 CERT_DestroyOCSPCertID(certID);
5090 return SECFailure; 5028 return SECFailure;
5091 } 5029 }
5092 if (cachedResponseFreshness == ocspFresh) { 5030 if (cachedResponseFreshness == ocspFresh) {
5093 CERT_DestroyOCSPCertID(certID); 5031 CERT_DestroyOCSPCertID(certID);
5094 if (rvOcsp != SECSuccess) { 5032 if (rvOcsp != SECSuccess) {
5095 PORT_SetError(cachedErrorCode); 5033 PORT_SetError(cachedErrorCode);
5096 } 5034 }
5097 return rvOcsp; 5035 return rvOcsp;
5098 } 5036 }
5099 5037
5100 rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg, 5038 rv = ocsp_GetOCSPStatusFromNetwork(handle, certID, cert, time, pwArg,
5101 &certIDWasConsumed, 5039 &certIDWasConsumed,
5102 &rvOcsp); 5040 &rvOcsp);
5103 if (rv != SECSuccess) { 5041 if (rv != SECSuccess) {
5104 PRErrorCode err = PORT_GetError(); 5042 PRErrorCode err = PORT_GetError();
5105 if (ocsp_FetchingFailureIsVerificationFailure()) { 5043 if (ocsp_FetchingFailureIsVerificationFailure()) {
5106 PORT_SetError(err); 5044 PORT_SetError(err);
5107 rvOcsp = SECFailure; 5045 rvOcsp = SECFailure;
5108 } else if (cachedResponseFreshness == ocspStale && 5046 } else if (cachedResponseFreshness == ocspStale &&
5109 (cachedErrorCode == SEC_ERROR_OCSP_UNKNOWN_CERT || 5047 (cachedErrorCode == SEC_ERROR_OCSP_UNKNOWN_CERT ||
5110 cachedErrorCode == SEC_ERROR_REVOKED_CERTIFICATE)) { 5048 cachedErrorCode == SEC_ERROR_REVOKED_CERTIFICATE)) {
5111 /* If we couldn't get a response for a certificate that the OCSP 5049 /* If we couldn't get a response for a certificate that the OCSP
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5150 * SECItem *encodedResponse 5088 * SECItem *encodedResponse
5151 * the DER encoded bytes of the OCSP response 5089 * the DER encoded bytes of the OCSP response
5152 * void *pwArg 5090 * void *pwArg
5153 * argument for password prompting, if needed 5091 * argument for password prompting, if needed
5154 * RETURN: 5092 * RETURN:
5155 * SECSuccess if the cert was found in the cache, or if the OCSP response was 5093 * SECSuccess if the cert was found in the cache, or if the OCSP response was
5156 * found to be valid and inserted into the cache. SECFailure otherwise. 5094 * found to be valid and inserted into the cache. SECFailure otherwise.
5157 */ 5095 */
5158 SECStatus 5096 SECStatus
5159 CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle, 5097 CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
5160 » » » » CERTCertificate *cert, 5098 CERTCertificate *cert,
5161 » » » » PRTime time, 5099 PRTime time,
5162 » » » » const SECItem *encodedResponse, 5100 const SECItem *encodedResponse,
5163 » » » » void *pwArg) 5101 void *pwArg)
5164 { 5102 {
5165 CERTOCSPCertID *certID = NULL; 5103 CERTOCSPCertID *certID = NULL;
5166 PRBool certIDWasConsumed = PR_FALSE; 5104 PRBool certIDWasConsumed = PR_FALSE;
5167 SECStatus rv = SECFailure; 5105 SECStatus rv = SECFailure;
5168 SECStatus rvOcsp = SECFailure; 5106 SECStatus rvOcsp = SECFailure;
5169 SECErrorCodes dummy_error_code; /* we ignore this */ 5107 SECErrorCodes dummy_error_code; /* we ignore this */
5170 CERTOCSPResponse *decodedResponse = NULL; 5108 CERTOCSPResponse *decodedResponse = NULL;
5171 CERTOCSPSingleResponse *singleResponse = NULL; 5109 CERTOCSPSingleResponse *singleResponse = NULL;
5172 OCSPFreshness freshness; 5110 OCSPFreshness freshness;
5173 5111
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
5228 /* The cached value is good. We don't want to waste time validating 5166 /* The cached value is good. We don't want to waste time validating
5229 * this OCSP response. This is the first column in the table above. */ 5167 * this OCSP response. This is the first column in the table above. */
5230 CERT_DestroyOCSPCertID(certID); 5168 CERT_DestroyOCSPCertID(certID);
5231 return rv; 5169 return rv;
5232 } 5170 }
5233 5171
5234 /* The logic for caching the more recent response is handled in 5172 /* The logic for caching the more recent response is handled in
5235 * ocsp_CacheSingleResponse. */ 5173 * ocsp_CacheSingleResponse. */
5236 5174
5237 rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert, 5175 rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert,
5238 » » » » » » time, pwArg, 5176 time, pwArg,
5239 » » » » » » encodedResponse, 5177 encodedResponse,
5240 » » » » » » &decodedResponse, 5178 &decodedResponse,
5241 » » » » » » &singleResponse); 5179 &singleResponse);
5242 if (rv == SECSuccess) { 5180 if (rv == SECSuccess) {
5243 » rvOcsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time); 5181 rvOcsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
5244 » /* Cache any valid singleResponse, regardless of status. */ 5182 /* Cache any valid singleResponse, regardless of status. */
5245 » ocsp_CacheSingleResponse(certID, singleResponse, &certIDWasConsumed); 5183 ocsp_CacheSingleResponse(certID, singleResponse, &certIDWasConsumed);
5246 } 5184 }
5247 if (decodedResponse) { 5185 if (decodedResponse) {
5248 » CERT_DestroyOCSPResponse(decodedResponse); 5186 CERT_DestroyOCSPResponse(decodedResponse);
5249 } 5187 }
5250 if (!certIDWasConsumed) { 5188 if (!certIDWasConsumed) {
5251 CERT_DestroyOCSPCertID(certID); 5189 CERT_DestroyOCSPCertID(certID);
5252 } 5190 }
5253 return rv == SECSuccess ? rvOcsp : rv; 5191 return rv == SECSuccess ? rvOcsp : rv;
5254 } 5192 }
5255 5193
5256 /* 5194 /*
5257 * Status in *certIDWasConsumed will always be correct, regardless of 5195 * Status in *certIDWasConsumed will always be correct, regardless of
5258 * return value. 5196 * return value.
5259 */ 5197 */
5260 static SECStatus 5198 static SECStatus
5261 ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, 5199 ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
5262 CERTOCSPCertID *certID, 5200 CERTOCSPCertID *certID,
5263 CERTCertificate *cert, 5201 CERTCertificate *cert,
5264 PRTime time, 5202 PRTime time,
5265 void *pwArg, 5203 void *pwArg,
5266 PRBool *certIDWasConsumed, 5204 PRBool *certIDWasConsumed,
5267 SECStatus *rv_ocsp) 5205 SECStatus *rv_ocsp)
5268 { 5206 {
5269 char *location = NULL; 5207 char *location = NULL;
5270 PRBool locationIsDefault; 5208 PRBool locationIsDefault;
5271 SECItem *encodedResponse = NULL; 5209 SECItem *encodedResponse = NULL;
5272 CERTOCSPRequest *request = NULL; 5210 CERTOCSPRequest *request = NULL;
5273 SECStatus rv = SECFailure; 5211 SECStatus rv = SECFailure;
5274 5212
5275 CERTOCSPResponse *decodedResponse = NULL; 5213 CERTOCSPResponse *decodedResponse = NULL;
5276 CERTOCSPSingleResponse *singleResponse = NULL; 5214 CERTOCSPSingleResponse *singleResponse = NULL;
5277 enum { stageGET, stagePOST } currentStage; 5215 enum { stageGET,
5216 stagePOST } currentStage;
5278 PRBool retry = PR_FALSE; 5217 PRBool retry = PR_FALSE;
5279 5218
5280 if (!certIDWasConsumed || !rv_ocsp) { 5219 if (!certIDWasConsumed || !rv_ocsp) {
5281 PORT_SetError(SEC_ERROR_INVALID_ARGS); 5220 PORT_SetError(SEC_ERROR_INVALID_ARGS);
5282 return SECFailure; 5221 return SECFailure;
5283 } 5222 }
5284 *certIDWasConsumed = PR_FALSE; 5223 *certIDWasConsumed = PR_FALSE;
5285 *rv_ocsp = SECFailure; 5224 *rv_ocsp = SECFailure;
5286 5225
5287 if (!OCSP_Global.monitor) { 5226 if (!OCSP_Global.monitor) {
(...skipping 15 matching lines...) Expand all
5303 * If we have no such location, then this cert does not "deserve" to 5242 * If we have no such location, then this cert does not "deserve" to
5304 * be checked -- that is, we consider it a success and just return. 5243 * be checked -- that is, we consider it a success and just return.
5305 * The way we tell that is by looking at the error number to see if 5244 * The way we tell that is by looking at the error number to see if
5306 * the problem was no AIA extension was found; any other error was 5245 * the problem was no AIA extension was found; any other error was
5307 * a true failure that we unfortunately have to treat as an overall 5246 * a true failure that we unfortunately have to treat as an overall
5308 * failure here. 5247 * failure here.
5309 */ 5248 */
5310 location = ocsp_GetResponderLocation(handle, cert, PR_TRUE, 5249 location = ocsp_GetResponderLocation(handle, cert, PR_TRUE,
5311 &locationIsDefault); 5250 &locationIsDefault);
5312 if (location == NULL) { 5251 if (location == NULL) {
5313 int err = PORT_GetError(); 5252 int err = PORT_GetError();
5314 if (err == SEC_ERROR_EXTENSION_NOT_FOUND || 5253 if (err == SEC_ERROR_EXTENSION_NOT_FOUND ||
5315 err == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) { 5254 err == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) {
5316 PORT_SetError(0); 5255 PORT_SetError(0);
5317 *rv_ocsp = SECSuccess; 5256 *rv_ocsp = SECSuccess;
5318 return SECSuccess; 5257 return SECSuccess;
5319 } 5258 }
5320 return SECFailure; 5259 return SECFailure;
5321 } 5260 }
5322 5261
5323 /* 5262 /*
5324 * XXX In the fullness of time, we will want/need to handle a 5263 * XXX In the fullness of time, we will want/need to handle a
5325 * certificate chain. This will be done either when a new parameter 5264 * certificate chain. This will be done either when a new parameter
5326 * tells us to, or some configuration variable tells us to. In any 5265 * tells us to, or some configuration variable tells us to. In any
5327 * case, handling it is complicated because we may need to send as 5266 * case, handling it is complicated because we may need to send as
5328 * many requests (and receive as many responses) as we have certs 5267 * many requests (and receive as many responses) as we have certs
5329 * in the chain. If we are going to talk to a default responder, 5268 * in the chain. If we are going to talk to a default responder,
5330 * and we only support one default responder, we can put all of the 5269 * and we only support one default responder, we can put all of the
5331 * certs together into one request. Otherwise, we must break them up 5270 * certs together into one request. Otherwise, we must break them up
5332 * into multiple requests. (Even if all of the requests will go to 5271 * into multiple requests. (Even if all of the requests will go to
5333 * the same location, the signature on each response will be different, 5272 * the same location, the signature on each response will be different,
5334 * because each issuer is different. Carefully read the OCSP spec 5273 * because each issuer is different. Carefully read the OCSP spec
5335 * if you do not understand this.) 5274 * if you do not understand this.)
5336 */ 5275 */
5337 5276
5338 /* 5277 /*
5339 * XXX If/when signing of requests is supported, that second NULL 5278 * XXX If/when signing of requests is supported, that second NULL
5340 * should be changed to be the signer certificate. Not sure if that 5279 * should be changed to be the signer certificate. Not sure if that
5341 * should be passed into this function or retrieved via some operation 5280 * should be passed into this function or retrieved via some operation
5342 * on the handle/context. 5281 * on the handle/context.
5343 */ 5282 */
5344 5283
5345 do { 5284 do {
5346 » const char *method; 5285 const char *method;
5347 » PRBool validResponseWithAccurateInfo = PR_FALSE; 5286 PRBool validResponseWithAccurateInfo = PR_FALSE;
5348 » retry = PR_FALSE; 5287 retry = PR_FALSE;
5349 » *rv_ocsp = SECFailure; 5288 *rv_ocsp = SECFailure;
5350 5289
5351 » if (currentStage == stageGET) { 5290 if (currentStage == stageGET) {
5352 » method = "GET"; 5291 method = "GET";
5353 » } else { 5292 } else {
5354 » PORT_Assert(currentStage == stagePOST); 5293 PORT_Assert(currentStage == stagePOST);
5355 » method = "POST"; 5294 method = "POST";
5356 » } 5295 }
5357 5296
5358 » encodedResponse = 5297 encodedResponse =
5359 » ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert, 5298 ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert,
5360 » » » » » » location, method, 5299 location, method,
5361 » » » » » » time, locationIsDefault, 5300 time, locationIsDefault,
5362 » » » » » » pwArg, &request); 5301 pwArg, &request);
5363 5302
5364 » if (encodedResponse) { 5303 if (encodedResponse) {
5365 » rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert , 5304 rv = ocsp_GetDecodedVerifiedSingleResponseForID(handle, certID, cert ,
5366 » » » » » » » time, pwArg, 5305 time, pwArg,
5367 » » » » » » » encodedResponse, 5306 encodedResponse,
5368 » » » » » » » &decodedResponse, 5307 &decodedResponse,
5369 » » » » » » » &singleResponse); 5308 &singleResponse);
5370 » if (rv == SECSuccess) { 5309 if (rv == SECSuccess) {
5371 » » switch (singleResponse->certStatus->certStatusType) { 5310 switch (singleResponse->certStatus->certStatusType) {
5372 » » case ocspCertStatus_good: 5311 case ocspCertStatus_good:
5373 » » case ocspCertStatus_revoked: 5312 case ocspCertStatus_revoked:
5374 » » » validResponseWithAccurateInfo = PR_TRUE; 5313 validResponseWithAccurateInfo = PR_TRUE;
5375 » » » break; 5314 break;
5376 » » default: 5315 default:
5377 » » » break; 5316 break;
5378 » » } 5317 }
5379 » » *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time); 5318 *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(singleResponse, time);
5380 » } 5319 }
5381 » } 5320 }
5382 5321
5383 » if (currentStage == stageGET) { 5322 if (currentStage == stageGET) {
5384 » /* only accept GET response if good or revoked */ 5323 /* only accept GET response if good or revoked */
5385 » if (validResponseWithAccurateInfo) { 5324 if (validResponseWithAccurateInfo) {
5386 » » ocsp_CacheSingleResponse(certID, singleResponse, 5325 ocsp_CacheSingleResponse(certID, singleResponse,
5387 » » » » » certIDWasConsumed); 5326 certIDWasConsumed);
5388 » } else { 5327 } else {
5389 » » retry = PR_TRUE; 5328 retry = PR_TRUE;
5390 » » currentStage = stagePOST; 5329 currentStage = stagePOST;
5391 » } 5330 }
5392 » } else { 5331 } else {
5393 » /* cache the POST respone, regardless of status */ 5332 /* cache the POST respone, regardless of status */
5394 » if (!singleResponse) { 5333 if (!singleResponse) {
5395 » » cert_RememberOCSPProcessingFailure(certID, certIDWasConsumed); 5334 cert_RememberOCSPProcessingFailure(certID, certIDWasConsumed);
5396 » } else { 5335 } else {
5397 » » ocsp_CacheSingleResponse(certID, singleResponse, 5336 ocsp_CacheSingleResponse(certID, singleResponse,
5398 » » » » » certIDWasConsumed); 5337 certIDWasConsumed);
5399 » } 5338 }
5400 » } 5339 }
5401 5340
5402 » if (encodedResponse) { 5341 if (encodedResponse) {
5403 » SECITEM_FreeItem(encodedResponse, PR_TRUE); 5342 SECITEM_FreeItem(encodedResponse, PR_TRUE);
5404 » encodedResponse = NULL; 5343 encodedResponse = NULL;
5405 » } 5344 }
5406 » if (request) { 5345 if (request) {
5407 » CERT_DestroyOCSPRequest(request); 5346 CERT_DestroyOCSPRequest(request);
5408 » request = NULL; 5347 request = NULL;
5409 » } 5348 }
5410 » if (decodedResponse) { 5349 if (decodedResponse) {
5411 » CERT_DestroyOCSPResponse(decodedResponse); 5350 CERT_DestroyOCSPResponse(decodedResponse);
5412 » decodedResponse = NULL; 5351 decodedResponse = NULL;
5413 » } 5352 }
5414 » singleResponse = NULL; 5353 singleResponse = NULL;
5415 5354
5416 } while (retry); 5355 } while (retry);
5417 5356
5418 PORT_Free(location); 5357 PORT_Free(location);
5419 return rv; 5358 return rv;
5420 } 5359 }
5421 5360
5422 /* 5361 /*
5423 * FUNCTION: ocsp_GetDecodedVerifiedSingleResponseForID 5362 * FUNCTION: ocsp_GetDecodedVerifiedSingleResponseForID
5424 * This function decodes an OCSP response and checks for a valid response 5363 * This function decodes an OCSP response and checks for a valid response
(...skipping 22 matching lines...) Expand all
5447 * and if it's non-null, must destroy it using CERT_DestroyOCSPResponse. 5386 * and if it's non-null, must destroy it using CERT_DestroyOCSPResponse.
5448 * CERTOCSPSingleResponse **pSingle 5387 * CERTOCSPSingleResponse **pSingle
5449 * (output) on success, this points to the single response that corresponds 5388 * (output) on success, this points to the single response that corresponds
5450 * to the certID parameter. Points to the inside of pDecodedResponse. 5389 * to the certID parameter. Points to the inside of pDecodedResponse.
5451 * It isn't a copy, don't free it. 5390 * It isn't a copy, don't free it.
5452 * RETURN: 5391 * RETURN:
5453 * SECSuccess iff the response is valid. 5392 * SECSuccess iff the response is valid.
5454 */ 5393 */
5455 static SECStatus 5394 static SECStatus
5456 ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle, 5395 ocsp_GetDecodedVerifiedSingleResponseForID(CERTCertDBHandle *handle,
5457 » » » » » CERTOCSPCertID *certID, 5396 CERTOCSPCertID *certID,
5458 » » » » » CERTCertificate *cert, 5397 CERTCertificate *cert,
5459 » » » » » PRTime time, 5398 PRTime time,
5460 » » » » » void *pwArg, 5399 void *pwArg,
5461 » » » » » const SECItem *encodedResponse, 5400 const SECItem *encodedResponse,
5462 » » » » » CERTOCSPResponse **pDecodedResponse, 5401 CERTOCSPResponse **pDecodedResponse,
5463 » » » » » CERTOCSPSingleResponse **pSingle) 5402 CERTOCSPSingleResponse **pSingle)
5464 { 5403 {
5465 CERTCertificate *signerCert = NULL; 5404 CERTCertificate *signerCert = NULL;
5466 CERTCertificate *issuerCert = NULL; 5405 CERTCertificate *issuerCert = NULL;
5467 SECStatus rv = SECFailure; 5406 SECStatus rv = SECFailure;
5468 5407
5469 if (!pSingle || !pDecodedResponse) { 5408 if (!pSingle || !pDecodedResponse) {
5470 » return SECFailure; 5409 return SECFailure;
5471 } 5410 }
5472 *pSingle = NULL; 5411 *pSingle = NULL;
5473 *pDecodedResponse = CERT_DecodeOCSPResponse(encodedResponse); 5412 *pDecodedResponse = CERT_DecodeOCSPResponse(encodedResponse);
5474 if (!*pDecodedResponse) { 5413 if (!*pDecodedResponse) {
5475 » return SECFailure; 5414 return SECFailure;
5476 } 5415 }
5477 5416
5478 /* 5417 /*
5479 * Okay, we at least have a response that *looks* like a response! 5418 * Okay, we at least have a response that *looks* like a response!
5480 * Now see if the overall response status value is good or not. 5419 * Now see if the overall response status value is good or not.
5481 * If not, we set an error and give up. (It means that either the 5420 * If not, we set an error and give up. (It means that either the
5482 * server had a problem, or it didn't like something about our 5421 * server had a problem, or it didn't like something about our
5483 * request. Either way there is nothing to do but give up.) 5422 * request. Either way there is nothing to do but give up.)
5484 * Otherwise, we continue to find the actual per-cert status 5423 * Otherwise, we continue to find the actual per-cert status
5485 * in the response. 5424 * in the response.
5486 */ 5425 */
5487 if (CERT_GetOCSPResponseStatus(*pDecodedResponse) != SECSuccess) { 5426 if (CERT_GetOCSPResponseStatus(*pDecodedResponse) != SECSuccess) {
5488 » goto loser; 5427 goto loser;
5489 } 5428 }
5490 5429
5491 /* 5430 /*
5492 * If we've made it this far, we expect a response with a good signature. 5431 * If we've made it this far, we expect a response with a good signature.
5493 * So, check for that. 5432 * So, check for that.
5494 */ 5433 */
5495 issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA); 5434 issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
5496 rv = CERT_VerifyOCSPResponseSignature(*pDecodedResponse, handle, pwArg, 5435 rv = CERT_VerifyOCSPResponseSignature(*pDecodedResponse, handle, pwArg,
5497 &signerCert, issuerCert); 5436 &signerCert, issuerCert);
5498 if (rv != SECSuccess) { 5437 if (rv != SECSuccess) {
5499 » goto loser; 5438 goto loser;
5500 } 5439 }
5501 5440
5502 PORT_Assert(signerCert != NULL);» /* internal consistency check */ 5441 PORT_Assert(signerCert != NULL); /* internal consistency check */
5503 /* XXX probably should set error, return failure if signerCert is null */ 5442 /* XXX probably should set error, return failure if signerCert is null */
5504 5443
5505 /* 5444 /*
5506 * Again, we are only doing one request for one cert. 5445 * Again, we are only doing one request for one cert.
5507 * XXX When we handle cert chains, the following code will obviously 5446 * XXX When we handle cert chains, the following code will obviously
5508 * have to be modified, in coordation with the code above that will 5447 * have to be modified, in coordation with the code above that will
5509 * have to determine how to make multiple requests, etc. 5448 * have to determine how to make multiple requests, etc.
5510 */ 5449 */
5511 rv = ocsp_GetVerifiedSingleResponseForCertID(handle, *pDecodedResponse, cert ID, 5450 rv = ocsp_GetVerifiedSingleResponseForCertID(handle, *pDecodedResponse, cert ID,
5512 signerCert, time, pSingle); 5451 signerCert, time, pSingle);
5513 loser: 5452 loser:
5514 if (issuerCert != NULL) 5453 if (issuerCert != NULL)
5515 » CERT_DestroyCertificate(issuerCert); 5454 CERT_DestroyCertificate(issuerCert);
5516 if (signerCert != NULL) 5455 if (signerCert != NULL)
5517 » CERT_DestroyCertificate(signerCert); 5456 CERT_DestroyCertificate(signerCert);
5518 return rv; 5457 return rv;
5519 } 5458 }
5520 5459
5521 /* 5460 /*
5522 * FUNCTION: ocsp_CacheSingleResponse 5461 * FUNCTION: ocsp_CacheSingleResponse
5523 * This function requires that the caller has checked that the response 5462 * This function requires that the caller has checked that the response
5524 * is valid and verified. 5463 * is valid and verified.
5525 * The (positive or negative) valid response will be used to update the cache. 5464 * The (positive or negative) valid response will be used to update the cache.
5526 * INPUTS: 5465 * INPUTS:
5527 * CERTOCSPCertID *certID 5466 * CERTOCSPCertID *certID
5528 * the cert ID corresponding to |cert| 5467 * the cert ID corresponding to |cert|
5529 * PRBool *certIDWasConsumed 5468 * PRBool *certIDWasConsumed
5530 * (output) on return, this is true iff |certID| was consumed by this 5469 * (output) on return, this is true iff |certID| was consumed by this
5531 * function. 5470 * function.
5532 */ 5471 */
5533 void 5472 void
5534 ocsp_CacheSingleResponse(CERTOCSPCertID *certID, 5473 ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
5535 » » » CERTOCSPSingleResponse *single, 5474 CERTOCSPSingleResponse *single,
5536 » » » PRBool *certIDWasConsumed) 5475 PRBool *certIDWasConsumed)
5537 { 5476 {
5538 if (single != NULL) { 5477 if (single != NULL) {
5539 » PR_EnterMonitor(OCSP_Global.monitor); 5478 PR_EnterMonitor(OCSP_Global.monitor);
5540 » if (OCSP_Global.maxCacheEntries >= 0) { 5479 if (OCSP_Global.maxCacheEntries >= 0) {
5541 » ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single, 5480 ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
5542 » » » » » certIDWasConsumed); 5481 certIDWasConsumed);
5543 » /* ignore cache update failures */ 5482 /* ignore cache update failures */
5544 » } 5483 }
5545 » PR_ExitMonitor(OCSP_Global.monitor); 5484 PR_ExitMonitor(OCSP_Global.monitor);
5546 } 5485 }
5547 } 5486 }
5548 5487
5549 SECStatus 5488 SECStatus
5550 ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle, 5489 ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
5551 CERTOCSPResponse *response, 5490 CERTOCSPResponse *response,
5552 CERTOCSPCertID *certID, 5491 CERTOCSPCertID *certID,
5553 CERTCertificate *signerCert, 5492 CERTCertificate *signerCert,
5554 PRTime time, 5493 PRTime time,
5555 CERTOCSPSingleResponse 5494 CERTOCSPSingleResponse
5556 **pSingleResponse) 5495 **pSingleResponse)
5557 { 5496 {
5558 SECStatus rv; 5497 SECStatus rv;
5559 ocspResponseData *responseData; 5498 ocspResponseData *responseData;
5560 PRTime producedAt; 5499 PRTime producedAt;
5561 CERTOCSPSingleResponse *single; 5500 CERTOCSPSingleResponse *single;
5562 5501
5563 /* 5502 /*
5564 * The ResponseData part is the real guts of the response. 5503 * The ResponseData part is the real guts of the response.
5565 */ 5504 */
(...skipping 23 matching lines...) Expand all
5589 rv = ocsp_VerifySingleResponse(single, handle, signerCert, producedAt); 5528 rv = ocsp_VerifySingleResponse(single, handle, signerCert, producedAt);
5590 if (rv != SECSuccess) 5529 if (rv != SECSuccess)
5591 goto loser; 5530 goto loser;
5592 *pSingleResponse = single; 5531 *pSingleResponse = single;
5593 5532
5594 loser: 5533 loser:
5595 return rv; 5534 return rv;
5596 } 5535 }
5597 5536
5598 SECStatus 5537 SECStatus
5599 CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle, 5538 CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
5600 CERTOCSPResponse *response, 5539 CERTOCSPResponse *response,
5601 CERTOCSPCertID *certID, 5540 CERTOCSPCertID *certID,
5602 CERTCertificate *signerCert, 5541 CERTCertificate *signerCert,
5603 PRTime time) 5542 PRTime time)
5604 { 5543 {
5605 /* 5544 /*
5606 * We do not update the cache, because: 5545 * We do not update the cache, because:
5607 * 5546 *
5608 * CERT_GetOCSPStatusForCertID is an old exported API that was introduced 5547 * CERT_GetOCSPStatusForCertID is an old exported API that was introduced
5609 * before the OCSP cache got implemented. 5548 * before the OCSP cache got implemented.
5610 * 5549 *
5611 * The implementation of helper function cert_ProcessOCSPResponse 5550 * The implementation of helper function cert_ProcessOCSPResponse
5612 * requires the ability to transfer ownership of the the given certID to 5551 * requires the ability to transfer ownership of the the given certID to
5613 * the cache. The external API doesn't allow us to prevent the caller from 5552 * the cache. The external API doesn't allow us to prevent the caller from
5614 * destroying the certID. We don't have the original certificate available, 5553 * destroying the certID. We don't have the original certificate available,
5615 * therefore we are unable to produce another certID object (that could 5554 * therefore we are unable to produce another certID object (that could
5616 * be stored in the cache). 5555 * be stored in the cache).
5617 * 5556 *
5618 * Should we ever implement code to produce a deep copy of certID, 5557 * Should we ever implement code to produce a deep copy of certID,
5619 * then this could be changed to allow updating the cache. 5558 * then this could be changed to allow updating the cache.
5620 * The duplication would have to be done in 5559 * The duplication would have to be done in
5621 * cert_ProcessOCSPResponse, if the out parameter to indicate 5560 * cert_ProcessOCSPResponse, if the out parameter to indicate
5622 * a transfer of ownership is NULL. 5561 * a transfer of ownership is NULL.
5623 */ 5562 */
5624 return cert_ProcessOCSPResponse(handle, response, certID, 5563 return cert_ProcessOCSPResponse(handle, response, certID,
5625 signerCert, time, 5564 signerCert, time,
5626 NULL, NULL); 5565 NULL, NULL);
5627 } 5566 }
5628 5567
5629 /* 5568 /*
5630 * The first 5 parameters match the definition of CERT_GetOCSPStatusForCertID. 5569 * The first 5 parameters match the definition of CERT_GetOCSPStatusForCertID.
5631 */ 5570 */
5632 SECStatus 5571 SECStatus
5633 cert_ProcessOCSPResponse(CERTCertDBHandle *handle, 5572 cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
5634 CERTOCSPResponse *response, 5573 CERTOCSPResponse *response,
5635 CERTOCSPCertID *certID, 5574 CERTOCSPCertID *certID,
5636 CERTCertificate *signerCert, 5575 CERTCertificate *signerCert,
5637 PRTime time, 5576 PRTime time,
5638 PRBool *certIDWasConsumed, 5577 PRBool *certIDWasConsumed,
5639 SECStatus *cacheUpdateStatus) 5578 SECStatus *cacheUpdateStatus)
5640 { 5579 {
5641 SECStatus rv; 5580 SECStatus rv;
5642 SECStatus rv_cache = SECSuccess; 5581 SECStatus rv_cache = SECSuccess;
5643 CERTOCSPSingleResponse *single = NULL; 5582 CERTOCSPSingleResponse *single = NULL;
5644 5583
5645 rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID, 5584 rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
5646 signerCert, time, &single); 5585 signerCert, time, &single);
5647 if (rv == SECSuccess) { 5586 if (rv == SECSuccess) {
5648 /* 5587 /*
5649 * Check whether the status says revoked, and if so 5588 * Check whether the status says revoked, and if so
5650 * how that compares to the time value passed into this routine. 5589 * how that compares to the time value passed into this routine.
5651 */ 5590 */
5652 rv = ocsp_SingleResponseCertHasGoodStatus(single, time); 5591 rv = ocsp_SingleResponseCertHasGoodStatus(single, time);
5653 } 5592 }
5654 5593
5655 if (certIDWasConsumed) { 5594 if (certIDWasConsumed) {
5656 /* 5595 /*
5657 * We don't have copy-of-certid implemented. In order to update 5596 * We don't have copy-of-certid implemented. In order to update
5658 * the cache, the caller must supply an out variable 5597 * the cache, the caller must supply an out variable
5659 * certIDWasConsumed, allowing us to return ownership status. 5598 * certIDWasConsumed, allowing us to return ownership status.
5660 */ 5599 */
5661 5600
5662 PR_EnterMonitor(OCSP_Global.monitor); 5601 PR_EnterMonitor(OCSP_Global.monitor);
5663 if (OCSP_Global.maxCacheEntries >= 0) { 5602 if (OCSP_Global.maxCacheEntries >= 0) {
5664 /* single == NULL means: remember response failure */ 5603 /* single == NULL means: remember response failure */
5665 rv_cache = 5604 rv_cache =
5666 ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, 5605 ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID,
5667 single, certIDWasConsumed); 5606 single, certIDWasConsumed);
5668 } 5607 }
5669 PR_ExitMonitor(OCSP_Global.monitor); 5608 PR_ExitMonitor(OCSP_Global.monitor);
5670 if (cacheUpdateStatus) { 5609 if (cacheUpdateStatus) {
5671 *cacheUpdateStatus = rv_cache; 5610 *cacheUpdateStatus = rv_cache;
5672 } 5611 }
5673 } 5612 }
5674 5613
5675 return rv; 5614 return rv;
5676 } 5615 }
5677 5616
5678 SECStatus 5617 SECStatus
5679 cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID, 5618 cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
5680 PRBool *certIDWasConsumed) 5619 PRBool *certIDWasConsumed)
5681 { 5620 {
5682 SECStatus rv = SECSuccess; 5621 SECStatus rv = SECSuccess;
5683 PR_EnterMonitor(OCSP_Global.monitor); 5622 PR_EnterMonitor(OCSP_Global.monitor);
5684 if (OCSP_Global.maxCacheEntries >= 0) { 5623 if (OCSP_Global.maxCacheEntries >= 0) {
5685 rv = ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, NULL, 5624 rv = ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, NULL,
5686 certIDWasConsumed); 5625 certIDWasConsumed);
5687 } 5626 }
5688 PR_ExitMonitor(OCSP_Global.monitor); 5627 PR_ExitMonitor(OCSP_Global.monitor);
5689 return rv; 5628 return rv;
5690 } 5629 }
5691 5630
5692 /* 5631 /*
5693 * Disable status checking and destroy related structures/data. 5632 * Disable status checking and destroy related structures/data.
5694 */ 5633 */
5695 static SECStatus 5634 static SECStatus
5696 ocsp_DestroyStatusChecking(CERTStatusConfig *statusConfig) 5635 ocsp_DestroyStatusChecking(CERTStatusConfig *statusConfig)
5697 { 5636 {
5698 ocspCheckingContext *statusContext; 5637 ocspCheckingContext *statusContext;
5699 5638
5700 /* 5639 /*
5701 * Disable OCSP checking 5640 * Disable OCSP checking
5702 */ 5641 */
5703 statusConfig->statusChecker = NULL; 5642 statusConfig->statusChecker = NULL;
5704 5643
5705 statusContext = statusConfig->statusContext; 5644 statusContext = statusConfig->statusContext;
5706 PORT_Assert(statusContext != NULL); 5645 PORT_Assert(statusContext != NULL);
5707 if (statusContext == NULL) 5646 if (statusContext == NULL)
5708 » return SECFailure; 5647 return SECFailure;
5709 5648
5710 if (statusContext->defaultResponderURI != NULL) 5649 if (statusContext->defaultResponderURI != NULL)
5711 » PORT_Free(statusContext->defaultResponderURI); 5650 PORT_Free(statusContext->defaultResponderURI);
5712 if (statusContext->defaultResponderNickname != NULL) 5651 if (statusContext->defaultResponderNickname != NULL)
5713 » PORT_Free(statusContext->defaultResponderNickname); 5652 PORT_Free(statusContext->defaultResponderNickname);
5714 5653
5715 PORT_Free(statusContext); 5654 PORT_Free(statusContext);
5716 statusConfig->statusContext = NULL; 5655 statusConfig->statusContext = NULL;
5717 5656
5718 PORT_Free(statusConfig); 5657 PORT_Free(statusConfig);
5719 5658
5720 return SECSuccess; 5659 return SECSuccess;
5721 } 5660 }
5722 5661
5723
5724 /* 5662 /*
5725 * FUNCTION: CERT_DisableOCSPChecking 5663 * FUNCTION: CERT_DisableOCSPChecking
5726 * Turns off OCSP checking for the given certificate database. 5664 * Turns off OCSP checking for the given certificate database.
5727 * This routine disables OCSP checking. Though it will return 5665 * This routine disables OCSP checking. Though it will return
5728 * SECFailure if OCSP checking is not enabled, it is "safe" to 5666 * SECFailure if OCSP checking is not enabled, it is "safe" to
5729 * call it that way and just ignore the return value, if it is 5667 * call it that way and just ignore the return value, if it is
5730 * easier to just call it than to "remember" whether it is enabled. 5668 * easier to just call it than to "remember" whether it is enabled.
5731 * INPUTS: 5669 * INPUTS:
5732 * CERTCertDBHandle *handle 5670 * CERTCertDBHandle *handle
5733 * Certificate database for which OCSP checking will be disabled. 5671 * Certificate database for which OCSP checking will be disabled.
5734 * RETURN: 5672 * RETURN:
5735 * Returns SECFailure if an error occurred (usually means that OCSP 5673 * Returns SECFailure if an error occurred (usually means that OCSP
5736 * checking was not enabled or status contexts were not initialized -- 5674 * checking was not enabled or status contexts were not initialized --
5737 * error set will be SEC_ERROR_OCSP_NOT_ENABLED); SECSuccess otherwise. 5675 * error set will be SEC_ERROR_OCSP_NOT_ENABLED); SECSuccess otherwise.
5738 */ 5676 */
5739 SECStatus 5677 SECStatus
5740 CERT_DisableOCSPChecking(CERTCertDBHandle *handle) 5678 CERT_DisableOCSPChecking(CERTCertDBHandle *handle)
5741 { 5679 {
5742 CERTStatusConfig *statusConfig; 5680 CERTStatusConfig *statusConfig;
5743 ocspCheckingContext *statusContext; 5681 ocspCheckingContext *statusContext;
5744 5682
5745 if (handle == NULL) { 5683 if (handle == NULL) {
5746 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 5684 PORT_SetError(SEC_ERROR_INVALID_ARGS);
5747 » return SECFailure; 5685 return SECFailure;
5748 } 5686 }
5749 5687
5750 statusConfig = CERT_GetStatusConfig(handle); 5688 statusConfig = CERT_GetStatusConfig(handle);
5751 statusContext = ocsp_GetCheckingContext(handle); 5689 statusContext = ocsp_GetCheckingContext(handle);
5752 if (statusContext == NULL) 5690 if (statusContext == NULL)
5753 » return SECFailure; 5691 return SECFailure;
5754 5692
5755 if (statusConfig->statusChecker != CERT_CheckOCSPStatus) { 5693 if (statusConfig->statusChecker != CERT_CheckOCSPStatus) {
5756 » /* 5694 /*
5757 » * Status configuration is present, but either not currently 5695 » * Status configuration is present, but either not currently
5758 » * enabled or not for OCSP. 5696 » * enabled or not for OCSP.
5759 » */ 5697 » */
5760 » PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED); 5698 PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED);
5761 » return SECFailure; 5699 return SECFailure;
5762 } 5700 }
5763 5701
5764 /* cache no longer necessary */ 5702 /* cache no longer necessary */
5765 CERT_ClearOCSPCache(); 5703 CERT_ClearOCSPCache();
5766 5704
5767 /* 5705 /*
5768 * This is how we disable status checking. Everything else remains 5706 * This is how we disable status checking. Everything else remains
5769 * in place in case we are enabled again. 5707 * in place in case we are enabled again.
5770 */ 5708 */
5771 statusConfig->statusChecker = NULL; 5709 statusConfig->statusChecker = NULL;
5772 5710
5773 return SECSuccess; 5711 return SECSuccess;
5774 } 5712 }
5775 5713
5776 /* 5714 /*
5777 * Allocate and initialize the informational structures for status checking. 5715 * Allocate and initialize the informational structures for status checking.
5778 * This is done when some configuration of OCSP is being done or when OCSP 5716 * This is done when some configuration of OCSP is being done or when OCSP
5779 * checking is being turned on, whichever comes first. 5717 * checking is being turned on, whichever comes first.
5780 */ 5718 */
5781 static SECStatus 5719 static SECStatus
5782 ocsp_InitStatusChecking(CERTCertDBHandle *handle) 5720 ocsp_InitStatusChecking(CERTCertDBHandle *handle)
5783 { 5721 {
5784 CERTStatusConfig *statusConfig = NULL; 5722 CERTStatusConfig *statusConfig = NULL;
5785 ocspCheckingContext *statusContext = NULL; 5723 ocspCheckingContext *statusContext = NULL;
5786 5724
5787 PORT_Assert(CERT_GetStatusConfig(handle) == NULL); 5725 PORT_Assert(CERT_GetStatusConfig(handle) == NULL);
5788 if (CERT_GetStatusConfig(handle) != NULL) { 5726 if (CERT_GetStatusConfig(handle) != NULL) {
5789 » /* XXX or call statusConfig->statusDestroy and continue? */ 5727 /* XXX or call statusConfig->statusDestroy and continue? */
5790 » return SECFailure; 5728 return SECFailure;
5791 } 5729 }
5792 5730
5793 statusConfig = PORT_ZNew(CERTStatusConfig); 5731 statusConfig = PORT_ZNew(CERTStatusConfig);
5794 if (statusConfig == NULL) 5732 if (statusConfig == NULL)
5795 » goto loser; 5733 goto loser;
5796 5734
5797 statusContext = PORT_ZNew(ocspCheckingContext); 5735 statusContext = PORT_ZNew(ocspCheckingContext);
5798 if (statusContext == NULL) 5736 if (statusContext == NULL)
5799 » goto loser; 5737 goto loser;
5800 5738
5801 statusConfig->statusDestroy = ocsp_DestroyStatusChecking; 5739 statusConfig->statusDestroy = ocsp_DestroyStatusChecking;
5802 statusConfig->statusContext = statusContext; 5740 statusConfig->statusContext = statusContext;
5803 5741
5804 CERT_SetStatusConfig(handle, statusConfig); 5742 CERT_SetStatusConfig(handle, statusConfig);
5805 5743
5806 return SECSuccess; 5744 return SECSuccess;
5807 5745
5808 loser: 5746 loser:
5809 if (statusConfig != NULL) 5747 if (statusConfig != NULL)
5810 » PORT_Free(statusConfig); 5748 PORT_Free(statusConfig);
5811 return SECFailure; 5749 return SECFailure;
5812 } 5750 }
5813 5751
5814
5815 /* 5752 /*
5816 * FUNCTION: CERT_EnableOCSPChecking 5753 * FUNCTION: CERT_EnableOCSPChecking
5817 * Turns on OCSP checking for the given certificate database. 5754 * Turns on OCSP checking for the given certificate database.
5818 * INPUTS: 5755 * INPUTS:
5819 * CERTCertDBHandle *handle 5756 * CERTCertDBHandle *handle
5820 * Certificate database for which OCSP checking will be enabled. 5757 * Certificate database for which OCSP checking will be enabled.
5821 * RETURN: 5758 * RETURN:
5822 * Returns SECFailure if an error occurred (likely only problem 5759 * Returns SECFailure if an error occurred (likely only problem
5823 * allocating memory); SECSuccess otherwise. 5760 * allocating memory); SECSuccess otherwise.
5824 */ 5761 */
5825 SECStatus 5762 SECStatus
5826 CERT_EnableOCSPChecking(CERTCertDBHandle *handle) 5763 CERT_EnableOCSPChecking(CERTCertDBHandle *handle)
5827 { 5764 {
5828 CERTStatusConfig *statusConfig; 5765 CERTStatusConfig *statusConfig;
5829 5766
5830 SECStatus rv; 5767 SECStatus rv;
5831 5768
5832 if (handle == NULL) { 5769 if (handle == NULL) {
5833 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 5770 PORT_SetError(SEC_ERROR_INVALID_ARGS);
5834 » return SECFailure; 5771 return SECFailure;
5835 } 5772 }
5836 5773
5837 statusConfig = CERT_GetStatusConfig(handle); 5774 statusConfig = CERT_GetStatusConfig(handle);
5838 if (statusConfig == NULL) { 5775 if (statusConfig == NULL) {
5839 » rv = ocsp_InitStatusChecking(handle); 5776 rv = ocsp_InitStatusChecking(handle);
5840 » if (rv != SECSuccess) 5777 if (rv != SECSuccess)
5841 » return rv; 5778 return rv;
5842 5779
5843 » /* Get newly established value */ 5780 /* Get newly established value */
5844 » statusConfig = CERT_GetStatusConfig(handle); 5781 statusConfig = CERT_GetStatusConfig(handle);
5845 » PORT_Assert(statusConfig != NULL); 5782 PORT_Assert(statusConfig != NULL);
5846 } 5783 }
5847 5784
5848 /* 5785 /*
5849 * Setting the checker function is what really enables the checking 5786 * Setting the checker function is what really enables the checking
5850 * when each cert verification is done. 5787 * when each cert verification is done.
5851 */ 5788 */
5852 statusConfig->statusChecker = CERT_CheckOCSPStatus; 5789 statusConfig->statusChecker = CERT_CheckOCSPStatus;
5853 5790
5854 return SECSuccess; 5791 return SECSuccess;
5855 } 5792 }
5856 5793
5857
5858 /* 5794 /*
5859 * FUNCTION: CERT_SetOCSPDefaultResponder 5795 * FUNCTION: CERT_SetOCSPDefaultResponder
5860 * Specify the location and cert of the default responder. 5796 * Specify the location and cert of the default responder.
5861 * If OCSP checking is already enabled *and* use of a default responder 5797 * If OCSP checking is already enabled *and* use of a default responder
5862 * is also already enabled, all OCSP checking from now on will go directly 5798 * is also already enabled, all OCSP checking from now on will go directly
5863 * to the specified responder. If OCSP checking is not enabled, or if 5799 * to the specified responder. If OCSP checking is not enabled, or if
5864 * it is but use of a default responder is not enabled, the information 5800 * it is but use of a default responder is not enabled, the information
5865 * will be recorded and take effect whenever both are enabled. 5801 * will be recorded and take effect whenever both are enabled.
5866 * INPUTS: 5802 * INPUTS:
5867 * CERTCertDBHandle *handle 5803 * CERTCertDBHandle *handle
5868 * Cert database on which OCSP checking should use the default responder. 5804 * Cert database on which OCSP checking should use the default responder.
5869 * char *url 5805 * char *url
5870 * The location of the default responder (e.g. "http://foo.com:80/ocsp") 5806 * The location of the default responder (e.g. "http://foo.com:80/ocsp")
5871 * Note that the location will not be tested until the first attempt 5807 * Note that the location will not be tested until the first attempt
5872 * to send a request there. 5808 * to send a request there.
5873 * char *name 5809 * char *name
5874 * The nickname of the cert to trust (expected) to sign the OCSP responses. 5810 * The nickname of the cert to trust (expected) to sign the OCSP responses.
5875 * If the corresponding cert cannot be found, SECFailure is returned. 5811 * If the corresponding cert cannot be found, SECFailure is returned.
5876 * RETURN: 5812 * RETURN:
5877 * Returns SECFailure if an error occurred; SECSuccess otherwise. 5813 * Returns SECFailure if an error occurred; SECSuccess otherwise.
5878 * The most likely error is that the cert for "name" could not be found 5814 * The most likely error is that the cert for "name" could not be found
5879 * (probably SEC_ERROR_UNKNOWN_CERT). Other errors are low-level (no memory, 5815 * (probably SEC_ERROR_UNKNOWN_CERT). Other errors are low-level (no memory,
5880 * bad database, etc.). 5816 * bad database, etc.).
5881 */ 5817 */
5882 SECStatus 5818 SECStatus
5883 CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle, 5819 CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
5884 » » » const char *url, const char *name) 5820 const char *url, const char *name)
5885 { 5821 {
5886 CERTCertificate *cert; 5822 CERTCertificate *cert;
5887 ocspCheckingContext *statusContext; 5823 ocspCheckingContext *statusContext;
5888 char *url_copy = NULL; 5824 char *url_copy = NULL;
5889 char *name_copy = NULL; 5825 char *name_copy = NULL;
5890 SECStatus rv; 5826 SECStatus rv;
5891 5827
5892 if (handle == NULL || url == NULL || name == NULL) { 5828 if (handle == NULL || url == NULL || name == NULL) {
5893 » /* 5829 /*
5894 » * XXX When interface is exported, probably want better errors; 5830 » * XXX When interface is exported, probably want better errors;
5895 » * perhaps different one for each parameter. 5831 » * perhaps different one for each parameter.
5896 » */ 5832 » */
5897 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 5833 PORT_SetError(SEC_ERROR_INVALID_ARGS);
5898 » return SECFailure; 5834 return SECFailure;
5899 } 5835 }
5900 5836
5901 /* 5837 /*
5902 * Find the certificate for the specified nickname. Do this first 5838 * Find the certificate for the specified nickname. Do this first
5903 * because it seems the most likely to fail. 5839 * because it seems the most likely to fail.
5904 * 5840 *
5905 * XXX Shouldn't need that cast if the FindCertByNickname interface 5841 * XXX Shouldn't need that cast if the FindCertByNickname interface
5906 * used const to convey that it does not modify the name. Maybe someday. 5842 * used const to convey that it does not modify the name. Maybe someday.
5907 */ 5843 */
5908 cert = CERT_FindCertByNickname(handle, (char *) name); 5844 cert = CERT_FindCertByNickname(handle, (char *)name);
5909 if (cert == NULL) { 5845 if (cert == NULL) {
5910 /* 5846 /*
5911 * look for the cert on an external token. 5847 * look for the cert on an external token.
5912 */ 5848 */
5913 cert = PK11_FindCertFromNickname((char *)name, NULL); 5849 cert = PK11_FindCertFromNickname((char *)name, NULL);
5914 } 5850 }
5915 if (cert == NULL) 5851 if (cert == NULL)
5916 » return SECFailure; 5852 return SECFailure;
5917 5853
5918 /* 5854 /*
5919 * Make a copy of the url and nickname. 5855 * Make a copy of the url and nickname.
5920 */ 5856 */
5921 url_copy = PORT_Strdup(url); 5857 url_copy = PORT_Strdup(url);
5922 name_copy = PORT_Strdup(name); 5858 name_copy = PORT_Strdup(name);
5923 if (url_copy == NULL || name_copy == NULL) { 5859 if (url_copy == NULL || name_copy == NULL) {
5924 » rv = SECFailure; 5860 rv = SECFailure;
5925 » goto loser; 5861 goto loser;
5926 } 5862 }
5927 5863
5928 statusContext = ocsp_GetCheckingContext(handle); 5864 statusContext = ocsp_GetCheckingContext(handle);
5929 5865
5930 /* 5866 /*
5931 * Allocate and init the context if it doesn't already exist. 5867 * Allocate and init the context if it doesn't already exist.
5932 */ 5868 */
5933 if (statusContext == NULL) { 5869 if (statusContext == NULL) {
5934 » rv = ocsp_InitStatusChecking(handle); 5870 rv = ocsp_InitStatusChecking(handle);
5935 » if (rv != SECSuccess) 5871 if (rv != SECSuccess)
5936 » goto loser; 5872 goto loser;
5937 5873
5938 » statusContext = ocsp_GetCheckingContext(handle); 5874 statusContext = ocsp_GetCheckingContext(handle);
5939 » PORT_Assert(statusContext != NULL);» /* extreme paranoia */ 5875 PORT_Assert(statusContext != NULL); /* extreme paranoia */
5940 } 5876 }
5941 5877
5942 /* 5878 /*
5943 * Note -- we do not touch the status context until after all of 5879 * Note -- we do not touch the status context until after all of
5944 * the steps which could cause errors. If something goes wrong, 5880 * the steps which could cause errors. If something goes wrong,
5945 * we want to leave things as they were. 5881 * we want to leave things as they were.
5946 */ 5882 */
5947 5883
5948 /* 5884 /*
5949 * Get rid of old url and name if there. 5885 * Get rid of old url and name if there.
5950 */ 5886 */
5951 if (statusContext->defaultResponderNickname != NULL) 5887 if (statusContext->defaultResponderNickname != NULL)
5952 » PORT_Free(statusContext->defaultResponderNickname); 5888 PORT_Free(statusContext->defaultResponderNickname);
5953 if (statusContext->defaultResponderURI != NULL) 5889 if (statusContext->defaultResponderURI != NULL)
5954 » PORT_Free(statusContext->defaultResponderURI); 5890 PORT_Free(statusContext->defaultResponderURI);
5955 5891
5956 /* 5892 /*
5957 * And replace them with the new ones. 5893 * And replace them with the new ones.
5958 */ 5894 */
5959 statusContext->defaultResponderURI = url_copy; 5895 statusContext->defaultResponderURI = url_copy;
5960 statusContext->defaultResponderNickname = name_copy; 5896 statusContext->defaultResponderNickname = name_copy;
5961 5897
5962 /* 5898 /*
5963 * If there was already a cert in place, get rid of it and replace it. 5899 * If there was already a cert in place, get rid of it and replace it.
5964 * Otherwise, we are not currently enabled, so we don't want to save it; 5900 * Otherwise, we are not currently enabled, so we don't want to save it;
5965 * it will get re-found and set whenever use of a default responder is 5901 * it will get re-found and set whenever use of a default responder is
5966 * enabled. 5902 * enabled.
5967 */ 5903 */
5968 if (statusContext->defaultResponderCert != NULL) { 5904 if (statusContext->defaultResponderCert != NULL) {
5969 » CERT_DestroyCertificate(statusContext->defaultResponderCert); 5905 CERT_DestroyCertificate(statusContext->defaultResponderCert);
5970 » statusContext->defaultResponderCert = cert; 5906 statusContext->defaultResponderCert = cert;
5971 /*OCSP enabled, switching responder: clear cache*/ 5907 /*OCSP enabled, switching responder: clear cache*/
5972 CERT_ClearOCSPCache(); 5908 CERT_ClearOCSPCache();
5973 } else { 5909 } else {
5974 » PORT_Assert(statusContext->useDefaultResponder == PR_FALSE); 5910 PORT_Assert(statusContext->useDefaultResponder == PR_FALSE);
5975 » CERT_DestroyCertificate(cert); 5911 CERT_DestroyCertificate(cert);
5976 /*OCSP currently not enabled, no need to clear cache*/ 5912 /*OCSP currently not enabled, no need to clear cache*/
5977 } 5913 }
5978 5914
5979 return SECSuccess; 5915 return SECSuccess;
5980 5916
5981 loser: 5917 loser:
5982 CERT_DestroyCertificate(cert); 5918 CERT_DestroyCertificate(cert);
5983 if (url_copy != NULL) 5919 if (url_copy != NULL)
5984 » PORT_Free(url_copy); 5920 PORT_Free(url_copy);
5985 if (name_copy != NULL) 5921 if (name_copy != NULL)
5986 » PORT_Free(name_copy); 5922 PORT_Free(name_copy);
5987 return rv; 5923 return rv;
5988 } 5924 }
5989 5925
5990
5991 /* 5926 /*
5992 * FUNCTION: CERT_EnableOCSPDefaultResponder 5927 * FUNCTION: CERT_EnableOCSPDefaultResponder
5993 * Turns on use of a default responder when OCSP checking. 5928 * Turns on use of a default responder when OCSP checking.
5994 * If OCSP checking is already enabled, this will make subsequent checks 5929 * If OCSP checking is already enabled, this will make subsequent checks
5995 * go directly to the default responder. (The location of the responder 5930 * go directly to the default responder. (The location of the responder
5996 * and the nickname of the responder cert must already be specified.) 5931 * and the nickname of the responder cert must already be specified.)
5997 * If OCSP checking is not enabled, this will be recorded and take effect 5932 * If OCSP checking is not enabled, this will be recorded and take effect
5998 * whenever it is enabled. 5933 * whenever it is enabled.
5999 * INPUTS: 5934 * INPUTS:
6000 * CERTCertDBHandle *handle 5935 * CERTCertDBHandle *handle
6001 * Cert database on which OCSP checking should use the default responder. 5936 * Cert database on which OCSP checking should use the default responder.
6002 * RETURN: 5937 * RETURN:
6003 * Returns SECFailure if an error occurred; SECSuccess otherwise. 5938 * Returns SECFailure if an error occurred; SECSuccess otherwise.
6004 * No errors are especially likely unless the caller did not previously 5939 * No errors are especially likely unless the caller did not previously
6005 * perform a successful call to SetOCSPDefaultResponder (in which case 5940 * perform a successful call to SetOCSPDefaultResponder (in which case
6006 * the error set will be SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER). 5941 * the error set will be SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER).
6007 */ 5942 */
6008 SECStatus 5943 SECStatus
6009 CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle) 5944 CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle)
6010 { 5945 {
6011 ocspCheckingContext *statusContext; 5946 ocspCheckingContext *statusContext;
6012 CERTCertificate *cert; 5947 CERTCertificate *cert;
6013 SECStatus rv; 5948 SECStatus rv;
6014 SECCertificateUsage usage; 5949 SECCertificateUsage usage;
6015 5950
6016 if (handle == NULL) { 5951 if (handle == NULL) {
6017 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 5952 PORT_SetError(SEC_ERROR_INVALID_ARGS);
6018 » return SECFailure; 5953 return SECFailure;
6019 } 5954 }
6020 5955
6021 statusContext = ocsp_GetCheckingContext(handle); 5956 statusContext = ocsp_GetCheckingContext(handle);
6022 5957
6023 if (statusContext == NULL) { 5958 if (statusContext == NULL) {
6024 » /* 5959 /*
6025 » * Strictly speaking, the error already set is "correct", 5960 » * Strictly speaking, the error already set is "correct",
6026 » * but cover over it with one more helpful in this context. 5961 » * but cover over it with one more helpful in this context.
6027 » */ 5962 » */
6028 » PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER); 5963 PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
6029 » return SECFailure; 5964 return SECFailure;
6030 } 5965 }
6031 5966
6032 if (statusContext->defaultResponderURI == NULL) { 5967 if (statusContext->defaultResponderURI == NULL) {
6033 » PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER); 5968 PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
6034 » return SECFailure; 5969 return SECFailure;
6035 } 5970 }
6036 5971
6037 if (statusContext->defaultResponderNickname == NULL) { 5972 if (statusContext->defaultResponderNickname == NULL) {
6038 » PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER); 5973 PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER);
6039 » return SECFailure; 5974 return SECFailure;
6040 } 5975 }
6041 5976
6042 /* 5977 /*
6043 * Find the cert for the nickname. 5978 * Find the cert for the nickname.
6044 */ 5979 */
6045 cert = CERT_FindCertByNickname(handle, 5980 cert = CERT_FindCertByNickname(handle,
6046 » » » » statusContext->defaultResponderNickname); 5981 statusContext->defaultResponderNickname);
6047 if (cert == NULL) { 5982 if (cert == NULL) {
6048 cert = PK11_FindCertFromNickname(statusContext->defaultResponderNickname , 5983 cert = PK11_FindCertFromNickname(statusContext->defaultResponderNickname ,
6049 NULL); 5984 NULL);
6050 } 5985 }
6051 /* 5986 /*
6052 * We should never have trouble finding the cert, because its 5987 * We should never have trouble finding the cert, because its
6053 * existence should have been proven by SetOCSPDefaultResponder. 5988 * existence should have been proven by SetOCSPDefaultResponder.
6054 */ 5989 */
6055 PORT_Assert(cert != NULL); 5990 PORT_Assert(cert != NULL);
6056 if (cert == NULL) 5991 if (cert == NULL)
6057 » return SECFailure; 5992 return SECFailure;
6058 5993
6059 /* 5994 /*
6060 * Supplied cert should at least have a signing capability in order for us 5995 * Supplied cert should at least have a signing capability in order for us
6061 * to use it as a trusted responder cert. Ability to sign is guaranteed if 5996 * to use it as a trusted responder cert. Ability to sign is guaranteed if
6062 * cert is validated to have any set of the usages below. 5997 * cert is validated to have any set of the usages below.
6063 */ 5998 */
6064 rv = CERT_VerifyCertificateNow(handle, cert, PR_TRUE, 5999 rv = CERT_VerifyCertificateNow(handle, cert, PR_TRUE,
6065 certificateUsageCheckAllUsages, 6000 certificateUsageCheckAllUsages,
6066 NULL, &usage); 6001 NULL, &usage);
6067 if (rv != SECSuccess || (usage & (certificateUsageSSLClient | 6002 if (rv != SECSuccess || (usage & (certificateUsageSSLClient |
6068 certificateUsageSSLServer | 6003 certificateUsageSSLServer |
6069 certificateUsageSSLServerWithStepUp | 6004 certificateUsageSSLServerWithStepUp |
6070 certificateUsageEmailSigner | 6005 certificateUsageEmailSigner |
6071 certificateUsageObjectSigner | 6006 certificateUsageObjectSigner |
6072 certificateUsageStatusResponder | 6007 certificateUsageStatusResponder |
6073 certificateUsageSSLCA)) == 0) { 6008 certificateUsageSSLCA)) == 0) {
6074 » PORT_SetError(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID); 6009 PORT_SetError(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID);
6075 » return SECFailure; 6010 return SECFailure;
6076 } 6011 }
6077 6012
6078 /* 6013 /*
6079 * And hang onto it. 6014 * And hang onto it.
6080 */ 6015 */
6081 statusContext->defaultResponderCert = cert; 6016 statusContext->defaultResponderCert = cert;
6082 6017
6083 /* we don't allow a mix of cache entries from different responders */ 6018 /* we don't allow a mix of cache entries from different responders */
6084 CERT_ClearOCSPCache(); 6019 CERT_ClearOCSPCache();
6085 6020
6086 /* 6021 /*
6087 * Finally, record the fact that we now have a default responder enabled. 6022 * Finally, record the fact that we now have a default responder enabled.
6088 */ 6023 */
6089 statusContext->useDefaultResponder = PR_TRUE; 6024 statusContext->useDefaultResponder = PR_TRUE;
6090 return SECSuccess; 6025 return SECSuccess;
6091 } 6026 }
6092 6027
6093
6094 /* 6028 /*
6095 * FUNCTION: CERT_DisableOCSPDefaultResponder 6029 * FUNCTION: CERT_DisableOCSPDefaultResponder
6096 * Turns off use of a default responder when OCSP checking. 6030 * Turns off use of a default responder when OCSP checking.
6097 * (Does nothing if use of a default responder is not enabled.) 6031 * (Does nothing if use of a default responder is not enabled.)
6098 * INPUTS: 6032 * INPUTS:
6099 * CERTCertDBHandle *handle 6033 * CERTCertDBHandle *handle
6100 * Cert database on which OCSP checking should stop using a default 6034 * Cert database on which OCSP checking should stop using a default
6101 * responder. 6035 * responder.
6102 * RETURN: 6036 * RETURN:
6103 * Returns SECFailure if an error occurred; SECSuccess otherwise. 6037 * Returns SECFailure if an error occurred; SECSuccess otherwise.
6104 * Errors very unlikely (like random memory corruption...). 6038 * Errors very unlikely (like random memory corruption...).
6105 */ 6039 */
6106 SECStatus 6040 SECStatus
6107 CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle) 6041 CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle)
6108 { 6042 {
6109 CERTStatusConfig *statusConfig; 6043 CERTStatusConfig *statusConfig;
6110 ocspCheckingContext *statusContext; 6044 ocspCheckingContext *statusContext;
6111 CERTCertificate *tmpCert; 6045 CERTCertificate *tmpCert;
6112 6046
6113 if (handle == NULL) { 6047 if (handle == NULL) {
6114 » PORT_SetError(SEC_ERROR_INVALID_ARGS); 6048 PORT_SetError(SEC_ERROR_INVALID_ARGS);
6115 » return SECFailure; 6049 return SECFailure;
6116 } 6050 }
6117 6051
6118 statusConfig = CERT_GetStatusConfig(handle); 6052 statusConfig = CERT_GetStatusConfig(handle);
6119 if (statusConfig == NULL) 6053 if (statusConfig == NULL)
6120 » return SECSuccess; 6054 return SECSuccess;
6121 6055
6122 statusContext = ocsp_GetCheckingContext(handle); 6056 statusContext = ocsp_GetCheckingContext(handle);
6123 PORT_Assert(statusContext != NULL); 6057 PORT_Assert(statusContext != NULL);
6124 if (statusContext == NULL) 6058 if (statusContext == NULL)
6125 » return SECFailure; 6059 return SECFailure;
6126 6060
6127 tmpCert = statusContext->defaultResponderCert; 6061 tmpCert = statusContext->defaultResponderCert;
6128 if (tmpCert) { 6062 if (tmpCert) {
6129 » statusContext->defaultResponderCert = NULL; 6063 statusContext->defaultResponderCert = NULL;
6130 » CERT_DestroyCertificate(tmpCert); 6064 CERT_DestroyCertificate(tmpCert);
6131 /* we don't allow a mix of cache entries from different responders */ 6065 /* we don't allow a mix of cache entries from different responders */
6132 CERT_ClearOCSPCache(); 6066 CERT_ClearOCSPCache();
6133 } 6067 }
6134 6068
6135 /* 6069 /*
6136 * Finally, record the fact. 6070 * Finally, record the fact.
6137 */ 6071 */
6138 statusContext->useDefaultResponder = PR_FALSE; 6072 statusContext->useDefaultResponder = PR_FALSE;
6139 return SECSuccess; 6073 return SECSuccess;
6140 } 6074 }
(...skipping 11 matching lines...) Expand all
6152 PR_ExitMonitor(OCSP_Global.monitor); 6086 PR_ExitMonitor(OCSP_Global.monitor);
6153 6087
6154 return SECSuccess; 6088 return SECSuccess;
6155 } 6089 }
6156 6090
6157 SECStatus 6091 SECStatus
6158 CERT_GetOCSPResponseStatus(CERTOCSPResponse *response) 6092 CERT_GetOCSPResponseStatus(CERTOCSPResponse *response)
6159 { 6093 {
6160 PORT_Assert(response); 6094 PORT_Assert(response);
6161 if (response->statusValue == ocspResponse_successful) 6095 if (response->statusValue == ocspResponse_successful)
6162 » return SECSuccess; 6096 return SECSuccess;
6163 6097
6164 switch (response->statusValue) { 6098 switch (response->statusValue) {
6165 case ocspResponse_malformedRequest: 6099 case ocspResponse_malformedRequest:
6166 » PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); 6100 PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST);
6167 » break; 6101 break;
6168 case ocspResponse_internalError: 6102 case ocspResponse_internalError:
6169 » PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); 6103 PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR);
6170 » break; 6104 break;
6171 case ocspResponse_tryLater: 6105 case ocspResponse_tryLater:
6172 » PORT_SetError(SEC_ERROR_OCSP_TRY_SERVER_LATER); 6106 PORT_SetError(SEC_ERROR_OCSP_TRY_SERVER_LATER);
6173 » break; 6107 break;
6174 case ocspResponse_sigRequired: 6108 case ocspResponse_sigRequired:
6175 » /* XXX We *should* retry with a signature, if possible. */ 6109 /* XXX We *should* retry with a signature, if possible. */
6176 » PORT_SetError(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG); 6110 PORT_SetError(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
6177 » break; 6111 break;
6178 case ocspResponse_unauthorized: 6112 case ocspResponse_unauthorized:
6179 » PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST); 6113 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
6180 » break; 6114 break;
6181 case ocspResponse_unused: 6115 case ocspResponse_unused:
6182 default: 6116 default:
6183 » PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS); 6117 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
6184 » break; 6118 break;
6185 } 6119 }
6186 return SECFailure; 6120 return SECFailure;
6187 } 6121 }
OLDNEW
« no previous file with comments | « nss/lib/certhigh/ocsp.h ('k') | nss/lib/certhigh/ocspi.h » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698