Back to index

lightning-sunbird  0.9+nobinonly
ocspti.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038  * Private header defining OCSP types.
00039  *
00040  * $Id: ocspti.h,v 1.5 2004/04/25 15:03:03 gerv%gerv.net Exp $
00041  */
00042 
00043 #ifndef _OCSPTI_H_
00044 #define _OCSPTI_H_
00045 
00046 #include "ocspt.h"
00047 
00048 #include "certt.h"
00049 #include "plarena.h"
00050 #include "seccomon.h"
00051 #include "secoidt.h"
00052 
00053 
00054 /*
00055  * Some notes about naming conventions...
00056  *
00057  * The public data types all start with "CERTOCSP" (e.g. CERTOCSPRequest).
00058  * (Even the public types are opaque, however.  Only their names are
00059  * "exported".)
00060  *
00061  * Internal-only data types drop the "CERT" prefix and use only the
00062  * lower-case "ocsp" (e.g. ocspTBSRequest), for brevity sake.
00063  *
00064  * In either case, the base/suffix of the type name usually matches the
00065  * name as defined in the OCSP specification.  The exceptions to this are:
00066  *  - When there is overlap between the "OCSP" or "ocsp" prefix and
00067  *    the name used in the standard.  That is, you cannot strip off the
00068  *    "CERTOCSP" or "ocsp" prefix and necessarily get the name of the
00069  *    type as it is defined in the standard; the "real" name will be
00070  *    *either* "OCSPSuffix" or just "Suffix".
00071  *  - When the name in the standard was a little too generic.  (e.g. The
00072  *    standard defines "Request" but we call it a "SingleRequest".)
00073  *    In this case a comment above the type definition calls attention
00074  *    to the difference.
00075  *
00076  * The definitions laid out in this header file are intended to follow
00077  * the same order as the definitions in the OCSP specification itself.
00078  * With the OCSP standard in hand, you should be able to move through
00079  * this file and follow along.  To future modifiers of this file: please
00080  * try to keep it that way.  The only exceptions are the few cases where
00081  * we need to define a type before it is referenced (e.g. enumerations),
00082  * whereas in the OCSP specification these are usually defined the other
00083  * way around (reference before definition).
00084  */
00085 
00086 
00087 /*
00088  * Forward-declarations of internal-only data structures.
00089  *
00090  * These are in alphabetical order (case-insensitive); please keep it that way!
00091  */
00092 typedef struct ocspBasicOCSPResponseStr ocspBasicOCSPResponse;
00093 typedef struct ocspCertStatusStr ocspCertStatus;
00094 typedef struct ocspResponderIDStr ocspResponderID;
00095 typedef struct ocspResponseBytesStr ocspResponseBytes;
00096 typedef struct ocspResponseDataStr ocspResponseData;
00097 typedef struct ocspRevokedInfoStr ocspRevokedInfo;
00098 typedef struct ocspServiceLocatorStr ocspServiceLocator;
00099 typedef struct ocspSignatureStr ocspSignature;
00100 typedef struct ocspSingleRequestStr ocspSingleRequest;
00101 typedef struct ocspSingleResponseStr ocspSingleResponse;
00102 typedef struct ocspTBSRequestStr ocspTBSRequest;
00103 
00104 
00105 /*
00106  * An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
00107  */
00108 struct CERTOCSPRequestStr {
00109     PRArenaPool *arena;                   /* local; not part of encoding */
00110     ocspTBSRequest *tbsRequest;
00111     ocspSignature *optionalSignature;
00112 };
00113 
00114 /*
00115  * A TBSRequest; when an OCSPRequest is signed, the encoding of this
00116  * is what the signature is actually applied to.  ("TBS" == To Be Signed)
00117  * Whether signed or not, however, this structure will be present, and
00118  * is the "meat" of the OCSPRequest.
00119  *
00120  * Note that the "requestorName" field cannot be encoded/decoded in the
00121  * same pass as the entire request -- it needs to be handled with a special
00122  * call to convert to/from our internal form of a GeneralName.  Thus the
00123  * "derRequestorName" field, which is the actual DER-encoded bytes.
00124  *
00125  * The "extensionHandle" field is used on creation only; it holds
00126  * in-progress extensions as they are optionally added to the request.
00127  */
00128 struct ocspTBSRequestStr {
00129     SECItem version;               /* an INTEGER */
00130     SECItem *derRequestorName;            /* encoded GeneralName; see above */
00131     CERTGeneralNameList *requestorName;   /* local; not part of encoding */
00132     ocspSingleRequest **requestList;
00133     CERTCertExtension **requestExtensions;
00134     void *extensionHandle;         /* local; not part of encoding */
00135 };
00136 
00137 /*
00138  * This is the actual signature information for an OCSPRequest (applied to
00139  * the TBSRequest structure) or for a BasicOCSPResponse (applied to a
00140  * ResponseData structure).
00141  *
00142  * Note that the "signature" field itself is a BIT STRING; operations on
00143  * it need to keep that in mind, converting the length to bytes as needed
00144  * and back again afterward (so that the length is usually expressing bits).
00145  *
00146  * The "cert" field is the signer's certificate.  In the case of a received
00147  * signature, it will be filled in when the signature is verified.  In the
00148  * case of a created signature, it is filled in on creation and will be the
00149  * cert used to create the signature when the signing-and-encoding occurs,
00150  * as well as the cert (and its chain) to fill in derCerts if requested.
00151  *
00152  * The extra fields cache information about the signature after we have
00153  * attempted a verification.  "wasChecked", if true, means the signature
00154  * has been checked against the appropriate data and thus that "status"
00155  * contains the result of that verification.  If "status" is not SECSuccess,
00156  * "failureReason" is a copy of the error code that was set at the time;
00157  * presumably it tells why the signature verification failed.
00158  */
00159 struct ocspSignatureStr {
00160     SECAlgorithmID signatureAlgorithm;
00161     SECItem signature;                    /* a BIT STRING */
00162     SECItem **derCerts;                   /* a SEQUENCE OF Certificate */
00163     CERTCertificate *cert;         /* local; not part of encoding */
00164     PRBool wasChecked;                    /* local; not part of encoding */
00165     SECStatus status;                     /* local; not part of encoding */
00166     int failureReason;                    /* local; not part of encoding */
00167 };
00168 
00169 /*
00170  * An OCSPRequest contains a SEQUENCE OF these, one for each certificate
00171  * whose status is being checked.
00172  *
00173  * Note that in the OCSP specification this is just called "Request",
00174  * but since that seemed confusing (vs. an OCSPRequest) and to be more
00175  * consistent with the parallel type "SingleResponse", I called it a
00176  * "SingleRequest".
00177  * 
00178  * XXX figure out how to get rid of that arena -- there must be a way
00179  */
00180 struct ocspSingleRequestStr {
00181     PRArenaPool *arena;                   /* just a copy of the response arena,
00182                                     * needed here for extension handling
00183                                     * routines, on creation only */
00184     CERTOCSPCertID *reqCert;
00185     CERTCertExtension **singleRequestExtensions;
00186 };
00187 
00188 /*
00189  * A CertID is the means of identifying a certificate, used both in requests
00190  * and in responses.
00191  *
00192  * When in a SingleRequest it specifies the certificate to be checked.
00193  * When in a SingleResponse it is the cert whose status is being given.
00194  */
00195 struct CERTOCSPCertIDStr {
00196     SECAlgorithmID hashAlgorithm;
00197     SECItem issuerNameHash;        /* an OCTET STRING */
00198     SECItem issuerKeyHash;         /* an OCTET STRING */
00199     SECItem serialNumber;          /* an INTEGER */
00200     SECItem issuerSHA1NameHash;           /* keep other hashes around when */
00201     SECItem issuerMD5NameHash;              /* we have them */
00202     SECItem issuerMD2NameHash;
00203     SECItem issuerSHA1KeyHash;            /* keep other hashes around when */
00204     SECItem issuerMD5KeyHash;              /* we have them */
00205     SECItem issuerMD2KeyHash;
00206     PRArenaPool *poolp;
00207 };
00208 
00209 /*
00210  * This describes the value of the responseStatus field in an OCSPResponse.
00211  * The corresponding ASN.1 definition is:
00212  *
00213  * OCSPResponseStatus       ::=    ENUMERATED {
00214  *     successful           (0),   --Response has valid confirmations
00215  *     malformedRequest     (1),   --Illegal confirmation request
00216  *     internalError        (2),   --Internal error in issuer
00217  *     tryLater             (3),   --Try again later
00218  *                                 --(4) is not used
00219  *     sigRequired          (5),   --Must sign the request
00220  *     unauthorized         (6),   --Request unauthorized
00221  * }
00222  */
00223 typedef enum {
00224     ocspResponse_successful = 0,
00225     ocspResponse_malformedRequest = 1,
00226     ocspResponse_internalError = 2,
00227     ocspResponse_tryLater = 3,
00228     ocspResponse_unused = 4,
00229     ocspResponse_sigRequired = 5,
00230     ocspResponse_unauthorized = 6,
00231     ocspResponse_other                    /* unknown/unrecognized value */
00232 } ocspResponseStatus;
00233 
00234 /*
00235  * An OCSPResponse is what is sent (encoded) by an OCSP responder.
00236  *
00237  * The field "responseStatus" is the ASN.1 encoded value; the field
00238  * "statusValue" is simply that same value translated into our local
00239  * type ocspResponseStatus.
00240  */
00241 struct CERTOCSPResponseStr {
00242     PRArenaPool *arena;                   /* local; not part of encoding */
00243     SECItem responseStatus;        /* an ENUMERATED, see above */
00244     ocspResponseStatus statusValue;       /* local; not part of encoding */
00245     ocspResponseBytes *responseBytes;     /* only when status is successful */
00246 };
00247 
00248 /*
00249  * A ResponseBytes (despite appearances) is what contains the meat
00250  * of a successful response -- but still in encoded form.  The type
00251  * given as "responseType" tells you how to decode the string.
00252  *
00253  * We look at the OID and translate it into our local OID representation
00254  * "responseTypeTag", and use that value to tell us how to decode the
00255  * actual response itself.  For now the only kind of OCSP response we
00256  * know about is a BasicOCSPResponse.  However, the intention in the
00257  * OCSP specification is to allow for other response types, so we are
00258  * building in that flexibility from the start and thus put a pointer
00259  * to that data structure inside of a union.  Whenever OCSP adds more
00260  * response types, just add them to the union.
00261  */
00262 struct ocspResponseBytesStr {
00263     SECItem responseType;          /* an OBJECT IDENTIFIER */
00264     SECOidTag responseTypeTag;            /* local; not part of encoding */
00265     SECItem response;                     /* an OCTET STRING */
00266     union {
00267        ocspBasicOCSPResponse *basic;      /* when type is id-pkix-ocsp-basic */
00268     } decodedResponse;                    /* local; not part of encoding */
00269 };
00270 
00271 /*
00272  * A BasicOCSPResponse -- when the responseType in a ResponseBytes is
00273  * id-pkix-ocsp-basic, the "response" OCTET STRING above is the DER
00274  * encoding of one of these.
00275  *
00276  * Note that in the OCSP specification, the signature fields are not
00277  * part of a separate sub-structure.  But since they are the same fields
00278  * as we define for the signature in a request, it made sense to share
00279  * the C data structure here and in some shared code to operate on them.
00280  */
00281 struct ocspBasicOCSPResponseStr {
00282     ocspResponseData *tbsResponseData;    /* "tbs" == To Be Signed */
00283     ocspSignature responseSignature;
00284 };
00285 
00286 /*
00287  * A ResponseData is the part of a BasicOCSPResponse that is signed
00288  * (after it is DER encoded).  It contains the real details of the response
00289  * (a per-certificate status).
00290  */
00291 struct ocspResponseDataStr {
00292     SECItem version;               /* an INTEGER */
00293     SECItem derResponderID;
00294     ocspResponderID *responderID;  /* local; not part of encoding */
00295     SECItem producedAt;                   /* a GeneralizedTime */
00296     CERTOCSPSingleResponse **responses;
00297     CERTCertExtension **responseExtensions;
00298 };
00299 
00300 /*
00301  * A ResponderID identifies the responder -- or more correctly, the
00302  * signer of the response.  The ASN.1 definition of a ResponderID is:
00303  *
00304  * ResponderID       ::=    CHOICE {
00305  *     byName               [1] EXPLICIT Name,
00306  *     byKey                [2] EXPLICIT KeyHash }
00307  *
00308  * Because it is CHOICE, the type of identification used and the
00309  * identification itself are actually encoded together.  To represent
00310  * this same information internally, we explicitly define a type and
00311  * save it, along with the value, into a data structure.
00312  */
00313 
00314 typedef enum {
00315     ocspResponderID_byName,
00316     ocspResponderID_byKey,
00317     ocspResponderID_other          /* unknown kind of responderID */
00318 } ocspResponderIDType;
00319 
00320 struct ocspResponderIDStr {
00321     ocspResponderIDType responderIDType;/* local; not part of encoding */
00322     union {
00323        CERTName name;                     /* when ocspResponderID_byName */
00324        SECItem keyHash;            /* when ocspResponderID_byKey */
00325        SECItem other;                     /* when ocspResponderID_other */
00326     } responderIDValue;
00327 };
00328 
00329 /*
00330  * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
00331  * SingleResponse -- one for each certificate whose status is being supplied.
00332  * 
00333  * XXX figure out how to get rid of that arena -- there must be a way
00334  */
00335 struct CERTOCSPSingleResponseStr {
00336     PRArenaPool *arena;                   /* just a copy of the response arena,
00337                                     * needed here for extension handling
00338                                     * routines, on creation only */
00339     CERTOCSPCertID *certID;
00340     SECItem derCertStatus;
00341     ocspCertStatus *certStatus;           /* local; not part of encoding */
00342     SECItem thisUpdate;                   /* a GeneralizedTime */
00343     SECItem *nextUpdate;           /* a GeneralizedTime */
00344     CERTCertExtension **singleExtensions;
00345 };
00346 
00347 /*
00348  * A CertStatus is the actual per-certificate status.  Its ASN.1 definition:
00349  *
00350  * CertStatus ::=    CHOICE {
00351  *     good                 [0] IMPLICIT NULL,
00352  *     revoked                     [1] IMPLICIT RevokedInfo,
00353  *     unknown                     [2] IMPLICIT UnknownInfo }
00354  *
00355  * (where for now UnknownInfo is defined to be NULL but in the
00356  * future may be replaced with an enumeration).
00357  *
00358  * Because it is CHOICE, the status value and its associated information
00359  * (if any) are actually encoded together.  To represent this same
00360  * information internally, we explicitly define a type and save it,
00361  * along with the value, into a data structure.
00362  */
00363 
00364 typedef enum {
00365     ocspCertStatus_good,           /* cert is not revoked */
00366     ocspCertStatus_revoked,        /* cert is revoked */
00367     ocspCertStatus_unknown,        /* cert was unknown to the responder */
00368     ocspCertStatus_other           /* status was not an expected value */
00369 } ocspCertStatusType;
00370 
00371 /*
00372  * This is the actual per-certificate status.
00373  *
00374  * The "goodInfo" and "unknownInfo" items are only place-holders for a NULL.
00375  * (Though someday OCSP may replace UnknownInfo with an enumeration that
00376  * gives more detailed information.)
00377  */
00378 struct ocspCertStatusStr {
00379     ocspCertStatusType certStatusType;    /* local; not part of encoding */
00380     union {
00381        SECItem *goodInfo;          /* when ocspCertStatus_good */
00382        ocspRevokedInfo *revokedInfo;      /* when ocspCertStatus_revoked */
00383        SECItem *unknownInfo;              /* when ocspCertStatus_unknown */
00384        SECItem *otherInfo;         /* when ocspCertStatus_other */
00385     } certStatusInfo; 
00386 };
00387 
00388 /*
00389  * A RevokedInfo gives information about a revoked certificate -- when it
00390  * was revoked and why.
00391  */
00392 struct ocspRevokedInfoStr {
00393     SECItem revocationTime;        /* a GeneralizedTime */
00394     SECItem *revocationReason;            /* a CRLReason; ignored for now */
00395 };
00396 
00397 /*
00398  * ServiceLocator can be included as one of the singleRequestExtensions.
00399  * When added, it specifies the (name of the) issuer of the cert being
00400  * checked, and optionally the value of the AuthorityInfoAccess extension
00401  * if the cert has one.
00402  */
00403 struct ocspServiceLocatorStr {
00404     CERTName *issuer;
00405     SECItem locator; /* DER encoded authInfoAccess extension from cert */
00406 };
00407 
00408 #endif /* _OCSPTI_H_ */