|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 /* |
|
5 * certi.h - private data structures for the certificate library |
|
6 */ |
|
7 #ifndef _CERTI_H_ |
|
8 #define _CERTI_H_ |
|
9 |
|
10 #include "certt.h" |
|
11 #include "nssrwlkt.h" |
|
12 |
|
13 /* |
|
14 #define GLOBAL_RWLOCK 1 |
|
15 */ |
|
16 |
|
17 #define DPC_RWLOCK 1 |
|
18 |
|
19 /* all definitions in this file are subject to change */ |
|
20 |
|
21 typedef struct OpaqueCRLFieldsStr OpaqueCRLFields; |
|
22 typedef struct CRLEntryCacheStr CRLEntryCache; |
|
23 typedef struct CRLDPCacheStr CRLDPCache; |
|
24 typedef struct CRLIssuerCacheStr CRLIssuerCache; |
|
25 typedef struct CRLCacheStr CRLCache; |
|
26 typedef struct CachedCrlStr CachedCrl; |
|
27 typedef struct NamedCRLCacheStr NamedCRLCache; |
|
28 typedef struct NamedCRLCacheEntryStr NamedCRLCacheEntry; |
|
29 |
|
30 struct OpaqueCRLFieldsStr { |
|
31 PRBool partial; |
|
32 PRBool decodingError; |
|
33 PRBool badEntries; |
|
34 PRBool badDER; |
|
35 PRBool badExtensions; |
|
36 PRBool heapDER; |
|
37 }; |
|
38 |
|
39 typedef struct PreAllocatorStr PreAllocator; |
|
40 |
|
41 struct PreAllocatorStr |
|
42 { |
|
43 PRSize len; |
|
44 void* data; |
|
45 PRSize used; |
|
46 PLArenaPool* arena; |
|
47 PRSize extra; |
|
48 }; |
|
49 |
|
50 /* CRL entry cache. |
|
51 This is the same as an entry plus the next/prev pointers for the hash table |
|
52 */ |
|
53 |
|
54 struct CRLEntryCacheStr { |
|
55 CERTCrlEntry entry; |
|
56 CRLEntryCache *prev, *next; |
|
57 }; |
|
58 |
|
59 #define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set |
|
60 if we have CRL objects with an invalid DER or signature. Can be |
|
61 cleared if the invalid objects are deleted from the token */ |
|
62 #define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set |
|
63 if the last CRL fetch encountered an error. Can be cleared if a |
|
64 new fetch succeeds */ |
|
65 |
|
66 #define CRL_CACHE_OUT_OF_MEMORY 0x0004 /* this state will be set |
|
67 if we don't have enough memory to build the hash table of entries */ |
|
68 |
|
69 typedef enum { |
|
70 CRL_OriginToken = 0, /* CRL came from PKCS#11 token */ |
|
71 CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */ |
|
72 } CRLOrigin; |
|
73 |
|
74 typedef enum { |
|
75 dpcacheNoEntry = 0, /* no entry found for this SN */ |
|
76 dpcacheFoundEntry = 1, /* entry found for this SN */ |
|
77 dpcacheCallerError = 2, /* invalid args */ |
|
78 dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */ |
|
79 /* or unverified */ |
|
80 dpcacheEmpty = 4, /* no CRL in cache */ |
|
81 dpcacheLookupError = 5 /* internal error */ |
|
82 } dpcacheStatus; |
|
83 |
|
84 |
|
85 struct CachedCrlStr { |
|
86 CERTSignedCrl* crl; |
|
87 CRLOrigin origin; |
|
88 /* hash table of entries. We use a PLHashTable and pre-allocate the |
|
89 required amount of memory in one shot, so that our allocator can |
|
90 simply pass offsets into it when hashing. |
|
91 |
|
92 This won't work anymore when we support delta CRLs and iCRLs, because |
|
93 the size of the hash table will vary over time. At that point, the best |
|
94 solution will be to allocate large CRLEntry structures by modifying |
|
95 the DER decoding template. The extra space would be for next/prev |
|
96 pointers. This would allow entries from different CRLs to be mixed in |
|
97 the same hash table. |
|
98 */ |
|
99 PLHashTable* entries; |
|
100 PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */ |
|
101 PRBool sigChecked; /* this CRL signature has already been checked */ |
|
102 PRBool sigValid; /* signature verification status . |
|
103 Only meaningful if checked is PR_TRUE . */ |
|
104 PRBool unbuildable; /* Avoid using assosiated CRL is it fails |
|
105 * a decoding step */ |
|
106 }; |
|
107 |
|
108 /* CRL distribution point cache object |
|
109 This is a cache of CRL entries for a given distribution point of an issuer |
|
110 It is built from a collection of one full and 0 or more delta CRLs. |
|
111 */ |
|
112 |
|
113 struct CRLDPCacheStr { |
|
114 #ifdef DPC_RWLOCK |
|
115 NSSRWLock* lock; |
|
116 #else |
|
117 PRLock* lock; |
|
118 #endif |
|
119 CERTCertificate* issuer; /* issuer cert |
|
120 XXX there may be multiple issuer certs, |
|
121 with different validity dates. Also |
|
122 need to deal with SKID/AKID . See |
|
123 bugzilla 217387, 233118 */ |
|
124 SECItem* subject; /* DER of issuer subject */ |
|
125 SECItem* distributionPoint; /* DER of distribution point. This may be |
|
126 NULL when distribution points aren't |
|
127 in use (ie. the CA has a single CRL). |
|
128 Currently not used. */ |
|
129 |
|
130 /* array of full CRLs matching this distribution point */ |
|
131 PRUint32 ncrls; /* total number of CRLs in crls */ |
|
132 CachedCrl** crls; /* array of all matching CRLs */ |
|
133 /* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several |
|
134 issuers. In the future, we'll need to globally recycle the CRL in a |
|
135 separate list in order to avoid extra lookups, decodes, and copies */ |
|
136 |
|
137 /* pointers to good decoded CRLs used to build the cache */ |
|
138 CachedCrl* selected; /* full CRL selected for use in the cache */ |
|
139 #if 0 |
|
140 /* for future use */ |
|
141 PRInt32 numdeltas; /* number of delta CRLs used for the cache */ |
|
142 CachedCrl** deltas; /* delta CRLs used for the cache */ |
|
143 #endif |
|
144 /* cache invalidity bitflag */ |
|
145 PRUint16 invalid; /* this state will be set if either |
|
146 CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set. |
|
147 In those cases, all certs are considered to have unknown status. |
|
148 The invalid state can only be cleared during an update if all |
|
149 error states are cleared */ |
|
150 PRBool refresh; /* manual refresh from tokens has been forced */ |
|
151 PRBool mustchoose; /* trigger reselection algorithm, for case when |
|
152 RAM CRL objects are dropped from the cache */ |
|
153 PRTime lastfetch; /* time a CRL token fetch was last performed */ |
|
154 PRTime lastcheck; /* time CRL token objects were last checked for |
|
155 existence */ |
|
156 }; |
|
157 |
|
158 /* CRL issuer cache object |
|
159 This object tracks all the distribution point caches for a given issuer. |
|
160 XCRL once we support multiple issuing distribution points, this object |
|
161 will be a hash table. For now, it just holds the single CRL distribution |
|
162 point cache structure. |
|
163 */ |
|
164 |
|
165 struct CRLIssuerCacheStr { |
|
166 SECItem* subject; /* DER of issuer subject */ |
|
167 CRLDPCache* dpp; |
|
168 #if 0 |
|
169 /* XCRL for future use. |
|
170 We don't need to lock at the moment because we only have one DP, |
|
171 which gets created at the same time as this object */ |
|
172 NSSRWLock* lock; |
|
173 CRLDPCache** dps; |
|
174 PLHashTable* distributionpoints; |
|
175 CERTCertificate* issuer; |
|
176 #endif |
|
177 }; |
|
178 |
|
179 /* CRL revocation cache object |
|
180 This object tracks all the issuer caches |
|
181 */ |
|
182 |
|
183 struct CRLCacheStr { |
|
184 #ifdef GLOBAL_RWLOCK |
|
185 NSSRWLock* lock; |
|
186 #else |
|
187 PRLock* lock; |
|
188 #endif |
|
189 /* hash table of issuer to CRLIssuerCacheStr, |
|
190 indexed by issuer DER subject */ |
|
191 PLHashTable* issuers; |
|
192 }; |
|
193 |
|
194 SECStatus InitCRLCache(void); |
|
195 SECStatus ShutdownCRLCache(void); |
|
196 |
|
197 /* Returns a pointer to an environment-like string, a series of |
|
198 ** null-terminated strings, terminated by a zero-length string. |
|
199 ** This function is intended to be internal to NSS. |
|
200 */ |
|
201 extern char * cert_GetCertificateEmailAddresses(CERTCertificate *cert); |
|
202 |
|
203 /* |
|
204 * These functions are used to map subjectKeyID extension values to certs |
|
205 * and to keep track of the checks for user certificates in each slot |
|
206 */ |
|
207 SECStatus |
|
208 cert_CreateSubjectKeyIDHashTable(void); |
|
209 |
|
210 SECStatus |
|
211 cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert); |
|
212 |
|
213 SECStatus |
|
214 cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series); |
|
215 |
|
216 int |
|
217 cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid); |
|
218 |
|
219 /* |
|
220 * Call this function to remove an entry from the mapping table. |
|
221 */ |
|
222 SECStatus |
|
223 cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID); |
|
224 |
|
225 SECStatus |
|
226 cert_DestroySubjectKeyIDHashTable(void); |
|
227 |
|
228 SECItem* |
|
229 cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID); |
|
230 |
|
231 /* return maximum length of AVA value based on its type OID tag. */ |
|
232 extern int cert_AVAOidTagToMaxLen(SECOidTag tag); |
|
233 |
|
234 /* Make an AVA, allocated from pool, from OID and DER encoded value */ |
|
235 extern CERTAVA * CERT_CreateAVAFromRaw(PLArenaPool *pool, |
|
236 const SECItem * OID, const SECItem * value); |
|
237 |
|
238 /* Make an AVA from binary input specified by SECItem */ |
|
239 extern CERTAVA * CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, |
|
240 int valueType, SECItem *value); |
|
241 |
|
242 /* |
|
243 * get a DPCache object for the given issuer subject and dp |
|
244 * Automatically creates the cache object if it doesn't exist yet. |
|
245 */ |
|
246 SECStatus AcquireDPCache(CERTCertificate* issuer, const SECItem* subject, |
|
247 const SECItem* dp, PRTime t, void* wincx, |
|
248 CRLDPCache** dpcache, PRBool* writeLocked); |
|
249 |
|
250 /* check if a particular SN is in the CRL cache and return its entry */ |
|
251 dpcacheStatus DPCache_Lookup(CRLDPCache* cache, const SECItem* sn, |
|
252 CERTCrlEntry** returned); |
|
253 |
|
254 /* release a DPCache object that was previously acquired */ |
|
255 void ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked); |
|
256 |
|
257 /* |
|
258 * map Stan errors into NSS errors |
|
259 * This function examines the stan error stack and automatically sets |
|
260 * PORT_SetError(); to the appropriate SEC_ERROR value. |
|
261 */ |
|
262 void CERT_MapStanError(); |
|
263 |
|
264 /* Like CERT_VerifyCert, except with an additional argument, flags. The |
|
265 * flags are defined immediately below. |
|
266 */ |
|
267 SECStatus |
|
268 cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert, |
|
269 PRBool checkSig, SECCertUsage certUsage, PRTime t, |
|
270 PRUint32 flags, void *wincx, CERTVerifyLog *log); |
|
271 |
|
272 /* Use the default settings. |
|
273 * cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS, ...) is |
|
274 * equivalent to CERT_VerifyCert(...); |
|
275 */ |
|
276 #define CERT_VERIFYCERT_USE_DEFAULTS 0 |
|
277 |
|
278 /* Skip all the OCSP checks during certificate verification, regardless of |
|
279 * the global OCSP settings. By default, certificate |cert| will have its |
|
280 * revocation status checked via OCSP according to the global OCSP settings. |
|
281 * |
|
282 * OCSP checking is always skipped when certUsage is certUsageStatusResponder. |
|
283 */ |
|
284 #define CERT_VERIFYCERT_SKIP_OCSP 1 |
|
285 |
|
286 /* Interface function for libpkix cert validation engine: |
|
287 * cert_verify wrapper. */ |
|
288 SECStatus |
|
289 cert_VerifyCertChainPkix(CERTCertificate *cert, |
|
290 PRBool checkSig, |
|
291 SECCertUsage requiredUsage, |
|
292 PRTime time, |
|
293 void *wincx, |
|
294 CERTVerifyLog *log, |
|
295 PRBool *sigError, |
|
296 PRBool *revoked); |
|
297 |
|
298 SECStatus cert_InitLocks(void); |
|
299 |
|
300 SECStatus cert_DestroyLocks(void); |
|
301 |
|
302 /* |
|
303 * fill in nsCertType field of the cert based on the cert extension |
|
304 */ |
|
305 extern SECStatus cert_GetCertType(CERTCertificate *cert); |
|
306 |
|
307 /* |
|
308 * compute and return the value of nsCertType for cert, but do not |
|
309 * update the CERTCertificate. |
|
310 */ |
|
311 extern PRUint32 cert_ComputeCertType(CERTCertificate *cert); |
|
312 |
|
313 void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert, |
|
314 long errorCode, unsigned int depth, |
|
315 void *arg); |
|
316 |
|
317 /* Insert a DER CRL into the CRL cache, and take ownership of it. |
|
318 * |
|
319 * cert_CacheCRLByGeneralName takes ownership of the memory in crl argument |
|
320 * completely. crl must be freeable by SECITEM_FreeItem. It will be freed |
|
321 * immediately if it is rejected from the CRL cache, or later during cache |
|
322 * updates when a new crl is available, or at shutdown time. |
|
323 * |
|
324 * canonicalizedName represents the source of the CRL, a GeneralName. |
|
325 * The format of the encoding is not restricted, but all callers of |
|
326 * cert_CacheCRLByGeneralName and cert_FindCRLByGeneralName must use |
|
327 * the same encoding. To facilitate X.500 name matching, a canonicalized |
|
328 * encoding of the GeneralName should be used, if available. |
|
329 */ |
|
330 |
|
331 SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl, |
|
332 const SECItem* canonicalizedName); |
|
333 |
|
334 struct NamedCRLCacheStr { |
|
335 PRLock* lock; |
|
336 PLHashTable* entries; |
|
337 }; |
|
338 |
|
339 /* NamedCRLCacheEntryStr is filled in by cert_CacheCRLByGeneralName, |
|
340 * and read by cert_FindCRLByGeneralName */ |
|
341 struct NamedCRLCacheEntryStr { |
|
342 SECItem* canonicalizedName; |
|
343 SECItem* crl; /* DER, kept only if CRL |
|
344 * is successfully cached */ |
|
345 PRBool inCRLCache; |
|
346 PRTime successfulInsertionTime; /* insertion time */ |
|
347 PRTime lastAttemptTime; /* time of last call to |
|
348 cert_CacheCRLByGeneralName with this name */ |
|
349 PRBool badDER; /* ASN.1 error */ |
|
350 PRBool dupe; /* matching DER CRL already in CRL cache */ |
|
351 PRBool unsupported; /* IDP, delta, any other reason */ |
|
352 }; |
|
353 |
|
354 typedef enum { |
|
355 certRevocationStatusRevoked = 0, |
|
356 certRevocationStatusValid = 1, |
|
357 certRevocationStatusUnknown = 2 |
|
358 } CERTRevocationStatus; |
|
359 |
|
360 /* Returns detailed status of the cert(revStatus variable). Tells if |
|
361 * issuer cache has OriginFetchedWithTimeout crl in it. */ |
|
362 SECStatus |
|
363 cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer, |
|
364 const SECItem* dp, PRTime t, void *wincx, |
|
365 CERTRevocationStatus *revStatus, |
|
366 CERTCRLEntryReasonCode *revReason); |
|
367 |
|
368 |
|
369 SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned); |
|
370 |
|
371 /* cert_FindCRLByGeneralName must be called only while the named cache is |
|
372 * acquired, and the entry is only valid until cache is released. |
|
373 */ |
|
374 SECStatus cert_FindCRLByGeneralName(NamedCRLCache* ncc, |
|
375 const SECItem* canonicalizedName, |
|
376 NamedCRLCacheEntry** retEntry); |
|
377 |
|
378 SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc); |
|
379 |
|
380 /* This is private for now. Maybe shoule be public. */ |
|
381 CERTGeneralName * |
|
382 cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena); |
|
383 |
|
384 /* Count DNS names and IP addresses in a list of GeneralNames */ |
|
385 PRUint32 |
|
386 cert_CountDNSPatterns(CERTGeneralName *firstName); |
|
387 |
|
388 /* |
|
389 * returns the trust status of the leaf certificate based on usage. |
|
390 * If the leaf is explicitly untrusted, this function will fail and |
|
391 * failedFlags will be set to the trust bit value that lead to the failure. |
|
392 * If the leaf is trusted, isTrusted is set to true and the function returns |
|
393 * SECSuccess. This function does not check if the cert is fit for a |
|
394 * particular usage. |
|
395 */ |
|
396 SECStatus |
|
397 cert_CheckLeafTrust(CERTCertificate *cert, |
|
398 SECCertUsage usage, |
|
399 unsigned int *failedFlags, |
|
400 PRBool *isTrusted); |
|
401 |
|
402 #endif /* _CERTI_H_ */ |
|
403 |