#ifndef _TLS_H_INCLUDED_
#define _TLS_H_INCLUDED_
#include <name_code.h>
#define TLS_LEV_NOTFOUND -1
#define TLS_LEV_NONE 0
#define TLS_LEV_MAY 1
#define TLS_LEV_ENCRYPT 2
#define TLS_LEV_VERIFY 3
#define TLS_LEV_SECURE 4
extern NAME_CODE tls_level_table[];
#define tls_level_lookup(s) name_code(tls_level_table, NAME_CODE_FLAG_NONE, (s))
#define str_tls_level(l) str_name_code(tls_level_table, (l))
#ifdef USE_TLS
#include <openssl/lhash.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
#error "need OpenSSL version 0.9.5 or later"
#endif
#include <vstream.h>
#include <name_mask.h>
#include <name_code.h>
#define TLS_BIO_BUFSIZE 8192
#define TLS_MGR_SCACHE_SMTPD "smtpd"
#define TLS_MGR_SCACHE_SMTP "smtp"
#define TLS_MGR_SCACHE_LMTP "lmtp"
#define CCERT_BUFSIZ 256
typedef struct {
SSL *con;
BIO *internal_bio;
BIO *network_bio;
char *cache_type;
char *serverid;
char *peer_CN;
char *issuer_CN;
char *peer_fingerprint;
char *peername;
int enforce_verify_errors;
int enforce_CN;
int hostname_matched;
int peer_verified;
const char *protocol;
const char *cipher_name;
int cipher_usebits;
int cipher_algbits;
int log_level;
int session_reused;
} TLScontext_t;
#define TLS_PROTOCOL_SSLv2 (1<<0)
#define TLS_PROTOCOL_SSLv3 (1<<1)
#define TLS_PROTOCOL_TLSv1 (1<<2)
#define TLS_ALL_PROTOCOLS \
( TLS_PROTOCOL_SSLv2 | TLS_PROTOCOL_SSLv3 | TLS_PROTOCOL_TLSv1 )
#define TLS_CIPHER_NONE 0
#define TLS_CIPHER_NULL 1
#define TLS_CIPHER_EXPORT 2
#define TLS_CIPHER_LOW 3
#define TLS_CIPHER_MEDIUM 4
#define TLS_CIPHER_HIGH 5
extern NAME_MASK tls_protocol_table[];
extern NAME_CODE tls_cipher_level_table[];
#define tls_protocol_mask(tag, protocols) \
name_mask_delim_opt((tag), tls_protocol_table, (protocols), \
":" NAME_MASK_DEFAULT_DELIM, \
NAME_MASK_ANY_CASE | NAME_MASK_RETURN)
#define tls_protocol_names(tag, mask) \
str_name_mask_opt((VSTRING *)0, (tag), tls_protocol_table, (mask), \
NAME_MASK_FATAL|NAME_MASK_COMMA)
#define tls_cipher_level(str) \
name_code(tls_cipher_level_table, NAME_CODE_FLAG_NONE, (str))
#define TLS_END_EXCLUDE ((char *)0)
extern const char *tls_cipher_list(int,...);
extern const char *tls_set_cipher_list(SSL_CTX *, const char *);
typedef struct {
int log_level;
int verifydepth;
const char *cache_type;
const char *cert_file;
const char *key_file;
const char *dcert_file;
const char *dkey_file;
const char *CAfile;
const char *CApath;
} tls_client_init_props;
typedef struct {
SSL_CTX *ctx;
VSTREAM *stream;
int log_level;
int timeout;
int tls_level;
char *nexthop;
char *host;
char *serverid;
int protocols;
char *cipherlist;
char *certmatch;
} tls_client_start_props;
extern SSL_CTX *tls_client_init(const tls_client_init_props *);
extern TLScontext_t *tls_client_start(const tls_client_start_props *);
#define tls_client_stop(ctx , stream, timeout, failure, TLScontext) \
tls_session_stop((ctx), (stream), (timeout), (failure), (TLScontext))
typedef struct {
int log_level;
int verifydepth;
const char *cache_type;
long scache_timeout;
int set_sessid;
const char *cert_file;
const char *key_file;
const char *dcert_file;
const char *dkey_file;
const char *CAfile;
const char *CApath;
const char *cipherlist;
int protocols;
const char *dh1024_param_file;
const char *dh512_param_file;
int ask_ccert;
} tls_server_props;
typedef struct {
SSL_CTX *ctx;
VSTREAM *stream;
int log_level;
int timeout;
int requirecert;
char *serverid;
char *peername;
char *peeraddr;
} tls_server_start_props;
extern SSL_CTX *tls_server_init(const tls_server_props *);
extern TLScontext_t *tls_server_start(const tls_server_start_props *props);
#define tls_server_stop(ctx , stream, timeout, failure, TLScontext) \
tls_session_stop((ctx), (stream), (timeout), (failure), (TLScontext))
extern void tls_session_stop(SSL_CTX *, VSTREAM *, int, int,
TLScontext_t *);
#ifdef TLS_INTERNAL
#include <vstring.h>
extern VSTRING *tls_session_passivate(SSL_SESSION *);
extern SSL_SESSION *tls_session_activate(const char *, int);
extern void tls_stream_start(VSTREAM *, TLScontext_t *);
extern void tls_stream_stop(VSTREAM *);
extern int tls_bio(int, int, TLScontext_t *,
int (*) (SSL *),
int (*) (SSL *, void *, int),
int (*) (SSL *, const void *, int),
void *, int);
#define tls_bio_connect(fd, timeout, context) \
tls_bio((fd), (timeout), (context), SSL_connect, \
NULL, NULL, NULL, 0)
#define tls_bio_accept(fd, timeout, context) \
tls_bio((fd), (timeout), (context), SSL_accept, \
NULL, NULL, NULL, 0)
#define tls_bio_shutdown(fd, timeout, context) \
tls_bio((fd), (timeout), (context), SSL_shutdown, \
NULL, NULL, NULL, 0)
#define tls_bio_read(fd, buf, len, timeout, context) \
tls_bio((fd), (timeout), (context), NULL, \
SSL_read, NULL, (buf), (len))
#define tls_bio_write(fd, buf, len, timeout, context) \
tls_bio((fd), (timeout), (context), NULL, \
NULL, SSL_write, (buf), (len))
extern void tls_set_dh_1024_from_file(const char *);
extern void tls_set_dh_512_from_file(const char *);
extern DH *tls_tmp_dh_cb(SSL *, int, int);
extern RSA *tls_tmp_rsa_cb(SSL *, int, int);
extern char *tls_peer_CN(X509 *);
extern char *tls_issuer_CN(X509 *);
extern int tls_verify_certificate_callback(int, X509_STORE_CTX *);
extern int tls_set_ca_certificate_info(SSL_CTX *, const char *, const char *);
extern int tls_set_my_certificate_key_info(SSL_CTX *, const char *,
const char *,
const char *,
const char *);
extern int TLScontext_index;
extern int TLSscache_index;
extern TLScontext_t *tls_alloc_context(int, const char *);
extern void tls_free_context(TLScontext_t *);
extern void tls_check_version(void);
extern long tls_bug_bits(void);
extern void tls_print_errors(void);
extern void tls_info_callback(const SSL *, int, int);
extern long tls_bio_dump_cb(BIO *, int, const char *, int, long, long);
extern void tls_int_seed(void);
extern int tls_ext_seed(int);
#endif
#endif
#endif