DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Untracked file

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Private header defining OCSP types.
 *
 * $Id: ocspti.h,v 1.11 2013/01/23 23:05:51 kaie%kuix.de Exp $
 */

#ifndef _OCSPTI_H_
#define _OCSPTI_H_

#include "ocspt.h"

#include "certt.h"
#include "plarena.h"
#include "seccomon.h"
#include "secoidt.h"


/*
 * Some notes about naming conventions...
 *
 * The public data types all start with "CERTOCSP" (e.g. CERTOCSPRequest).
 * (Even the public types are opaque, however.  Only their names are
 * "exported".)
 *
 * Internal-only data types drop the "CERT" prefix and use only the
 * lower-case "ocsp" (e.g. ocspTBSRequest), for brevity sake.
 *
 * In either case, the base/suffix of the type name usually matches the
 * name as defined in the OCSP specification.  The exceptions to this are:
 *  - When there is overlap between the "OCSP" or "ocsp" prefix and
 *    the name used in the standard.  That is, you cannot strip off the
 *    "CERTOCSP" or "ocsp" prefix and necessarily get the name of the
 *    type as it is defined in the standard; the "real" name will be
 *    *either* "OCSPSuffix" or just "Suffix".
 *  - When the name in the standard was a little too generic.  (e.g. The
 *    standard defines "Request" but we call it a "SingleRequest".)
 *    In this case a comment above the type definition calls attention
 *    to the difference.
 *
 * The definitions laid out in this header file are intended to follow
 * the same order as the definitions in the OCSP specification itself.
 * With the OCSP standard in hand, you should be able to move through
 * this file and follow along.  To future modifiers of this file: please
 * try to keep it that way.  The only exceptions are the few cases where
 * we need to define a type before it is referenced (e.g. enumerations),
 * whereas in the OCSP specification these are usually defined the other
 * way around (reference before definition).
 */


/*
 * Forward-declarations of internal-only data structures.
 *
 * These are in alphabetical order (case-insensitive); please keep it that way!
 */
typedef struct ocspBasicOCSPResponseStr ocspBasicOCSPResponse;
typedef struct ocspCertStatusStr ocspCertStatus;
typedef struct ocspResponderIDStr ocspResponderID;
typedef struct ocspResponseBytesStr ocspResponseBytes;
typedef struct ocspResponseDataStr ocspResponseData;
typedef struct ocspRevokedInfoStr ocspRevokedInfo;
typedef struct ocspServiceLocatorStr ocspServiceLocator;
typedef struct ocspSignatureStr ocspSignature;
typedef struct ocspSingleRequestStr ocspSingleRequest;
typedef struct ocspSingleResponseStr ocspSingleResponse;
typedef struct ocspTBSRequestStr ocspTBSRequest;


/*
 * An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
 */
struct CERTOCSPRequestStr {
    PRArenaPool *arena;			/* local; not part of encoding */
    ocspTBSRequest *tbsRequest;
    ocspSignature *optionalSignature;
};

/*
 * A TBSRequest; when an OCSPRequest is signed, the encoding of this
 * is what the signature is actually applied to.  ("TBS" == To Be Signed)
 * Whether signed or not, however, this structure will be present, and
 * is the "meat" of the OCSPRequest.
 *
 * Note that the "requestorName" field cannot be encoded/decoded in the
 * same pass as the entire request -- it needs to be handled with a special
 * call to convert to/from our internal form of a GeneralName.  Thus the
 * "derRequestorName" field, which is the actual DER-encoded bytes.
 *
 * The "extensionHandle" field is used on creation only; it holds
 * in-progress extensions as they are optionally added to the request.
 */
struct ocspTBSRequestStr {
    SECItem version;			/* an INTEGER */
    SECItem *derRequestorName;		/* encoded GeneralName; see above */
    CERTGeneralNameList *requestorName;	/* local; not part of encoding */
    ocspSingleRequest **requestList;
    CERTCertExtension **requestExtensions;
    void *extensionHandle;		/* local; not part of encoding */
};

/*
 * This is the actual signature information for an OCSPRequest (applied to
 * the TBSRequest structure) or for a BasicOCSPResponse (applied to a
 * ResponseData structure).
 *
 * Note that the "signature" field itself is a BIT STRING; operations on
 * it need to keep that in mind, converting the length to bytes as needed
 * and back again afterward (so that the length is usually expressing bits).
 *
 * The "cert" field is the signer's certificate.  In the case of a received
 * signature, it will be filled in when the signature is verified.  In the
 * case of a created signature, it is filled in on creation and will be the
 * cert used to create the signature when the signing-and-encoding occurs,
 * as well as the cert (and its chain) to fill in derCerts if requested.
 *
 * The extra fields cache information about the signature after we have
 * attempted a verification.  "wasChecked", if true, means the signature
 * has been checked against the appropriate data and thus that "status"
 * contains the result of that verification.  If "status" is not SECSuccess,
 * "failureReason" is a copy of the error code that was set at the time;
 * presumably it tells why the signature verification failed.
 */
struct ocspSignatureStr {
    SECAlgorithmID signatureAlgorithm;
    SECItem signature;			/* a BIT STRING */
    SECItem **derCerts;			/* a SEQUENCE OF Certificate */
    CERTCertificate *cert;		/* local; not part of encoding */
    PRBool wasChecked;			/* local; not part of encoding */
    SECStatus status;			/* local; not part of encoding */
    int failureReason;			/* local; not part of encoding */
};

/*
 * An OCSPRequest contains a SEQUENCE OF these, one for each certificate
 * whose status is being checked.
 *
 * Note that in the OCSP specification this is just called "Request",
 * but since that seemed confusing (vs. an OCSPRequest) and to be more
 * consistent with the parallel type "SingleResponse", I called it a
 * "SingleRequest".
 * 
 * XXX figure out how to get rid of that arena -- there must be a way
 */
struct ocspSingleRequestStr {
    PRArenaPool *arena;			/* just a copy of the response arena,
					 * needed here for extension handling
					 * routines, on creation only */
    CERTOCSPCertID *reqCert;
    CERTCertExtension **singleRequestExtensions;
};

/*
 * A CertID is the means of identifying a certificate, used both in requests
 * and in responses.
 *
 * When in a SingleRequest it specifies the certificate to be checked.
 * When in a SingleResponse it is the cert whose status is being given.
 */
struct CERTOCSPCertIDStr {
    SECAlgorithmID hashAlgorithm;
    SECItem issuerNameHash;		/* an OCTET STRING */
    SECItem issuerKeyHash;		/* an OCTET STRING */
    SECItem serialNumber;		/* an INTEGER */
    SECItem issuerSHA1NameHash;		/* keep other hashes around when */
    SECItem issuerMD5NameHash;              /* we have them */
    SECItem issuerMD2NameHash;
    SECItem issuerSHA1KeyHash;		/* keep other hashes around when */
    SECItem issuerMD5KeyHash;              /* we have them */
    SECItem issuerMD2KeyHash;
    PRArenaPool *poolp;
};

/*
 * This describes the value of the responseStatus field in an OCSPResponse.
 * The corresponding ASN.1 definition is:
 *
 * OCSPResponseStatus	::=	ENUMERATED {
 *	successful		(0),	--Response has valid confirmations
 *	malformedRequest	(1),	--Illegal confirmation request
 *	internalError		(2),	--Internal error in issuer
 *	tryLater		(3),	--Try again later
 *					--(4) is not used
 *	sigRequired		(5),	--Must sign the request
 *	unauthorized		(6),	--Request unauthorized
 * }
 */
typedef enum {
    ocspResponse_min = 0,
    ocspResponse_successful = 0,
    ocspResponse_malformedRequest = 1,
    ocspResponse_internalError = 2,
    ocspResponse_tryLater = 3,
    ocspResponse_unused = 4,
    ocspResponse_sigRequired = 5,
    ocspResponse_unauthorized = 6,
    ocspResponse_max = 6 /* Please update max when adding values.
                          * Remember to also update arrays, e.g.
                          * "responseStatusNames" in ocspclnt.c
                          * and potentially other places. */
} ocspResponseStatus;

/*
 * An OCSPResponse is what is sent (encoded) by an OCSP responder.
 *
 * The field "responseStatus" is the ASN.1 encoded value; the field
 * "statusValue" is simply that same value translated into our local
 * type ocspResponseStatus.
 */
struct CERTOCSPResponseStr {
    PRArenaPool *arena;			/* local; not part of encoding */
    SECItem responseStatus;		/* an ENUMERATED, see above */
    ocspResponseStatus statusValue;	/* local; not part of encoding */
    ocspResponseBytes *responseBytes;	/* only when status is successful */
};

/*
 * A ResponseBytes (despite appearances) is what contains the meat
 * of a successful response -- but still in encoded form.  The type
 * given as "responseType" tells you how to decode the string.
 *
 * We look at the OID and translate it into our local OID representation
 * "responseTypeTag", and use that value to tell us how to decode the
 * actual response itself.  For now the only kind of OCSP response we
 * know about is a BasicOCSPResponse.  However, the intention in the
 * OCSP specification is to allow for other response types, so we are
 * building in that flexibility from the start and thus put a pointer
 * to that data structure inside of a union.  Whenever OCSP adds more
 * response types, just add them to the union.
 */
struct ocspResponseBytesStr {
    SECItem responseType;		/* an OBJECT IDENTIFIER */
    SECOidTag responseTypeTag;		/* local; not part of encoding */
    SECItem response;			/* an OCTET STRING */
    union {
	ocspBasicOCSPResponse *basic;	/* when type is id-pkix-ocsp-basic */
    } decodedResponse;			/* local; not part of encoding */
};

/*
 * A BasicOCSPResponse -- when the responseType in a ResponseBytes is
 * id-pkix-ocsp-basic, the "response" OCTET STRING above is the DER
 * encoding of one of these.
 *
 * Note that in the OCSP specification, the signature fields are not
 * part of a separate sub-structure.  But since they are the same fields
 * as we define for the signature in a request, it made sense to share
 * the C data structure here and in some shared code to operate on them.
 */
struct ocspBasicOCSPResponseStr {
    SECItem tbsResponseDataDER;
    ocspResponseData *tbsResponseData;	/* "tbs" == To Be Signed */
    ocspSignature responseSignature;
};

/*
 * A ResponseData is the part of a BasicOCSPResponse that is signed
 * (after it is DER encoded).  It contains the real details of the response
 * (a per-certificate status).
 */
struct ocspResponseDataStr {
    SECItem version;			/* an INTEGER */
    SECItem derResponderID;
    ocspResponderID *responderID;	/* local; not part of encoding */
    SECItem producedAt;			/* a GeneralizedTime */
    CERTOCSPSingleResponse **responses;
    CERTCertExtension **responseExtensions;
};

struct ocspResponderIDStr {
    CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */
    union {
	CERTName name;			/* when ocspResponderID_byName */
	SECItem keyHash;		/* when ocspResponderID_byKey */
	SECItem other;			/* when ocspResponderID_other */
    } responderIDValue;
};

/*
 * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
 * SingleResponse -- one for each certificate whose status is being supplied.
 * 
 * XXX figure out how to get rid of that arena -- there must be a way
 */
struct CERTOCSPSingleResponseStr {
    PRArenaPool *arena;			/* just a copy of the response arena,
					 * needed here for extension handling
					 * routines, on creation only */
    CERTOCSPCertID *certID;
    SECItem derCertStatus;
    ocspCertStatus *certStatus;		/* local; not part of encoding */
    SECItem thisUpdate;			/* a GeneralizedTime */
    SECItem *nextUpdate;		/* a GeneralizedTime */
    CERTCertExtension **singleExtensions;
};

/*
 * A CertStatus is the actual per-certificate status.  Its ASN.1 definition:
 *
 * CertStatus	::=	CHOICE {
 *	good			[0] IMPLICIT NULL,
 *	revoked			[1] IMPLICIT RevokedInfo,
 *	unknown			[2] IMPLICIT UnknownInfo }
 *
 * (where for now UnknownInfo is defined to be NULL but in the
 * future may be replaced with an enumeration).
 *
 * Because it is CHOICE, the status value and its associated information
 * (if any) are actually encoded together.  To represent this same
 * information internally, we explicitly define a type and save it,
 * along with the value, into a data structure.
 */

typedef enum {
    ocspCertStatus_good,		/* cert is not revoked */
    ocspCertStatus_revoked,		/* cert is revoked */
    ocspCertStatus_unknown,		/* cert was unknown to the responder */
    ocspCertStatus_other		/* status was not an expected value */
} ocspCertStatusType;

/*
 * This is the actual per-certificate status.
 *
 * The "goodInfo" and "unknownInfo" items are only place-holders for a NULL.
 * (Though someday OCSP may replace UnknownInfo with an enumeration that
 * gives more detailed information.)
 */
struct ocspCertStatusStr {
    ocspCertStatusType certStatusType;	/* local; not part of encoding */
    union {
	SECItem *goodInfo;		/* when ocspCertStatus_good */
	ocspRevokedInfo *revokedInfo;	/* when ocspCertStatus_revoked */
	SECItem *unknownInfo;		/* when ocspCertStatus_unknown */
	SECItem *otherInfo;		/* when ocspCertStatus_other */
    } certStatusInfo; 
};

/*
 * A RevokedInfo gives information about a revoked certificate -- when it
 * was revoked and why.
 */
struct ocspRevokedInfoStr {
    SECItem revocationTime;		/* a GeneralizedTime */
    SECItem *revocationReason;		/* a CRLReason; ignored for now */
};

/*
 * ServiceLocator can be included as one of the singleRequestExtensions.
 * When added, it specifies the (name of the) issuer of the cert being
 * checked, and optionally the value of the AuthorityInfoAccess extension
 * if the cert has one.
 */
struct ocspServiceLocatorStr {
    CERTName *issuer;
    SECItem locator;	/* DER encoded authInfoAccess extension from cert */
};

#endif /* _OCSPTI_H_ */