security/nss/lib/certdb/certi.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial