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