tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

certi.h (15574B)


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