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_ */