iostream-ssl.h revision 976dee5384c4827dc648c9bc53825390521c388e
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi#ifndef IOSTREAM_SSL_H
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi#define IOSTREAM_SSL_H
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
9f63060b0f4231438f82a6b8056ffb2e5befcc2drbowenstruct ssl_iostream;
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashistruct ssl_iostream_context;
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashistruct ssl_iostream_cert {
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *cert;
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *key;
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *key_password;
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi};
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashistruct ssl_iostream_settings {
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi /* NOTE: when updating, remember to update:
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi ssl_iostream_settings_string_offsets[],
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi ssl_iostream_settings_drop_stream_only() */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *min_protocol; /* both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *cipher_list; /* both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *curve_list; /* both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *ca, *ca_file, *ca_dir; /* context-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi /* alternative cert is for providing certificate using
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi different key algorithm */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi struct ssl_iostream_cert cert; /* both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi struct ssl_iostream_cert alt_cert; /* both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *dh; /* context-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *cert_username_field; /* both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *crypto_device; /* context-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi bool verbose, verbose_invalid_cert; /* stream-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi bool skip_crl_check; /* context-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi bool verify_remote_cert; /* neither/both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi bool allow_invalid_cert; /* stream-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi bool prefer_server_ciphers; /* both */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi bool compression; /* context-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi bool tickets; /* context-only */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi};
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Load SSL module */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashiint ssl_module_load(const char **error_r);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Returns 0 if ok, -1 and sets error_r if failed. The returned error string
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi becomes available via ssl_iostream_get_last_error(). The callback most
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi likely should be calling ssl_iostream_check_cert_validity(). */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashitypedef int
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashissl_iostream_handshake_callback_t(const char **error_r, void *context);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Called when TLS SNI becomes available. */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashitypedef int ssl_iostream_sni_callback_t(const char *name, const char **error_r,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi void *context);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Explicitly initialize SSL library globally. This is also done automatically
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi when the first SSL connection is created, but it may be useful to call it
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi earlier in case of chrooting. After the initialization is successful, any
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi further calls will just be ignored. Returns 0 on success, -1 on error. */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashiint io_stream_ssl_global_init(const struct ssl_iostream_settings *set,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char **error_r);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashiint io_stream_create_ssl_client(struct ssl_iostream_context *ctx, const char *host,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const struct ssl_iostream_settings *set,
6687002a066d64aaa3a076a2cebf8ca517276f17takashi struct istream **input, struct ostream **output,
6687002a066d64aaa3a076a2cebf8ca517276f17takashi struct ssl_iostream **iostream_r,
6687002a066d64aaa3a076a2cebf8ca517276f17takashi const char **error_r);
99cef7b4ddb1c9b2a05ea664fc04dcc83a63e8benilgunint io_stream_create_ssl_server(struct ssl_iostream_context *ctx,
99cef7b4ddb1c9b2a05ea664fc04dcc83a63e8benilgun const struct ssl_iostream_settings *set,
99cef7b4ddb1c9b2a05ea664fc04dcc83a63e8benilgun struct istream **input, struct ostream **output,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi struct ssl_iostream **iostream_r,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char **error_r);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* returned input and output streams must also be unreferenced */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashivoid ssl_iostream_unref(struct ssl_iostream **ssl_io);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* shutdown SSL connection and unreference ssl iostream */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashivoid ssl_iostream_destroy(struct ssl_iostream **ssl_io);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* If verbose logging is enabled, use the specified log prefix */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashivoid ssl_iostream_set_log_prefix(struct ssl_iostream *ssl_io,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *prefix);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashiint ssl_iostream_handshake(struct ssl_iostream *ssl_io);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Call the given callback when SSL handshake finishes. The callback must
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi verify whether the certificate and its hostname is valid. If there is no
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi callback, the default is to use ssl_iostream_check_cert_validity() with the
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi same host as given to io_stream_create_ssl_client() */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashivoid ssl_iostream_set_handshake_callback(struct ssl_iostream *ssl_io,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi ssl_iostream_handshake_callback_t *callback,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi void *context);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Call the given callback when client sends SNI. The callback can change the
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi ssl_iostream's context (with different certificates) by using
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi ssl_iostream_change_context(). */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashivoid ssl_iostream_set_sni_callback(struct ssl_iostream *ssl_io,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi ssl_iostream_sni_callback_t *callback,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi void *context);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashivoid ssl_iostream_change_context(struct ssl_iostream *ssl_io,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi struct ssl_iostream_context *ctx);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashibool ssl_iostream_is_handshaked(const struct ssl_iostream *ssl_io);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Returns TRUE if the remote cert is invalid, or handshake callback returned
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi failure. */
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashibool ssl_iostream_has_handshake_failed(const struct ssl_iostream *ssl_io);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashibool ssl_iostream_has_valid_client_cert(const struct ssl_iostream *ssl_io);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashibool ssl_iostream_has_broken_client_cert(struct ssl_iostream *ssl_io);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashiint ssl_iostream_check_cert_validity(struct ssl_iostream *ssl_io,
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi const char *host, const char **error_r);
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi/* Returns TRUE if the given name matches the SSL stream's certificate.
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi The returned reason is a human-readable string explaining what exactly
c8015dcc4e7280b5b55144555bb0b734d37fdcc6takashi matched the name, or why nothing matched. Note that this function works
only if the certificate was valid - using it when certificate is invalid
will always return FALSE before even checking the hostname. */
bool ssl_iostream_cert_match_name(struct ssl_iostream *ssl_io, const char *name,
const char **reason_r);
const char *ssl_iostream_get_peer_name(struct ssl_iostream *ssl_io);
const char *ssl_iostream_get_compression(struct ssl_iostream *ssl_io);
const char *ssl_iostream_get_server_name(struct ssl_iostream *ssl_io);
const char *ssl_iostream_get_security_string(struct ssl_iostream *ssl_io);
const char *ssl_iostream_get_last_error(struct ssl_iostream *ssl_io);
int ssl_iostream_context_init_client(const struct ssl_iostream_settings *set,
struct ssl_iostream_context **ctx_r,
const char **error_r);
int ssl_iostream_context_init_server(const struct ssl_iostream_settings *set,
struct ssl_iostream_context **ctx_r,
const char **error_r);
void ssl_iostream_context_ref(struct ssl_iostream_context *ctx);
void ssl_iostream_context_unref(struct ssl_iostream_context **ctx);
struct ssl_iostream_settings *ssl_iostream_settings_dup(pool_t pool,
const struct ssl_iostream_settings *old_set);
void ssl_iostream_settings_init_from(pool_t pool,
struct ssl_iostream_settings *dest,
const struct ssl_iostream_settings *src);
/* Persistent cache of ssl_iostream_contexts. The context is permanently stored
until ssl_iostream_context_cache_free() is called. The returned context
must be unreferenced by the caller. */
int ssl_iostream_client_context_cache_get(const struct ssl_iostream_settings *set,
struct ssl_iostream_context **ctx_r,
const char **error_r);
int ssl_iostream_server_context_cache_get(const struct ssl_iostream_settings *set,
struct ssl_iostream_context **ctx_r,
const char **error_r);
void ssl_iostream_context_cache_free(void);
#endif