| OLD | NEW |
| (Empty) |
| 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 * $Id: ocspti.h,v 1.11 2013/01/23 23:05:51 kaie%kuix.de Exp $ | |
| 9 */ | |
| 10 | |
| 11 #ifndef _OCSPTI_H_ | |
| 12 #define _OCSPTI_H_ | |
| 13 | |
| 14 #include "ocspt.h" | |
| 15 | |
| 16 #include "certt.h" | |
| 17 #include "plarena.h" | |
| 18 #include "seccomon.h" | |
| 19 #include "secoidt.h" | |
| 20 | |
| 21 | |
| 22 /* | |
| 23 * Some notes about naming conventions... | |
| 24 * | |
| 25 * The public data types all start with "CERTOCSP" (e.g. CERTOCSPRequest). | |
| 26 * (Even the public types are opaque, however. Only their names are | |
| 27 * "exported".) | |
| 28 * | |
| 29 * Internal-only data types drop the "CERT" prefix and use only the | |
| 30 * lower-case "ocsp" (e.g. ocspTBSRequest), for brevity sake. | |
| 31 * | |
| 32 * In either case, the base/suffix of the type name usually matches the | |
| 33 * name as defined in the OCSP specification. The exceptions to this are: | |
| 34 * - When there is overlap between the "OCSP" or "ocsp" prefix and | |
| 35 * the name used in the standard. That is, you cannot strip off the | |
| 36 * "CERTOCSP" or "ocsp" prefix and necessarily get the name of the | |
| 37 * type as it is defined in the standard; the "real" name will be | |
| 38 * *either* "OCSPSuffix" or just "Suffix". | |
| 39 * - When the name in the standard was a little too generic. (e.g. The | |
| 40 * standard defines "Request" but we call it a "SingleRequest".) | |
| 41 * In this case a comment above the type definition calls attention | |
| 42 * to the difference. | |
| 43 * | |
| 44 * The definitions laid out in this header file are intended to follow | |
| 45 * the same order as the definitions in the OCSP specification itself. | |
| 46 * With the OCSP standard in hand, you should be able to move through | |
| 47 * this file and follow along. To future modifiers of this file: please | |
| 48 * try to keep it that way. The only exceptions are the few cases where | |
| 49 * we need to define a type before it is referenced (e.g. enumerations), | |
| 50 * whereas in the OCSP specification these are usually defined the other | |
| 51 * way around (reference before definition). | |
| 52 */ | |
| 53 | |
| 54 | |
| 55 /* | |
| 56 * Forward-declarations of internal-only data structures. | |
| 57 * | |
| 58 * These are in alphabetical order (case-insensitive); please keep it that way! | |
| 59 */ | |
| 60 typedef struct ocspBasicOCSPResponseStr ocspBasicOCSPResponse; | |
| 61 typedef struct ocspCertStatusStr ocspCertStatus; | |
| 62 typedef struct ocspResponderIDStr ocspResponderID; | |
| 63 typedef struct ocspResponseBytesStr ocspResponseBytes; | |
| 64 typedef struct ocspResponseDataStr ocspResponseData; | |
| 65 typedef struct ocspRevokedInfoStr ocspRevokedInfo; | |
| 66 typedef struct ocspServiceLocatorStr ocspServiceLocator; | |
| 67 typedef struct ocspSignatureStr ocspSignature; | |
| 68 typedef struct ocspSingleRequestStr ocspSingleRequest; | |
| 69 typedef struct ocspSingleResponseStr ocspSingleResponse; | |
| 70 typedef struct ocspTBSRequestStr ocspTBSRequest; | |
| 71 | |
| 72 | |
| 73 /* | |
| 74 * An OCSPRequest; this is what is sent (encoded) to an OCSP responder. | |
| 75 */ | |
| 76 struct CERTOCSPRequestStr { | |
| 77 PRArenaPool *arena; /* local; not part of encoding */ | |
| 78 ocspTBSRequest *tbsRequest; | |
| 79 ocspSignature *optionalSignature; | |
| 80 }; | |
| 81 | |
| 82 /* | |
| 83 * A TBSRequest; when an OCSPRequest is signed, the encoding of this | |
| 84 * is what the signature is actually applied to. ("TBS" == To Be Signed) | |
| 85 * Whether signed or not, however, this structure will be present, and | |
| 86 * is the "meat" of the OCSPRequest. | |
| 87 * | |
| 88 * Note that the "requestorName" field cannot be encoded/decoded in the | |
| 89 * same pass as the entire request -- it needs to be handled with a special | |
| 90 * call to convert to/from our internal form of a GeneralName. Thus the | |
| 91 * "derRequestorName" field, which is the actual DER-encoded bytes. | |
| 92 * | |
| 93 * The "extensionHandle" field is used on creation only; it holds | |
| 94 * in-progress extensions as they are optionally added to the request. | |
| 95 */ | |
| 96 struct ocspTBSRequestStr { | |
| 97 SECItem version; /* an INTEGER */ | |
| 98 SECItem *derRequestorName; /* encoded GeneralName; see above */ | |
| 99 CERTGeneralNameList *requestorName; /* local; not part of encoding */ | |
| 100 ocspSingleRequest **requestList; | |
| 101 CERTCertExtension **requestExtensions; | |
| 102 void *extensionHandle; /* local; not part of encoding */ | |
| 103 }; | |
| 104 | |
| 105 /* | |
| 106 * This is the actual signature information for an OCSPRequest (applied to | |
| 107 * the TBSRequest structure) or for a BasicOCSPResponse (applied to a | |
| 108 * ResponseData structure). | |
| 109 * | |
| 110 * Note that the "signature" field itself is a BIT STRING; operations on | |
| 111 * it need to keep that in mind, converting the length to bytes as needed | |
| 112 * and back again afterward (so that the length is usually expressing bits). | |
| 113 * | |
| 114 * The "cert" field is the signer's certificate. In the case of a received | |
| 115 * signature, it will be filled in when the signature is verified. In the | |
| 116 * case of a created signature, it is filled in on creation and will be the | |
| 117 * cert used to create the signature when the signing-and-encoding occurs, | |
| 118 * as well as the cert (and its chain) to fill in derCerts if requested. | |
| 119 * | |
| 120 * The extra fields cache information about the signature after we have | |
| 121 * attempted a verification. "wasChecked", if true, means the signature | |
| 122 * has been checked against the appropriate data and thus that "status" | |
| 123 * contains the result of that verification. If "status" is not SECSuccess, | |
| 124 * "failureReason" is a copy of the error code that was set at the time; | |
| 125 * presumably it tells why the signature verification failed. | |
| 126 */ | |
| 127 struct ocspSignatureStr { | |
| 128 SECAlgorithmID signatureAlgorithm; | |
| 129 SECItem signature; /* a BIT STRING */ | |
| 130 SECItem **derCerts; /* a SEQUENCE OF Certificate */ | |
| 131 CERTCertificate *cert; /* local; not part of encoding */ | |
| 132 PRBool wasChecked; /* local; not part of encoding */ | |
| 133 SECStatus status; /* local; not part of encoding */ | |
| 134 int failureReason; /* local; not part of encoding */ | |
| 135 }; | |
| 136 | |
| 137 /* | |
| 138 * An OCSPRequest contains a SEQUENCE OF these, one for each certificate | |
| 139 * whose status is being checked. | |
| 140 * | |
| 141 * Note that in the OCSP specification this is just called "Request", | |
| 142 * but since that seemed confusing (vs. an OCSPRequest) and to be more | |
| 143 * consistent with the parallel type "SingleResponse", I called it a | |
| 144 * "SingleRequest". | |
| 145 * | |
| 146 * XXX figure out how to get rid of that arena -- there must be a way | |
| 147 */ | |
| 148 struct ocspSingleRequestStr { | |
| 149 PRArenaPool *arena; /* just a copy of the response arena, | |
| 150 * needed here for extension handling | |
| 151 * routines, on creation only */ | |
| 152 CERTOCSPCertID *reqCert; | |
| 153 CERTCertExtension **singleRequestExtensions; | |
| 154 }; | |
| 155 | |
| 156 /* | |
| 157 * A CertID is the means of identifying a certificate, used both in requests | |
| 158 * and in responses. | |
| 159 * | |
| 160 * When in a SingleRequest it specifies the certificate to be checked. | |
| 161 * When in a SingleResponse it is the cert whose status is being given. | |
| 162 */ | |
| 163 struct CERTOCSPCertIDStr { | |
| 164 SECAlgorithmID hashAlgorithm; | |
| 165 SECItem issuerNameHash; /* an OCTET STRING */ | |
| 166 SECItem issuerKeyHash; /* an OCTET STRING */ | |
| 167 SECItem serialNumber; /* an INTEGER */ | |
| 168 SECItem issuerSHA1NameHash; /* keep other hashes around when */ | |
| 169 SECItem issuerMD5NameHash; /* we have them */ | |
| 170 SECItem issuerMD2NameHash; | |
| 171 SECItem issuerSHA1KeyHash; /* keep other hashes around when */ | |
| 172 SECItem issuerMD5KeyHash; /* we have them */ | |
| 173 SECItem issuerMD2KeyHash; | |
| 174 PRArenaPool *poolp; | |
| 175 }; | |
| 176 | |
| 177 /* | |
| 178 * This describes the value of the responseStatus field in an OCSPResponse. | |
| 179 * The corresponding ASN.1 definition is: | |
| 180 * | |
| 181 * OCSPResponseStatus ::= ENUMERATED { | |
| 182 * successful (0), --Response has valid confirmations | |
| 183 * malformedRequest (1), --Illegal confirmation request | |
| 184 * internalError (2), --Internal error in issuer | |
| 185 * tryLater (3), --Try again later | |
| 186 * --(4) is not used | |
| 187 * sigRequired (5), --Must sign the request | |
| 188 * unauthorized (6), --Request unauthorized | |
| 189 * } | |
| 190 */ | |
| 191 typedef enum { | |
| 192 ocspResponse_min = 0, | |
| 193 ocspResponse_successful = 0, | |
| 194 ocspResponse_malformedRequest = 1, | |
| 195 ocspResponse_internalError = 2, | |
| 196 ocspResponse_tryLater = 3, | |
| 197 ocspResponse_unused = 4, | |
| 198 ocspResponse_sigRequired = 5, | |
| 199 ocspResponse_unauthorized = 6, | |
| 200 ocspResponse_max = 6 /* Please update max when adding values. | |
| 201 * Remember to also update arrays, e.g. | |
| 202 * "responseStatusNames" in ocspclnt.c | |
| 203 * and potentially other places. */ | |
| 204 } ocspResponseStatus; | |
| 205 | |
| 206 /* | |
| 207 * An OCSPResponse is what is sent (encoded) by an OCSP responder. | |
| 208 * | |
| 209 * The field "responseStatus" is the ASN.1 encoded value; the field | |
| 210 * "statusValue" is simply that same value translated into our local | |
| 211 * type ocspResponseStatus. | |
| 212 */ | |
| 213 struct CERTOCSPResponseStr { | |
| 214 PRArenaPool *arena; /* local; not part of encoding */ | |
| 215 SECItem responseStatus; /* an ENUMERATED, see above */ | |
| 216 ocspResponseStatus statusValue; /* local; not part of encoding */ | |
| 217 ocspResponseBytes *responseBytes; /* only when status is successful */ | |
| 218 }; | |
| 219 | |
| 220 /* | |
| 221 * A ResponseBytes (despite appearances) is what contains the meat | |
| 222 * of a successful response -- but still in encoded form. The type | |
| 223 * given as "responseType" tells you how to decode the string. | |
| 224 * | |
| 225 * We look at the OID and translate it into our local OID representation | |
| 226 * "responseTypeTag", and use that value to tell us how to decode the | |
| 227 * actual response itself. For now the only kind of OCSP response we | |
| 228 * know about is a BasicOCSPResponse. However, the intention in the | |
| 229 * OCSP specification is to allow for other response types, so we are | |
| 230 * building in that flexibility from the start and thus put a pointer | |
| 231 * to that data structure inside of a union. Whenever OCSP adds more | |
| 232 * response types, just add them to the union. | |
| 233 */ | |
| 234 struct ocspResponseBytesStr { | |
| 235 SECItem responseType; /* an OBJECT IDENTIFIER */ | |
| 236 SECOidTag responseTypeTag; /* local; not part of encoding */ | |
| 237 SECItem response; /* an OCTET STRING */ | |
| 238 union { | |
| 239 ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */ | |
| 240 } decodedResponse; /* local; not part of encoding */ | |
| 241 }; | |
| 242 | |
| 243 /* | |
| 244 * A BasicOCSPResponse -- when the responseType in a ResponseBytes is | |
| 245 * id-pkix-ocsp-basic, the "response" OCTET STRING above is the DER | |
| 246 * encoding of one of these. | |
| 247 * | |
| 248 * Note that in the OCSP specification, the signature fields are not | |
| 249 * part of a separate sub-structure. But since they are the same fields | |
| 250 * as we define for the signature in a request, it made sense to share | |
| 251 * the C data structure here and in some shared code to operate on them. | |
| 252 */ | |
| 253 struct ocspBasicOCSPResponseStr { | |
| 254 SECItem tbsResponseDataDER; | |
| 255 ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */ | |
| 256 ocspSignature responseSignature; | |
| 257 }; | |
| 258 | |
| 259 /* | |
| 260 * A ResponseData is the part of a BasicOCSPResponse that is signed | |
| 261 * (after it is DER encoded). It contains the real details of the response | |
| 262 * (a per-certificate status). | |
| 263 */ | |
| 264 struct ocspResponseDataStr { | |
| 265 SECItem version; /* an INTEGER */ | |
| 266 SECItem derResponderID; | |
| 267 ocspResponderID *responderID; /* local; not part of encoding */ | |
| 268 SECItem producedAt; /* a GeneralizedTime */ | |
| 269 CERTOCSPSingleResponse **responses; | |
| 270 CERTCertExtension **responseExtensions; | |
| 271 }; | |
| 272 | |
| 273 struct ocspResponderIDStr { | |
| 274 CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */ | |
| 275 union { | |
| 276 CERTName name; /* when ocspResponderID_byName */ | |
| 277 SECItem keyHash; /* when ocspResponderID_byKey */ | |
| 278 SECItem other; /* when ocspResponderID_other */ | |
| 279 } responderIDValue; | |
| 280 }; | |
| 281 | |
| 282 /* | |
| 283 * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF | |
| 284 * SingleResponse -- one for each certificate whose status is being supplied. | |
| 285 * | |
| 286 * XXX figure out how to get rid of that arena -- there must be a way | |
| 287 */ | |
| 288 struct CERTOCSPSingleResponseStr { | |
| 289 PRArenaPool *arena; /* just a copy of the response arena, | |
| 290 * needed here for extension handling | |
| 291 * routines, on creation only */ | |
| 292 CERTOCSPCertID *certID; | |
| 293 SECItem derCertStatus; | |
| 294 ocspCertStatus *certStatus; /* local; not part of encoding */ | |
| 295 SECItem thisUpdate; /* a GeneralizedTime */ | |
| 296 SECItem *nextUpdate; /* a GeneralizedTime */ | |
| 297 CERTCertExtension **singleExtensions; | |
| 298 }; | |
| 299 | |
| 300 /* | |
| 301 * A CertStatus is the actual per-certificate status. Its ASN.1 definition: | |
| 302 * | |
| 303 * CertStatus ::= CHOICE { | |
| 304 * good [0] IMPLICIT NULL, | |
| 305 * revoked [1] IMPLICIT RevokedInfo, | |
| 306 * unknown [2] IMPLICIT UnknownInfo } | |
| 307 * | |
| 308 * (where for now UnknownInfo is defined to be NULL but in the | |
| 309 * future may be replaced with an enumeration). | |
| 310 * | |
| 311 * Because it is CHOICE, the status value and its associated information | |
| 312 * (if any) are actually encoded together. To represent this same | |
| 313 * information internally, we explicitly define a type and save it, | |
| 314 * along with the value, into a data structure. | |
| 315 */ | |
| 316 | |
| 317 typedef enum { | |
| 318 ocspCertStatus_good, /* cert is not revoked */ | |
| 319 ocspCertStatus_revoked, /* cert is revoked */ | |
| 320 ocspCertStatus_unknown, /* cert was unknown to the responder */ | |
| 321 ocspCertStatus_other /* status was not an expected value */ | |
| 322 } ocspCertStatusType; | |
| 323 | |
| 324 /* | |
| 325 * This is the actual per-certificate status. | |
| 326 * | |
| 327 * The "goodInfo" and "unknownInfo" items are only place-holders for a NULL. | |
| 328 * (Though someday OCSP may replace UnknownInfo with an enumeration that | |
| 329 * gives more detailed information.) | |
| 330 */ | |
| 331 struct ocspCertStatusStr { | |
| 332 ocspCertStatusType certStatusType; /* local; not part of encoding */ | |
| 333 union { | |
| 334 SECItem *goodInfo; /* when ocspCertStatus_good */ | |
| 335 ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */ | |
| 336 SECItem *unknownInfo; /* when ocspCertStatus_unknown */ | |
| 337 SECItem *otherInfo; /* when ocspCertStatus_other */ | |
| 338 } certStatusInfo; | |
| 339 }; | |
| 340 | |
| 341 /* | |
| 342 * A RevokedInfo gives information about a revoked certificate -- when it | |
| 343 * was revoked and why. | |
| 344 */ | |
| 345 struct ocspRevokedInfoStr { | |
| 346 SECItem revocationTime; /* a GeneralizedTime */ | |
| 347 SECItem *revocationReason; /* a CRLReason; ignored for now */ | |
| 348 }; | |
| 349 | |
| 350 /* | |
| 351 * ServiceLocator can be included as one of the singleRequestExtensions. | |
| 352 * When added, it specifies the (name of the) issuer of the cert being | |
| 353 * checked, and optionally the value of the AuthorityInfoAccess extension | |
| 354 * if the cert has one. | |
| 355 */ | |
| 356 struct ocspServiceLocatorStr { | |
| 357 CERTName *issuer; | |
| 358 SECItem locator; /* DER encoded authInfoAccess extension from cert */ | |
| 359 }; | |
| 360 | |
| 361 #endif /* _OCSPTI_H_ */ | |
| OLD | NEW |