Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | /* |
michael@0 | 6 | * Public header for exported OCSP types. |
michael@0 | 7 | */ |
michael@0 | 8 | |
michael@0 | 9 | #ifndef _OCSPT_H_ |
michael@0 | 10 | #define _OCSPT_H_ |
michael@0 | 11 | |
michael@0 | 12 | /* |
michael@0 | 13 | * The following are all opaque types. If someone needs to get at |
michael@0 | 14 | * a field within, then we need to fix the API. Try very hard not |
michael@0 | 15 | * make the type available to them. |
michael@0 | 16 | */ |
michael@0 | 17 | typedef struct CERTOCSPRequestStr CERTOCSPRequest; |
michael@0 | 18 | typedef struct CERTOCSPResponseStr CERTOCSPResponse; |
michael@0 | 19 | |
michael@0 | 20 | /* |
michael@0 | 21 | * XXX I think only those first two above should need to be exported, |
michael@0 | 22 | * but until I know for certain I am leaving the rest of these here, too. |
michael@0 | 23 | */ |
michael@0 | 24 | typedef struct CERTOCSPCertIDStr CERTOCSPCertID; |
michael@0 | 25 | typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse; |
michael@0 | 26 | |
michael@0 | 27 | /* |
michael@0 | 28 | * This interface is described in terms of an HttpClient which |
michael@0 | 29 | * supports at least a specified set of functions. (An implementer may |
michael@0 | 30 | * provide HttpClients with additional functionality accessible only to |
michael@0 | 31 | * users with a particular implementation in mind.) The basic behavior |
michael@0 | 32 | * is provided by defining a set of functions, listed in an |
michael@0 | 33 | * SEC_HttpServerFcnStruct. If the implementor of a SpecificHttpClient |
michael@0 | 34 | * registers his SpecificHttpClient as the default HttpClient, then his |
michael@0 | 35 | * functions will be called by the user of an HttpClient, such as an |
michael@0 | 36 | * OCSPChecker. |
michael@0 | 37 | * |
michael@0 | 38 | * The implementer of a specific HttpClient (e.g., the NSS-provided |
michael@0 | 39 | * DefaultHttpClient), populates an SEC_HttpClientFcnStruct, uses it to |
michael@0 | 40 | * register his client, and waits for his functions to be called. |
michael@0 | 41 | * |
michael@0 | 42 | * For future expandability, the SEC_HttpClientFcnStruct is defined as a |
michael@0 | 43 | * union, with the version field acting as a selector. The proposed |
michael@0 | 44 | * initial version of the structure is given following the definition |
michael@0 | 45 | * of the union. The HttpClientState structure is implementation- |
michael@0 | 46 | * dependent, and should be opaque to the user. |
michael@0 | 47 | */ |
michael@0 | 48 | |
michael@0 | 49 | typedef void * SEC_HTTP_SERVER_SESSION; |
michael@0 | 50 | typedef void * SEC_HTTP_REQUEST_SESSION; |
michael@0 | 51 | |
michael@0 | 52 | /* |
michael@0 | 53 | * This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a |
michael@0 | 54 | * specific HttpClient will allocate the necessary space, when this |
michael@0 | 55 | * function is called, and will free it when the corresponding FreeFcn |
michael@0 | 56 | * is called. The SEC_HTTP_SERVER_SESSION object is passed, as an opaque object, |
michael@0 | 57 | * to subsequent calls. |
michael@0 | 58 | * |
michael@0 | 59 | * If the function returns SECSuccess, the returned SEC_HTTP_SERVER_SESSION |
michael@0 | 60 | * must be cleaned up with a call to SEC_HttpServer_FreeSession, |
michael@0 | 61 | * after processing is finished. |
michael@0 | 62 | */ |
michael@0 | 63 | typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)( |
michael@0 | 64 | const char *host, |
michael@0 | 65 | PRUint16 portnum, |
michael@0 | 66 | SEC_HTTP_SERVER_SESSION *pSession); |
michael@0 | 67 | |
michael@0 | 68 | /* |
michael@0 | 69 | * This function is called to allow the implementation to attempt to keep |
michael@0 | 70 | * the connection alive. Depending on the underlying platform, it might |
michael@0 | 71 | * immediately return SECSuccess without having performed any operations. |
michael@0 | 72 | * (If a connection has not been kept alive, a subsequent call to |
michael@0 | 73 | * SEC_HttpRequest_TrySendAndReceiveFcn should reopen the connection |
michael@0 | 74 | * automatically.) |
michael@0 | 75 | * |
michael@0 | 76 | * If the connection uses nonblocking I/O, this function may return |
michael@0 | 77 | * SECWouldBlock and store a nonzero value at "pPollDesc". In that case |
michael@0 | 78 | * the caller may wait on the poll descriptor, and should call this function |
michael@0 | 79 | * again until SECSuccess (and a zero value at "pPollDesc") is obtained. |
michael@0 | 80 | */ |
michael@0 | 81 | typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)( |
michael@0 | 82 | SEC_HTTP_SERVER_SESSION session, |
michael@0 | 83 | PRPollDesc **pPollDesc); |
michael@0 | 84 | |
michael@0 | 85 | /* |
michael@0 | 86 | * This function frees the client SEC_HTTP_SERVER_SESSION object, closes all |
michael@0 | 87 | * SEC_HTTP_REQUEST_SESSIONs created for that server, discards all partial results, |
michael@0 | 88 | * frees any memory that was allocated by the client, and invalidates any |
michael@0 | 89 | * response pointers that might have been returned by prior server or request |
michael@0 | 90 | * functions. |
michael@0 | 91 | */ |
michael@0 | 92 | typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)( |
michael@0 | 93 | SEC_HTTP_SERVER_SESSION session); |
michael@0 | 94 | |
michael@0 | 95 | /* |
michael@0 | 96 | * This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a |
michael@0 | 97 | * specific HttpClient will allocate the necessary space, when this |
michael@0 | 98 | * function is called, and will free it when the corresponding FreeFcn |
michael@0 | 99 | * is called. The SEC_HTTP_REQUEST_SESSION object is passed, as an opaque object, |
michael@0 | 100 | * to subsequent calls. |
michael@0 | 101 | * |
michael@0 | 102 | * An implementation that does not support the requested protocol variant |
michael@0 | 103 | * (usually "http", but could eventually allow "https") or request method |
michael@0 | 104 | * should return SECFailure. |
michael@0 | 105 | * |
michael@0 | 106 | * Timeout values may include the constants PR_INTERVAL_NO_TIMEOUT (wait |
michael@0 | 107 | * forever) or PR_INTERVAL_NO_WAIT (nonblocking I/O). |
michael@0 | 108 | * |
michael@0 | 109 | * If the function returns SECSuccess, the returned SEC_HTTP_REQUEST_SESSION |
michael@0 | 110 | * must be cleaned up with a call to SEC_HttpRequest_FreeSession, |
michael@0 | 111 | * after processing is finished. |
michael@0 | 112 | */ |
michael@0 | 113 | typedef SECStatus (*SEC_HttpRequest_CreateFcn)( |
michael@0 | 114 | SEC_HTTP_SERVER_SESSION session, |
michael@0 | 115 | const char *http_protocol_variant, /* usually "http" */ |
michael@0 | 116 | const char *path_and_query_string, |
michael@0 | 117 | const char *http_request_method, |
michael@0 | 118 | const PRIntervalTime timeout, |
michael@0 | 119 | SEC_HTTP_REQUEST_SESSION *pRequest); |
michael@0 | 120 | |
michael@0 | 121 | /* |
michael@0 | 122 | * This function sets data to be sent to the server for an HTTP request |
michael@0 | 123 | * of http_request_method == POST. If a particular implementation |
michael@0 | 124 | * supports it, the details for the POST request can be set by calling |
michael@0 | 125 | * this function, prior to activating the request with TrySendAndReceiveFcn. |
michael@0 | 126 | * |
michael@0 | 127 | * An implementation that does not support the POST method should |
michael@0 | 128 | * implement a SetPostDataFcn function that returns immediately. |
michael@0 | 129 | * |
michael@0 | 130 | * Setting http_content_type is optional, the parameter may |
michael@0 | 131 | * by NULL or the empty string. |
michael@0 | 132 | */ |
michael@0 | 133 | typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)( |
michael@0 | 134 | SEC_HTTP_REQUEST_SESSION request, |
michael@0 | 135 | const char *http_data, |
michael@0 | 136 | const PRUint32 http_data_len, |
michael@0 | 137 | const char *http_content_type); |
michael@0 | 138 | |
michael@0 | 139 | /* |
michael@0 | 140 | * This function sets an additional HTTP protocol request header. |
michael@0 | 141 | * If a particular implementation supports it, one or multiple headers |
michael@0 | 142 | * can be added to the request by calling this function once or multiple |
michael@0 | 143 | * times, prior to activating the request with TryFcn. |
michael@0 | 144 | * |
michael@0 | 145 | * An implementation that does not support setting additional headers |
michael@0 | 146 | * should implement an AddRequestHeaderFcn function that returns immediately. |
michael@0 | 147 | */ |
michael@0 | 148 | typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)( |
michael@0 | 149 | SEC_HTTP_REQUEST_SESSION request, |
michael@0 | 150 | const char *http_header_name, |
michael@0 | 151 | const char *http_header_value); |
michael@0 | 152 | |
michael@0 | 153 | /* |
michael@0 | 154 | * This function initiates or continues an HTTP request. After |
michael@0 | 155 | * parameters have been set with the Create function and, optionally, |
michael@0 | 156 | * modified or enhanced with the AddParams function, this call creates |
michael@0 | 157 | * the socket connection and initiates the communication. |
michael@0 | 158 | * |
michael@0 | 159 | * If a timeout value of zero is specified, indicating non-blocking |
michael@0 | 160 | * I/O, the client creates a non-blocking socket, and returns a status |
michael@0 | 161 | * of SECWouldBlock and a non-NULL PRPollDesc if the operation is not |
michael@0 | 162 | * complete. In that case all other return parameters are undefined. |
michael@0 | 163 | * The caller is expected to repeat the call, possibly after using |
michael@0 | 164 | * PRPoll to determine that a completion has occurred, until a return |
michael@0 | 165 | * value of SECSuccess (and a NULL value for pPollDesc) or a return |
michael@0 | 166 | * value of SECFailure (indicating failure on the network level) |
michael@0 | 167 | * is obtained. |
michael@0 | 168 | * |
michael@0 | 169 | * http_response_data_len is both input and output parameter. |
michael@0 | 170 | * If a pointer to a PRUint32 is supplied, the http client is |
michael@0 | 171 | * expected to check the given integer value and always set an out |
michael@0 | 172 | * value, even on failure. |
michael@0 | 173 | * An input value of zero means, the caller will accept any response len. |
michael@0 | 174 | * A different input value indicates the maximum response value acceptable |
michael@0 | 175 | * to the caller. |
michael@0 | 176 | * If data is successfully read and the size is acceptable to the caller, |
michael@0 | 177 | * the function will return SECSuccess and set http_response_data_len to |
michael@0 | 178 | * the size of the block returned in http_response_data. |
michael@0 | 179 | * If the data read from the http server is larger than the acceptable |
michael@0 | 180 | * size, the function will return SECFailure. |
michael@0 | 181 | * http_response_data_len will be set to a value different from zero to |
michael@0 | 182 | * indicate the reason of the failure. |
michael@0 | 183 | * An out value of "0" means, the failure was unrelated to the |
michael@0 | 184 | * acceptable size. |
michael@0 | 185 | * An out value of "1" means, the result data is larger than the |
michael@0 | 186 | * accpeptable size, but the real size is not yet known to the http client |
michael@0 | 187 | * implementation and it stopped retrieving it, |
michael@0 | 188 | * Any other out value combined with a return value of SECFailure |
michael@0 | 189 | * will indicate the actual size of the server data. |
michael@0 | 190 | * |
michael@0 | 191 | * The caller is permitted to provide NULL values for any of the |
michael@0 | 192 | * http_response arguments, indicating the caller is not interested in |
michael@0 | 193 | * those values. If the caller does provide an address, the HttpClient |
michael@0 | 194 | * stores at that address a pointer to the corresponding argument, at |
michael@0 | 195 | * the completion of the operation. |
michael@0 | 196 | * |
michael@0 | 197 | * All returned pointers will be owned by the the HttpClient |
michael@0 | 198 | * implementation and will remain valid until the call to |
michael@0 | 199 | * SEC_HttpRequest_FreeFcn. |
michael@0 | 200 | */ |
michael@0 | 201 | typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)( |
michael@0 | 202 | SEC_HTTP_REQUEST_SESSION request, |
michael@0 | 203 | PRPollDesc **pPollDesc, |
michael@0 | 204 | PRUint16 *http_response_code, |
michael@0 | 205 | const char **http_response_content_type, |
michael@0 | 206 | const char **http_response_headers, |
michael@0 | 207 | const char **http_response_data, |
michael@0 | 208 | PRUint32 *http_response_data_len); |
michael@0 | 209 | |
michael@0 | 210 | /* |
michael@0 | 211 | * Calling CancelFcn asks for premature termination of the request. |
michael@0 | 212 | * |
michael@0 | 213 | * Future calls to SEC_HttpRequest_TrySendAndReceive should |
michael@0 | 214 | * by avoided, but in this case the HttpClient implementation |
michael@0 | 215 | * is expected to return immediately with SECFailure. |
michael@0 | 216 | * |
michael@0 | 217 | * After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn |
michael@0 | 218 | * is still necessary to free resources. |
michael@0 | 219 | */ |
michael@0 | 220 | typedef SECStatus (*SEC_HttpRequest_CancelFcn)( |
michael@0 | 221 | SEC_HTTP_REQUEST_SESSION request); |
michael@0 | 222 | |
michael@0 | 223 | /* |
michael@0 | 224 | * Before calling this function, it must be assured the request |
michael@0 | 225 | * has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has |
michael@0 | 226 | * returned SECSuccess, or the request has been canceled with |
michael@0 | 227 | * a call to SEC_HttpRequest_CancelFcn. |
michael@0 | 228 | * |
michael@0 | 229 | * This function frees the client state object, closes all sockets, |
michael@0 | 230 | * discards all partial results, frees any memory that was allocated |
michael@0 | 231 | * by the client, and invalidates all response pointers that might |
michael@0 | 232 | * have been returned by SEC_HttpRequest_TrySendAndReceiveFcn |
michael@0 | 233 | */ |
michael@0 | 234 | typedef SECStatus (*SEC_HttpRequest_FreeFcn)( |
michael@0 | 235 | SEC_HTTP_REQUEST_SESSION request); |
michael@0 | 236 | |
michael@0 | 237 | typedef struct SEC_HttpClientFcnV1Struct { |
michael@0 | 238 | SEC_HttpServer_CreateSessionFcn createSessionFcn; |
michael@0 | 239 | SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn; |
michael@0 | 240 | SEC_HttpServer_FreeSessionFcn freeSessionFcn; |
michael@0 | 241 | SEC_HttpRequest_CreateFcn createFcn; |
michael@0 | 242 | SEC_HttpRequest_SetPostDataFcn setPostDataFcn; |
michael@0 | 243 | SEC_HttpRequest_AddHeaderFcn addHeaderFcn; |
michael@0 | 244 | SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn; |
michael@0 | 245 | SEC_HttpRequest_CancelFcn cancelFcn; |
michael@0 | 246 | SEC_HttpRequest_FreeFcn freeFcn; |
michael@0 | 247 | } SEC_HttpClientFcnV1; |
michael@0 | 248 | |
michael@0 | 249 | typedef struct SEC_HttpClientFcnStruct { |
michael@0 | 250 | PRInt16 version; |
michael@0 | 251 | union { |
michael@0 | 252 | SEC_HttpClientFcnV1 ftable1; |
michael@0 | 253 | /* SEC_HttpClientFcnV2 ftable2; */ |
michael@0 | 254 | /* ... */ |
michael@0 | 255 | } fcnTable; |
michael@0 | 256 | } SEC_HttpClientFcn; |
michael@0 | 257 | |
michael@0 | 258 | /* |
michael@0 | 259 | * ocspMode_FailureIsVerificationFailure: |
michael@0 | 260 | * This is the classic behaviour of NSS. |
michael@0 | 261 | * Any OCSP failure is a verification failure (classic mode, default). |
michael@0 | 262 | * Without a good response, OCSP networking will be retried each time |
michael@0 | 263 | * it is required for verifying a cert. |
michael@0 | 264 | * |
michael@0 | 265 | * ocspMode_FailureIsNotAVerificationFailure: |
michael@0 | 266 | * If we fail to obtain a valid OCSP response, consider the |
michael@0 | 267 | * cert as good. |
michael@0 | 268 | * Failed OCSP attempts might get cached and not retried until |
michael@0 | 269 | * minimumSecondsToNextFetchAttempt. |
michael@0 | 270 | * If we are able to obtain a valid response, the cert |
michael@0 | 271 | * will be considered good, if either status is "good" |
michael@0 | 272 | * or the cert was not yet revoked at verification time. |
michael@0 | 273 | * |
michael@0 | 274 | * Additional failure modes might be added in the future. |
michael@0 | 275 | */ |
michael@0 | 276 | typedef enum { |
michael@0 | 277 | ocspMode_FailureIsVerificationFailure = 0, |
michael@0 | 278 | ocspMode_FailureIsNotAVerificationFailure = 1 |
michael@0 | 279 | } SEC_OcspFailureMode; |
michael@0 | 280 | |
michael@0 | 281 | /* |
michael@0 | 282 | * A ResponderID identifies the responder -- or more correctly, the |
michael@0 | 283 | * signer of the response. The ASN.1 definition of a ResponderID is: |
michael@0 | 284 | * |
michael@0 | 285 | * ResponderID ::= CHOICE { |
michael@0 | 286 | * byName [1] EXPLICIT Name, |
michael@0 | 287 | * byKey [2] EXPLICIT KeyHash } |
michael@0 | 288 | * |
michael@0 | 289 | * Because it is CHOICE, the type of identification used and the |
michael@0 | 290 | * identification itself are actually encoded together. To represent |
michael@0 | 291 | * this same information internally, we explicitly define a type and |
michael@0 | 292 | * save it, along with the value, into a data structure. |
michael@0 | 293 | */ |
michael@0 | 294 | |
michael@0 | 295 | typedef enum { |
michael@0 | 296 | ocspResponderID_other = -1, /* unknown kind of responderID */ |
michael@0 | 297 | ocspResponderID_byName = 1, |
michael@0 | 298 | ocspResponderID_byKey = 2 |
michael@0 | 299 | } CERTOCSPResponderIDType; |
michael@0 | 300 | |
michael@0 | 301 | #endif /* _OCSPT_H_ */ |