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 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
|
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Private header defining OCSP types.
*
* $Id: ocspti.h,v 1.5 2004/04/25 15:03:03 gerv%gerv.net 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_successful = 0,
ocspResponse_malformedRequest = 1,
ocspResponse_internalError = 2,
ocspResponse_tryLater = 3,
ocspResponse_unused = 4,
ocspResponse_sigRequired = 5,
ocspResponse_unauthorized = 6,
ocspResponse_other /* unknown/unrecognized value */
} 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 {
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;
};
/*
* A ResponderID identifies the responder -- or more correctly, the
* signer of the response. The ASN.1 definition of a ResponderID is:
*
* ResponderID ::= CHOICE {
* byName [1] EXPLICIT Name,
* byKey [2] EXPLICIT KeyHash }
*
* Because it is CHOICE, the type of identification used and the
* identification itself 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 {
ocspResponderID_byName,
ocspResponderID_byKey,
ocspResponderID_other /* unknown kind of responderID */
} ocspResponderIDType;
struct ocspResponderIDStr {
ocspResponderIDType 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_ */
|