tor-browser

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

ocspti.h (14282B)


      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 /*
      6 * Private header defining OCSP types.
      7 */
      8 
      9 #ifndef _OCSPTI_H_
     10 #define _OCSPTI_H_
     11 
     12 #include "ocspt.h"
     13 
     14 #include "certt.h"
     15 #include "plarena.h"
     16 #include "seccomon.h"
     17 #include "secoidt.h"
     18 
     19 /*
     20 * Some notes about naming conventions...
     21 *
     22 * The public data types all start with "CERTOCSP" (e.g. CERTOCSPRequest).
     23 * (Even the public types are opaque, however.  Only their names are
     24 * "exported".)
     25 *
     26 * Internal-only data types drop the "CERT" prefix and use only the
     27 * lower-case "ocsp" (e.g. ocspTBSRequest), for brevity sake.
     28 *
     29 * In either case, the base/suffix of the type name usually matches the
     30 * name as defined in the OCSP specification.  The exceptions to this are:
     31 *  - When there is overlap between the "OCSP" or "ocsp" prefix and
     32 *    the name used in the standard.  That is, you cannot strip off the
     33 *    "CERTOCSP" or "ocsp" prefix and necessarily get the name of the
     34 *    type as it is defined in the standard; the "real" name will be
     35 *    *either* "OCSPSuffix" or just "Suffix".
     36 *  - When the name in the standard was a little too generic.  (e.g. The
     37 *    standard defines "Request" but we call it a "SingleRequest".)
     38 *    In this case a comment above the type definition calls attention
     39 *    to the difference.
     40 *
     41 * The definitions laid out in this header file are intended to follow
     42 * the same order as the definitions in the OCSP specification itself.
     43 * With the OCSP standard in hand, you should be able to move through
     44 * this file and follow along.  To future modifiers of this file: please
     45 * try to keep it that way.  The only exceptions are the few cases where
     46 * we need to define a type before it is referenced (e.g. enumerations),
     47 * whereas in the OCSP specification these are usually defined the other
     48 * way around (reference before definition).
     49 */
     50 
     51 /*
     52 * Forward-declarations of internal-only data structures.
     53 *
     54 * These are in alphabetical order (case-insensitive); please keep it that way!
     55 */
     56 typedef struct ocspBasicOCSPResponseStr ocspBasicOCSPResponse;
     57 typedef struct ocspCertStatusStr ocspCertStatus;
     58 typedef struct ocspResponderIDStr ocspResponderID;
     59 typedef struct ocspResponseBytesStr ocspResponseBytes;
     60 typedef struct ocspResponseDataStr ocspResponseData;
     61 typedef struct ocspRevokedInfoStr ocspRevokedInfo;
     62 typedef struct ocspServiceLocatorStr ocspServiceLocator;
     63 typedef struct ocspSignatureStr ocspSignature;
     64 typedef struct ocspSingleRequestStr ocspSingleRequest;
     65 typedef struct ocspSingleResponseStr ocspSingleResponse;
     66 typedef struct ocspTBSRequestStr ocspTBSRequest;
     67 
     68 /*
     69 * An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
     70 */
     71 struct CERTOCSPRequestStr {
     72    PLArenaPool *arena; /* local; not part of encoding */
     73    ocspTBSRequest *tbsRequest;
     74    ocspSignature *optionalSignature;
     75 };
     76 
     77 /*
     78 * A TBSRequest; when an OCSPRequest is signed, the encoding of this
     79 * is what the signature is actually applied to.  ("TBS" == To Be Signed)
     80 * Whether signed or not, however, this structure will be present, and
     81 * is the "meat" of the OCSPRequest.
     82 *
     83 * Note that the "requestorName" field cannot be encoded/decoded in the
     84 * same pass as the entire request -- it needs to be handled with a special
     85 * call to convert to/from our internal form of a GeneralName.  Thus the
     86 * "derRequestorName" field, which is the actual DER-encoded bytes.
     87 *
     88 * The "extensionHandle" field is used on creation only; it holds
     89 * in-progress extensions as they are optionally added to the request.
     90 */
     91 struct ocspTBSRequestStr {
     92    SECItem version;                    /* an INTEGER */
     93    SECItem *derRequestorName;          /* encoded GeneralName; see above */
     94    CERTGeneralNameList *requestorName; /* local; not part of encoding */
     95    ocspSingleRequest **requestList;
     96    CERTCertExtension **requestExtensions;
     97    void *extensionHandle; /* local; not part of encoding */
     98 };
     99 
    100 /*
    101 * This is the actual signature information for an OCSPRequest (applied to
    102 * the TBSRequest structure) or for a BasicOCSPResponse (applied to a
    103 * ResponseData structure).
    104 *
    105 * Note that the "signature" field itself is a BIT STRING; operations on
    106 * it need to keep that in mind, converting the length to bytes as needed
    107 * and back again afterward (so that the length is usually expressing bits).
    108 *
    109 * The "cert" field is the signer's certificate.  In the case of a received
    110 * signature, it will be filled in when the signature is verified.  In the
    111 * case of a created signature, it is filled in on creation and will be the
    112 * cert used to create the signature when the signing-and-encoding occurs,
    113 * as well as the cert (and its chain) to fill in derCerts if requested.
    114 *
    115 * The extra fields cache information about the signature after we have
    116 * attempted a verification.  "wasChecked", if true, means the signature
    117 * has been checked against the appropriate data and thus that "status"
    118 * contains the result of that verification.  If "status" is not SECSuccess,
    119 * "failureReason" is a copy of the error code that was set at the time;
    120 * presumably it tells why the signature verification failed.
    121 */
    122 struct ocspSignatureStr {
    123    SECAlgorithmID signatureAlgorithm;
    124    SECItem signature;     /* a BIT STRING */
    125    SECItem **derCerts;    /* a SEQUENCE OF Certificate */
    126    CERTCertificate *cert; /* local; not part of encoding */
    127    PRBool wasChecked;     /* local; not part of encoding */
    128    SECStatus status;      /* local; not part of encoding */
    129    int failureReason;     /* local; not part of encoding */
    130 };
    131 
    132 /*
    133 * An OCSPRequest contains a SEQUENCE OF these, one for each certificate
    134 * whose status is being checked.
    135 *
    136 * Note that in the OCSP specification this is just called "Request",
    137 * but since that seemed confusing (vs. an OCSPRequest) and to be more
    138 * consistent with the parallel type "SingleResponse", I called it a
    139 * "SingleRequest".
    140 *
    141 * XXX figure out how to get rid of that arena -- there must be a way
    142 */
    143 struct ocspSingleRequestStr {
    144    PLArenaPool *arena; /* just a copy of the response arena,
    145                         * needed here for extension handling
    146                         * routines, on creation only */
    147    CERTOCSPCertID *reqCert;
    148    CERTCertExtension **singleRequestExtensions;
    149 };
    150 
    151 /*
    152 * A CertID is the means of identifying a certificate, used both in requests
    153 * and in responses.
    154 *
    155 * When in a SingleRequest it specifies the certificate to be checked.
    156 * When in a SingleResponse it is the cert whose status is being given.
    157 */
    158 struct CERTOCSPCertIDStr {
    159    SECAlgorithmID hashAlgorithm;
    160    SECItem issuerNameHash;     /* an OCTET STRING */
    161    SECItem issuerKeyHash;      /* an OCTET STRING */
    162    SECItem serialNumber;       /* an INTEGER */
    163    SECItem issuerSHA1NameHash; /* keep other hashes around when */
    164    SECItem issuerMD5NameHash;  /* we have them */
    165    SECItem issuerMD2NameHash;
    166    SECItem issuerSHA1KeyHash; /* keep other hashes around when */
    167    SECItem issuerMD5KeyHash;  /* we have them */
    168    SECItem issuerMD2KeyHash;
    169    PLArenaPool *poolp;
    170 };
    171 
    172 /*
    173 * This describes the value of the responseStatus field in an OCSPResponse.
    174 * The corresponding ASN.1 definition is:
    175 *
    176 * OCSPResponseStatus	::=	ENUMERATED {
    177 *	successful		(0),	--Response has valid confirmations
    178 *	malformedRequest	(1),	--Illegal confirmation request
    179 *	internalError		(2),	--Internal error in issuer
    180 *	tryLater		(3),	--Try again later
    181 *					--(4) is not used
    182 *	sigRequired		(5),	--Must sign the request
    183 *	unauthorized		(6),	--Request unauthorized
    184 * }
    185 */
    186 typedef enum {
    187    ocspResponse_min = 0,
    188    ocspResponse_successful = 0,
    189    ocspResponse_malformedRequest = 1,
    190    ocspResponse_internalError = 2,
    191    ocspResponse_tryLater = 3,
    192    ocspResponse_unused = 4,
    193    ocspResponse_sigRequired = 5,
    194    ocspResponse_unauthorized = 6,
    195    ocspResponse_max = 6 /* Please update max when adding values.
    196                          * Remember to also update arrays, e.g.
    197                          * "responseStatusNames" in ocspclnt.c
    198                          * and potentially other places. */
    199 } ocspResponseStatus;
    200 
    201 /*
    202 * An OCSPResponse is what is sent (encoded) by an OCSP responder.
    203 *
    204 * The field "responseStatus" is the ASN.1 encoded value; the field
    205 * "statusValue" is simply that same value translated into our local
    206 * type ocspResponseStatus.
    207 */
    208 struct CERTOCSPResponseStr {
    209    PLArenaPool *arena;               /* local; not part of encoding */
    210    SECItem responseStatus;           /* an ENUMERATED, see above */
    211    ocspResponseStatus statusValue;   /* local; not part of encoding */
    212    ocspResponseBytes *responseBytes; /* only when status is successful */
    213 };
    214 
    215 /*
    216 * A ResponseBytes (despite appearances) is what contains the meat
    217 * of a successful response -- but still in encoded form.  The type
    218 * given as "responseType" tells you how to decode the string.
    219 *
    220 * We look at the OID and translate it into our local OID representation
    221 * "responseTypeTag", and use that value to tell us how to decode the
    222 * actual response itself.  For now the only kind of OCSP response we
    223 * know about is a BasicOCSPResponse.  However, the intention in the
    224 * OCSP specification is to allow for other response types, so we are
    225 * building in that flexibility from the start and thus put a pointer
    226 * to that data structure inside of a union.  Whenever OCSP adds more
    227 * response types, just add them to the union.
    228 */
    229 struct ocspResponseBytesStr {
    230    SECItem responseType;      /* an OBJECT IDENTIFIER */
    231    SECOidTag responseTypeTag; /* local; not part of encoding */
    232    SECItem response;          /* an OCTET STRING */
    233    union {
    234        ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
    235    } decodedResponse;                /* local; not part of encoding */
    236 };
    237 
    238 /*
    239 * A BasicOCSPResponse -- when the responseType in a ResponseBytes is
    240 * id-pkix-ocsp-basic, the "response" OCTET STRING above is the DER
    241 * encoding of one of these.
    242 *
    243 * Note that in the OCSP specification, the signature fields are not
    244 * part of a separate sub-structure.  But since they are the same fields
    245 * as we define for the signature in a request, it made sense to share
    246 * the C data structure here and in some shared code to operate on them.
    247 */
    248 struct ocspBasicOCSPResponseStr {
    249    SECItem tbsResponseDataDER;
    250    ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
    251    ocspSignature responseSignature;
    252 };
    253 
    254 /*
    255 * A ResponseData is the part of a BasicOCSPResponse that is signed
    256 * (after it is DER encoded).  It contains the real details of the response
    257 * (a per-certificate status).
    258 */
    259 struct ocspResponseDataStr {
    260    SECItem version; /* an INTEGER */
    261    SECItem derResponderID;
    262    ocspResponderID *responderID; /* local; not part of encoding */
    263    SECItem producedAt;           /* a GeneralizedTime */
    264    CERTOCSPSingleResponse **responses;
    265    CERTCertExtension **responseExtensions;
    266 };
    267 
    268 struct ocspResponderIDStr {
    269    CERTOCSPResponderIDType responderIDType; /* local; not part of encoding */
    270    union {
    271        CERTName name;   /* when ocspResponderID_byName */
    272        SECItem keyHash; /* when ocspResponderID_byKey */
    273        SECItem other;   /* when ocspResponderID_other */
    274    } responderIDValue;
    275 };
    276 
    277 /*
    278 * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
    279 * SingleResponse -- one for each certificate whose status is being supplied.
    280 *
    281 * XXX figure out how to get rid of that arena -- there must be a way
    282 */
    283 struct CERTOCSPSingleResponseStr {
    284    PLArenaPool *arena; /* just a copy of the response arena,
    285                         * needed here for extension handling
    286                         * routines, on creation only */
    287    CERTOCSPCertID *certID;
    288    SECItem derCertStatus;
    289    ocspCertStatus *certStatus; /* local; not part of encoding */
    290    SECItem thisUpdate;         /* a GeneralizedTime */
    291    SECItem *nextUpdate;        /* a GeneralizedTime */
    292    CERTCertExtension **singleExtensions;
    293 };
    294 
    295 /*
    296 * A CertStatus is the actual per-certificate status.  Its ASN.1 definition:
    297 *
    298 * CertStatus	::=	CHOICE {
    299 *	good			[0] IMPLICIT NULL,
    300 *	revoked			[1] IMPLICIT RevokedInfo,
    301 *	unknown			[2] IMPLICIT UnknownInfo }
    302 *
    303 * (where for now UnknownInfo is defined to be NULL but in the
    304 * future may be replaced with an enumeration).
    305 *
    306 * Because it is CHOICE, the status value and its associated information
    307 * (if any) are actually encoded together.  To represent this same
    308 * information internally, we explicitly define a type and save it,
    309 * along with the value, into a data structure.
    310 */
    311 
    312 typedef enum {
    313    ocspCertStatus_good,    /* cert is not revoked */
    314    ocspCertStatus_revoked, /* cert is revoked */
    315    ocspCertStatus_unknown, /* cert was unknown to the responder */
    316    ocspCertStatus_other    /* status was not an expected value */
    317 } ocspCertStatusType;
    318 
    319 /*
    320 * This is the actual per-certificate status.
    321 *
    322 * The "goodInfo" and "unknownInfo" items are only place-holders for a NULL.
    323 * (Though someday OCSP may replace UnknownInfo with an enumeration that
    324 * gives more detailed information.)
    325 */
    326 struct ocspCertStatusStr {
    327    ocspCertStatusType certStatusType; /* local; not part of encoding */
    328    union {
    329        SECItem *goodInfo;            /* when ocspCertStatus_good */
    330        ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
    331        SECItem *unknownInfo;         /* when ocspCertStatus_unknown */
    332        SECItem *otherInfo;           /* when ocspCertStatus_other */
    333    } certStatusInfo;
    334 };
    335 
    336 /*
    337 * A RevokedInfo gives information about a revoked certificate -- when it
    338 * was revoked and why.
    339 */
    340 struct ocspRevokedInfoStr {
    341    SECItem revocationTime;    /* a GeneralizedTime */
    342    SECItem *revocationReason; /* a CRLReason; ignored for now */
    343 };
    344 
    345 /*
    346 * ServiceLocator can be included as one of the singleRequestExtensions.
    347 * When added, it specifies the (name of the) issuer of the cert being
    348 * checked, and optionally the value of the AuthorityInfoAccess extension
    349 * if the cert has one.
    350 */
    351 struct ocspServiceLocatorStr {
    352    CERTName *issuer;
    353    SECItem locator; /* DER encoded authInfoAccess extension from cert */
    354 };
    355 
    356 #endif /* _OCSPTI_H_ */