1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/certhigh/ocspti.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,359 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * Private header defining OCSP types. 1.10 + */ 1.11 + 1.12 +#ifndef _OCSPTI_H_ 1.13 +#define _OCSPTI_H_ 1.14 + 1.15 +#include "ocspt.h" 1.16 + 1.17 +#include "certt.h" 1.18 +#include "plarena.h" 1.19 +#include "seccomon.h" 1.20 +#include "secoidt.h" 1.21 + 1.22 + 1.23 +/* 1.24 + * Some notes about naming conventions... 1.25 + * 1.26 + * The public data types all start with "CERTOCSP" (e.g. CERTOCSPRequest). 1.27 + * (Even the public types are opaque, however. Only their names are 1.28 + * "exported".) 1.29 + * 1.30 + * Internal-only data types drop the "CERT" prefix and use only the 1.31 + * lower-case "ocsp" (e.g. ocspTBSRequest), for brevity sake. 1.32 + * 1.33 + * In either case, the base/suffix of the type name usually matches the 1.34 + * name as defined in the OCSP specification. The exceptions to this are: 1.35 + * - When there is overlap between the "OCSP" or "ocsp" prefix and 1.36 + * the name used in the standard. That is, you cannot strip off the 1.37 + * "CERTOCSP" or "ocsp" prefix and necessarily get the name of the 1.38 + * type as it is defined in the standard; the "real" name will be 1.39 + * *either* "OCSPSuffix" or just "Suffix". 1.40 + * - When the name in the standard was a little too generic. (e.g. The 1.41 + * standard defines "Request" but we call it a "SingleRequest".) 1.42 + * In this case a comment above the type definition calls attention 1.43 + * to the difference. 1.44 + * 1.45 + * The definitions laid out in this header file are intended to follow 1.46 + * the same order as the definitions in the OCSP specification itself. 1.47 + * With the OCSP standard in hand, you should be able to move through 1.48 + * this file and follow along. To future modifiers of this file: please 1.49 + * try to keep it that way. The only exceptions are the few cases where 1.50 + * we need to define a type before it is referenced (e.g. enumerations), 1.51 + * whereas in the OCSP specification these are usually defined the other 1.52 + * way around (reference before definition). 1.53 + */ 1.54 + 1.55 + 1.56 +/* 1.57 + * Forward-declarations of internal-only data structures. 1.58 + * 1.59 + * These are in alphabetical order (case-insensitive); please keep it that way! 1.60 + */ 1.61 +typedef struct ocspBasicOCSPResponseStr ocspBasicOCSPResponse; 1.62 +typedef struct ocspCertStatusStr ocspCertStatus; 1.63 +typedef struct ocspResponderIDStr ocspResponderID; 1.64 +typedef struct ocspResponseBytesStr ocspResponseBytes; 1.65 +typedef struct ocspResponseDataStr ocspResponseData; 1.66 +typedef struct ocspRevokedInfoStr ocspRevokedInfo; 1.67 +typedef struct ocspServiceLocatorStr ocspServiceLocator; 1.68 +typedef struct ocspSignatureStr ocspSignature; 1.69 +typedef struct ocspSingleRequestStr ocspSingleRequest; 1.70 +typedef struct ocspSingleResponseStr ocspSingleResponse; 1.71 +typedef struct ocspTBSRequestStr ocspTBSRequest; 1.72 + 1.73 + 1.74 +/* 1.75 + * An OCSPRequest; this is what is sent (encoded) to an OCSP responder. 1.76 + */ 1.77 +struct CERTOCSPRequestStr { 1.78 + PLArenaPool *arena; /* local; not part of encoding */ 1.79 + ocspTBSRequest *tbsRequest; 1.80 + ocspSignature *optionalSignature; 1.81 +}; 1.82 + 1.83 +/* 1.84 + * A TBSRequest; when an OCSPRequest is signed, the encoding of this 1.85 + * is what the signature is actually applied to. ("TBS" == To Be Signed) 1.86 + * Whether signed or not, however, this structure will be present, and 1.87 + * is the "meat" of the OCSPRequest. 1.88 + * 1.89 + * Note that the "requestorName" field cannot be encoded/decoded in the 1.90 + * same pass as the entire request -- it needs to be handled with a special 1.91 + * call to convert to/from our internal form of a GeneralName. Thus the 1.92 + * "derRequestorName" field, which is the actual DER-encoded bytes. 1.93 + * 1.94 + * The "extensionHandle" field is used on creation only; it holds 1.95 + * in-progress extensions as they are optionally added to the request. 1.96 + */ 1.97 +struct ocspTBSRequestStr { 1.98 + SECItem version; /* an INTEGER */ 1.99 + SECItem *derRequestorName; /* encoded GeneralName; see above */ 1.100 + CERTGeneralNameList *requestorName; /* local; not part of encoding */ 1.101 + ocspSingleRequest **requestList; 1.102 + CERTCertExtension **requestExtensions; 1.103 + void *extensionHandle; /* local; not part of encoding */ 1.104 +}; 1.105 + 1.106 +/* 1.107 + * This is the actual signature information for an OCSPRequest (applied to 1.108 + * the TBSRequest structure) or for a BasicOCSPResponse (applied to a 1.109 + * ResponseData structure). 1.110 + * 1.111 + * Note that the "signature" field itself is a BIT STRING; operations on 1.112 + * it need to keep that in mind, converting the length to bytes as needed 1.113 + * and back again afterward (so that the length is usually expressing bits). 1.114 + * 1.115 + * The "cert" field is the signer's certificate. In the case of a received 1.116 + * signature, it will be filled in when the signature is verified. In the 1.117 + * case of a created signature, it is filled in on creation and will be the 1.118 + * cert used to create the signature when the signing-and-encoding occurs, 1.119 + * as well as the cert (and its chain) to fill in derCerts if requested. 1.120 + * 1.121 + * The extra fields cache information about the signature after we have 1.122 + * attempted a verification. "wasChecked", if true, means the signature 1.123 + * has been checked against the appropriate data and thus that "status" 1.124 + * contains the result of that verification. If "status" is not SECSuccess, 1.125 + * "failureReason" is a copy of the error code that was set at the time; 1.126 + * presumably it tells why the signature verification failed. 1.127 + */ 1.128 +struct ocspSignatureStr { 1.129 + SECAlgorithmID signatureAlgorithm; 1.130 + SECItem signature; /* a BIT STRING */ 1.131 + SECItem **derCerts; /* a SEQUENCE OF Certificate */ 1.132 + CERTCertificate *cert; /* local; not part of encoding */ 1.133 + PRBool wasChecked; /* local; not part of encoding */ 1.134 + SECStatus status; /* local; not part of encoding */ 1.135 + int failureReason; /* local; not part of encoding */ 1.136 +}; 1.137 + 1.138 +/* 1.139 + * An OCSPRequest contains a SEQUENCE OF these, one for each certificate 1.140 + * whose status is being checked. 1.141 + * 1.142 + * Note that in the OCSP specification this is just called "Request", 1.143 + * but since that seemed confusing (vs. an OCSPRequest) and to be more 1.144 + * consistent with the parallel type "SingleResponse", I called it a 1.145 + * "SingleRequest". 1.146 + * 1.147 + * XXX figure out how to get rid of that arena -- there must be a way 1.148 + */ 1.149 +struct ocspSingleRequestStr { 1.150 + PLArenaPool *arena; /* just a copy of the response arena, 1.151 + * needed here for extension handling 1.152 + * routines, on creation only */ 1.153 + CERTOCSPCertID *reqCert; 1.154 + CERTCertExtension **singleRequestExtensions; 1.155 +}; 1.156 + 1.157 +/* 1.158 + * A CertID is the means of identifying a certificate, used both in requests 1.159 + * and in responses. 1.160 + * 1.161 + * When in a SingleRequest it specifies the certificate to be checked. 1.162 + * When in a SingleResponse it is the cert whose status is being given. 1.163 + */ 1.164 +struct CERTOCSPCertIDStr { 1.165 + SECAlgorithmID hashAlgorithm; 1.166 + SECItem issuerNameHash; /* an OCTET STRING */ 1.167 + SECItem issuerKeyHash; /* an OCTET STRING */ 1.168 + SECItem serialNumber; /* an INTEGER */ 1.169 + SECItem issuerSHA1NameHash; /* keep other hashes around when */ 1.170 + SECItem issuerMD5NameHash; /* we have them */ 1.171 + SECItem issuerMD2NameHash; 1.172 + SECItem issuerSHA1KeyHash; /* keep other hashes around when */ 1.173 + SECItem issuerMD5KeyHash; /* we have them */ 1.174 + SECItem issuerMD2KeyHash; 1.175 + PLArenaPool *poolp; 1.176 +}; 1.177 + 1.178 +/* 1.179 + * This describes the value of the responseStatus field in an OCSPResponse. 1.180 + * The corresponding ASN.1 definition is: 1.181 + * 1.182 + * OCSPResponseStatus ::= ENUMERATED { 1.183 + * successful (0), --Response has valid confirmations 1.184 + * malformedRequest (1), --Illegal confirmation request 1.185 + * internalError (2), --Internal error in issuer 1.186 + * tryLater (3), --Try again later 1.187 + * --(4) is not used 1.188 + * sigRequired (5), --Must sign the request 1.189 + * unauthorized (6), --Request unauthorized 1.190 + * } 1.191 + */ 1.192 +typedef enum { 1.193 + ocspResponse_min = 0, 1.194 + ocspResponse_successful = 0, 1.195 + ocspResponse_malformedRequest = 1, 1.196 + ocspResponse_internalError = 2, 1.197 + ocspResponse_tryLater = 3, 1.198 + ocspResponse_unused = 4, 1.199 + ocspResponse_sigRequired = 5, 1.200 + ocspResponse_unauthorized = 6, 1.201 + ocspResponse_max = 6 /* Please update max when adding values. 1.202 + * Remember to also update arrays, e.g. 1.203 + * "responseStatusNames" in ocspclnt.c 1.204 + * and potentially other places. */ 1.205 +} ocspResponseStatus; 1.206 + 1.207 +/* 1.208 + * An OCSPResponse is what is sent (encoded) by an OCSP responder. 1.209 + * 1.210 + * The field "responseStatus" is the ASN.1 encoded value; the field 1.211 + * "statusValue" is simply that same value translated into our local 1.212 + * type ocspResponseStatus. 1.213 + */ 1.214 +struct CERTOCSPResponseStr { 1.215 + PLArenaPool *arena; /* local; not part of encoding */ 1.216 + SECItem responseStatus; /* an ENUMERATED, see above */ 1.217 + ocspResponseStatus statusValue; /* local; not part of encoding */ 1.218 + ocspResponseBytes *responseBytes; /* only when status is successful */ 1.219 +}; 1.220 + 1.221 +/* 1.222 + * A ResponseBytes (despite appearances) is what contains the meat 1.223 + * of a successful response -- but still in encoded form. The type 1.224 + * given as "responseType" tells you how to decode the string. 1.225 + * 1.226 + * We look at the OID and translate it into our local OID representation 1.227 + * "responseTypeTag", and use that value to tell us how to decode the 1.228 + * actual response itself. For now the only kind of OCSP response we 1.229 + * know about is a BasicOCSPResponse. However, the intention in the 1.230 + * OCSP specification is to allow for other response types, so we are 1.231 + * building in that flexibility from the start and thus put a pointer 1.232 + * to that data structure inside of a union. Whenever OCSP adds more 1.233 + * response types, just add them to the union. 1.234 + */ 1.235 +struct ocspResponseBytesStr { 1.236 + SECItem responseType; /* an OBJECT IDENTIFIER */ 1.237 + SECOidTag responseTypeTag; /* local; not part of encoding */ 1.238 + SECItem response; /* an OCTET STRING */ 1.239 + union { 1.240 + ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */ 1.241 + } decodedResponse; /* local; not part of encoding */ 1.242 +}; 1.243 + 1.244 +/* 1.245 + * A BasicOCSPResponse -- when the responseType in a ResponseBytes is 1.246 + * id-pkix-ocsp-basic, the "response" OCTET STRING above is the DER 1.247 + * encoding of one of these. 1.248 + * 1.249 + * Note that in the OCSP specification, the signature fields are not 1.250 + * part of a separate sub-structure. But since they are the same fields 1.251 + * as we define for the signature in a request, it made sense to share 1.252 + * the C data structure here and in some shared code to operate on them. 1.253 + */ 1.254 +struct ocspBasicOCSPResponseStr { 1.255 + SECItem tbsResponseDataDER; 1.256 + ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */ 1.257 + ocspSignature responseSignature; 1.258 +}; 1.259 + 1.260 +/* 1.261 + * A ResponseData is the part of a BasicOCSPResponse that is signed 1.262 + * (after it is DER encoded). It contains the real details of the response 1.263 + * (a per-certificate status). 1.264 + */ 1.265 +struct ocspResponseDataStr { 1.266 + SECItem version; /* an INTEGER */ 1.267 + SECItem derResponderID; 1.268 + ocspResponderID *responderID; /* local; not part of encoding */ 1.269 + SECItem producedAt; /* a GeneralizedTime */ 1.270 + CERTOCSPSingleResponse **responses; 1.271 + CERTCertExtension **responseExtensions; 1.272 +}; 1.273 + 1.274 +struct ocspResponderIDStr { 1.275 + CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */ 1.276 + union { 1.277 + CERTName name; /* when ocspResponderID_byName */ 1.278 + SECItem keyHash; /* when ocspResponderID_byKey */ 1.279 + SECItem other; /* when ocspResponderID_other */ 1.280 + } responderIDValue; 1.281 +}; 1.282 + 1.283 +/* 1.284 + * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF 1.285 + * SingleResponse -- one for each certificate whose status is being supplied. 1.286 + * 1.287 + * XXX figure out how to get rid of that arena -- there must be a way 1.288 + */ 1.289 +struct CERTOCSPSingleResponseStr { 1.290 + PLArenaPool *arena; /* just a copy of the response arena, 1.291 + * needed here for extension handling 1.292 + * routines, on creation only */ 1.293 + CERTOCSPCertID *certID; 1.294 + SECItem derCertStatus; 1.295 + ocspCertStatus *certStatus; /* local; not part of encoding */ 1.296 + SECItem thisUpdate; /* a GeneralizedTime */ 1.297 + SECItem *nextUpdate; /* a GeneralizedTime */ 1.298 + CERTCertExtension **singleExtensions; 1.299 +}; 1.300 + 1.301 +/* 1.302 + * A CertStatus is the actual per-certificate status. Its ASN.1 definition: 1.303 + * 1.304 + * CertStatus ::= CHOICE { 1.305 + * good [0] IMPLICIT NULL, 1.306 + * revoked [1] IMPLICIT RevokedInfo, 1.307 + * unknown [2] IMPLICIT UnknownInfo } 1.308 + * 1.309 + * (where for now UnknownInfo is defined to be NULL but in the 1.310 + * future may be replaced with an enumeration). 1.311 + * 1.312 + * Because it is CHOICE, the status value and its associated information 1.313 + * (if any) are actually encoded together. To represent this same 1.314 + * information internally, we explicitly define a type and save it, 1.315 + * along with the value, into a data structure. 1.316 + */ 1.317 + 1.318 +typedef enum { 1.319 + ocspCertStatus_good, /* cert is not revoked */ 1.320 + ocspCertStatus_revoked, /* cert is revoked */ 1.321 + ocspCertStatus_unknown, /* cert was unknown to the responder */ 1.322 + ocspCertStatus_other /* status was not an expected value */ 1.323 +} ocspCertStatusType; 1.324 + 1.325 +/* 1.326 + * This is the actual per-certificate status. 1.327 + * 1.328 + * The "goodInfo" and "unknownInfo" items are only place-holders for a NULL. 1.329 + * (Though someday OCSP may replace UnknownInfo with an enumeration that 1.330 + * gives more detailed information.) 1.331 + */ 1.332 +struct ocspCertStatusStr { 1.333 + ocspCertStatusType certStatusType; /* local; not part of encoding */ 1.334 + union { 1.335 + SECItem *goodInfo; /* when ocspCertStatus_good */ 1.336 + ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */ 1.337 + SECItem *unknownInfo; /* when ocspCertStatus_unknown */ 1.338 + SECItem *otherInfo; /* when ocspCertStatus_other */ 1.339 + } certStatusInfo; 1.340 +}; 1.341 + 1.342 +/* 1.343 + * A RevokedInfo gives information about a revoked certificate -- when it 1.344 + * was revoked and why. 1.345 + */ 1.346 +struct ocspRevokedInfoStr { 1.347 + SECItem revocationTime; /* a GeneralizedTime */ 1.348 + SECItem *revocationReason; /* a CRLReason; ignored for now */ 1.349 +}; 1.350 + 1.351 +/* 1.352 + * ServiceLocator can be included as one of the singleRequestExtensions. 1.353 + * When added, it specifies the (name of the) issuer of the cert being 1.354 + * checked, and optionally the value of the AuthorityInfoAccess extension 1.355 + * if the cert has one. 1.356 + */ 1.357 +struct ocspServiceLocatorStr { 1.358 + CERTName *issuer; 1.359 + SECItem locator; /* DER encoded authInfoAccess extension from cert */ 1.360 +}; 1.361 + 1.362 +#endif /* _OCSPTI_H_ */