michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * Public header for exported OCSP types. michael@0: */ michael@0: michael@0: #ifndef _OCSPT_H_ michael@0: #define _OCSPT_H_ michael@0: michael@0: /* michael@0: * The following are all opaque types. If someone needs to get at michael@0: * a field within, then we need to fix the API. Try very hard not michael@0: * make the type available to them. michael@0: */ michael@0: typedef struct CERTOCSPRequestStr CERTOCSPRequest; michael@0: typedef struct CERTOCSPResponseStr CERTOCSPResponse; michael@0: michael@0: /* michael@0: * XXX I think only those first two above should need to be exported, michael@0: * but until I know for certain I am leaving the rest of these here, too. michael@0: */ michael@0: typedef struct CERTOCSPCertIDStr CERTOCSPCertID; michael@0: typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse; michael@0: michael@0: /* michael@0: * This interface is described in terms of an HttpClient which michael@0: * supports at least a specified set of functions. (An implementer may michael@0: * provide HttpClients with additional functionality accessible only to michael@0: * users with a particular implementation in mind.) The basic behavior michael@0: * is provided by defining a set of functions, listed in an michael@0: * SEC_HttpServerFcnStruct. If the implementor of a SpecificHttpClient michael@0: * registers his SpecificHttpClient as the default HttpClient, then his michael@0: * functions will be called by the user of an HttpClient, such as an michael@0: * OCSPChecker. michael@0: * michael@0: * The implementer of a specific HttpClient (e.g., the NSS-provided michael@0: * DefaultHttpClient), populates an SEC_HttpClientFcnStruct, uses it to michael@0: * register his client, and waits for his functions to be called. michael@0: * michael@0: * For future expandability, the SEC_HttpClientFcnStruct is defined as a michael@0: * union, with the version field acting as a selector. The proposed michael@0: * initial version of the structure is given following the definition michael@0: * of the union. The HttpClientState structure is implementation- michael@0: * dependent, and should be opaque to the user. michael@0: */ michael@0: michael@0: typedef void * SEC_HTTP_SERVER_SESSION; michael@0: typedef void * SEC_HTTP_REQUEST_SESSION; michael@0: michael@0: /* michael@0: * This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a michael@0: * specific HttpClient will allocate the necessary space, when this michael@0: * function is called, and will free it when the corresponding FreeFcn michael@0: * is called. The SEC_HTTP_SERVER_SESSION object is passed, as an opaque object, michael@0: * to subsequent calls. michael@0: * michael@0: * If the function returns SECSuccess, the returned SEC_HTTP_SERVER_SESSION michael@0: * must be cleaned up with a call to SEC_HttpServer_FreeSession, michael@0: * after processing is finished. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)( michael@0: const char *host, michael@0: PRUint16 portnum, michael@0: SEC_HTTP_SERVER_SESSION *pSession); michael@0: michael@0: /* michael@0: * This function is called to allow the implementation to attempt to keep michael@0: * the connection alive. Depending on the underlying platform, it might michael@0: * immediately return SECSuccess without having performed any operations. michael@0: * (If a connection has not been kept alive, a subsequent call to michael@0: * SEC_HttpRequest_TrySendAndReceiveFcn should reopen the connection michael@0: * automatically.) michael@0: * michael@0: * If the connection uses nonblocking I/O, this function may return michael@0: * SECWouldBlock and store a nonzero value at "pPollDesc". In that case michael@0: * the caller may wait on the poll descriptor, and should call this function michael@0: * again until SECSuccess (and a zero value at "pPollDesc") is obtained. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)( michael@0: SEC_HTTP_SERVER_SESSION session, michael@0: PRPollDesc **pPollDesc); michael@0: michael@0: /* michael@0: * This function frees the client SEC_HTTP_SERVER_SESSION object, closes all michael@0: * SEC_HTTP_REQUEST_SESSIONs created for that server, discards all partial results, michael@0: * frees any memory that was allocated by the client, and invalidates any michael@0: * response pointers that might have been returned by prior server or request michael@0: * functions. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)( michael@0: SEC_HTTP_SERVER_SESSION session); michael@0: michael@0: /* michael@0: * This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a michael@0: * specific HttpClient will allocate the necessary space, when this michael@0: * function is called, and will free it when the corresponding FreeFcn michael@0: * is called. The SEC_HTTP_REQUEST_SESSION object is passed, as an opaque object, michael@0: * to subsequent calls. michael@0: * michael@0: * An implementation that does not support the requested protocol variant michael@0: * (usually "http", but could eventually allow "https") or request method michael@0: * should return SECFailure. michael@0: * michael@0: * Timeout values may include the constants PR_INTERVAL_NO_TIMEOUT (wait michael@0: * forever) or PR_INTERVAL_NO_WAIT (nonblocking I/O). michael@0: * michael@0: * If the function returns SECSuccess, the returned SEC_HTTP_REQUEST_SESSION michael@0: * must be cleaned up with a call to SEC_HttpRequest_FreeSession, michael@0: * after processing is finished. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpRequest_CreateFcn)( michael@0: SEC_HTTP_SERVER_SESSION session, michael@0: const char *http_protocol_variant, /* usually "http" */ michael@0: const char *path_and_query_string, michael@0: const char *http_request_method, michael@0: const PRIntervalTime timeout, michael@0: SEC_HTTP_REQUEST_SESSION *pRequest); michael@0: michael@0: /* michael@0: * This function sets data to be sent to the server for an HTTP request michael@0: * of http_request_method == POST. If a particular implementation michael@0: * supports it, the details for the POST request can be set by calling michael@0: * this function, prior to activating the request with TrySendAndReceiveFcn. michael@0: * michael@0: * An implementation that does not support the POST method should michael@0: * implement a SetPostDataFcn function that returns immediately. michael@0: * michael@0: * Setting http_content_type is optional, the parameter may michael@0: * by NULL or the empty string. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)( michael@0: SEC_HTTP_REQUEST_SESSION request, michael@0: const char *http_data, michael@0: const PRUint32 http_data_len, michael@0: const char *http_content_type); michael@0: michael@0: /* michael@0: * This function sets an additional HTTP protocol request header. michael@0: * If a particular implementation supports it, one or multiple headers michael@0: * can be added to the request by calling this function once or multiple michael@0: * times, prior to activating the request with TryFcn. michael@0: * michael@0: * An implementation that does not support setting additional headers michael@0: * should implement an AddRequestHeaderFcn function that returns immediately. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)( michael@0: SEC_HTTP_REQUEST_SESSION request, michael@0: const char *http_header_name, michael@0: const char *http_header_value); michael@0: michael@0: /* michael@0: * This function initiates or continues an HTTP request. After michael@0: * parameters have been set with the Create function and, optionally, michael@0: * modified or enhanced with the AddParams function, this call creates michael@0: * the socket connection and initiates the communication. michael@0: * michael@0: * If a timeout value of zero is specified, indicating non-blocking michael@0: * I/O, the client creates a non-blocking socket, and returns a status michael@0: * of SECWouldBlock and a non-NULL PRPollDesc if the operation is not michael@0: * complete. In that case all other return parameters are undefined. michael@0: * The caller is expected to repeat the call, possibly after using michael@0: * PRPoll to determine that a completion has occurred, until a return michael@0: * value of SECSuccess (and a NULL value for pPollDesc) or a return michael@0: * value of SECFailure (indicating failure on the network level) michael@0: * is obtained. michael@0: * michael@0: * http_response_data_len is both input and output parameter. michael@0: * If a pointer to a PRUint32 is supplied, the http client is michael@0: * expected to check the given integer value and always set an out michael@0: * value, even on failure. michael@0: * An input value of zero means, the caller will accept any response len. michael@0: * A different input value indicates the maximum response value acceptable michael@0: * to the caller. michael@0: * If data is successfully read and the size is acceptable to the caller, michael@0: * the function will return SECSuccess and set http_response_data_len to michael@0: * the size of the block returned in http_response_data. michael@0: * If the data read from the http server is larger than the acceptable michael@0: * size, the function will return SECFailure. michael@0: * http_response_data_len will be set to a value different from zero to michael@0: * indicate the reason of the failure. michael@0: * An out value of "0" means, the failure was unrelated to the michael@0: * acceptable size. michael@0: * An out value of "1" means, the result data is larger than the michael@0: * accpeptable size, but the real size is not yet known to the http client michael@0: * implementation and it stopped retrieving it, michael@0: * Any other out value combined with a return value of SECFailure michael@0: * will indicate the actual size of the server data. michael@0: * michael@0: * The caller is permitted to provide NULL values for any of the michael@0: * http_response arguments, indicating the caller is not interested in michael@0: * those values. If the caller does provide an address, the HttpClient michael@0: * stores at that address a pointer to the corresponding argument, at michael@0: * the completion of the operation. michael@0: * michael@0: * All returned pointers will be owned by the the HttpClient michael@0: * implementation and will remain valid until the call to michael@0: * SEC_HttpRequest_FreeFcn. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)( michael@0: SEC_HTTP_REQUEST_SESSION request, michael@0: PRPollDesc **pPollDesc, michael@0: PRUint16 *http_response_code, michael@0: const char **http_response_content_type, michael@0: const char **http_response_headers, michael@0: const char **http_response_data, michael@0: PRUint32 *http_response_data_len); michael@0: michael@0: /* michael@0: * Calling CancelFcn asks for premature termination of the request. michael@0: * michael@0: * Future calls to SEC_HttpRequest_TrySendAndReceive should michael@0: * by avoided, but in this case the HttpClient implementation michael@0: * is expected to return immediately with SECFailure. michael@0: * michael@0: * After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn michael@0: * is still necessary to free resources. michael@0: */ michael@0: typedef SECStatus (*SEC_HttpRequest_CancelFcn)( michael@0: SEC_HTTP_REQUEST_SESSION request); michael@0: michael@0: /* michael@0: * Before calling this function, it must be assured the request michael@0: * has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has michael@0: * returned SECSuccess, or the request has been canceled with michael@0: * a call to SEC_HttpRequest_CancelFcn. michael@0: * michael@0: * This function frees the client state object, closes all sockets, michael@0: * discards all partial results, frees any memory that was allocated michael@0: * by the client, and invalidates all response pointers that might michael@0: * have been returned by SEC_HttpRequest_TrySendAndReceiveFcn michael@0: */ michael@0: typedef SECStatus (*SEC_HttpRequest_FreeFcn)( michael@0: SEC_HTTP_REQUEST_SESSION request); michael@0: michael@0: typedef struct SEC_HttpClientFcnV1Struct { michael@0: SEC_HttpServer_CreateSessionFcn createSessionFcn; michael@0: SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn; michael@0: SEC_HttpServer_FreeSessionFcn freeSessionFcn; michael@0: SEC_HttpRequest_CreateFcn createFcn; michael@0: SEC_HttpRequest_SetPostDataFcn setPostDataFcn; michael@0: SEC_HttpRequest_AddHeaderFcn addHeaderFcn; michael@0: SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn; michael@0: SEC_HttpRequest_CancelFcn cancelFcn; michael@0: SEC_HttpRequest_FreeFcn freeFcn; michael@0: } SEC_HttpClientFcnV1; michael@0: michael@0: typedef struct SEC_HttpClientFcnStruct { michael@0: PRInt16 version; michael@0: union { michael@0: SEC_HttpClientFcnV1 ftable1; michael@0: /* SEC_HttpClientFcnV2 ftable2; */ michael@0: /* ... */ michael@0: } fcnTable; michael@0: } SEC_HttpClientFcn; michael@0: michael@0: /* michael@0: * ocspMode_FailureIsVerificationFailure: michael@0: * This is the classic behaviour of NSS. michael@0: * Any OCSP failure is a verification failure (classic mode, default). michael@0: * Without a good response, OCSP networking will be retried each time michael@0: * it is required for verifying a cert. michael@0: * michael@0: * ocspMode_FailureIsNotAVerificationFailure: michael@0: * If we fail to obtain a valid OCSP response, consider the michael@0: * cert as good. michael@0: * Failed OCSP attempts might get cached and not retried until michael@0: * minimumSecondsToNextFetchAttempt. michael@0: * If we are able to obtain a valid response, the cert michael@0: * will be considered good, if either status is "good" michael@0: * or the cert was not yet revoked at verification time. michael@0: * michael@0: * Additional failure modes might be added in the future. michael@0: */ michael@0: typedef enum { michael@0: ocspMode_FailureIsVerificationFailure = 0, michael@0: ocspMode_FailureIsNotAVerificationFailure = 1 michael@0: } SEC_OcspFailureMode; michael@0: michael@0: /* michael@0: * A ResponderID identifies the responder -- or more correctly, the michael@0: * signer of the response. The ASN.1 definition of a ResponderID is: michael@0: * michael@0: * ResponderID ::= CHOICE { michael@0: * byName [1] EXPLICIT Name, michael@0: * byKey [2] EXPLICIT KeyHash } michael@0: * michael@0: * Because it is CHOICE, the type of identification used and the michael@0: * identification itself are actually encoded together. To represent michael@0: * this same information internally, we explicitly define a type and michael@0: * save it, along with the value, into a data structure. michael@0: */ michael@0: michael@0: typedef enum { michael@0: ocspResponderID_other = -1, /* unknown kind of responderID */ michael@0: ocspResponderID_byName = 1, michael@0: ocspResponderID_byKey = 2 michael@0: } CERTOCSPResponderIDType; michael@0: michael@0: #endif /* _OCSPT_H_ */