#ifndef _TLS_H_INCLUDED_
#define _TLS_H_INCLUDED_
#include <name_code.h>
#include <argv.h>
#define TLS_LEV_INVALID -2
#define TLS_LEV_NOTFOUND -1
#define TLS_LEV_NONE 0
#define TLS_LEV_MAY 1
#define TLS_LEV_ENCRYPT 2
#define TLS_LEV_FPRINT 3
#define TLS_LEV_HALF_DANE 4
#define TLS_LEV_DANE 5
#define TLS_LEV_DANE_ONLY 6
#define TLS_LEV_VERIFY 7
#define TLS_LEV_SECURE 8
#define TLS_REQUIRED(l) ((l) > TLS_LEV_MAY)
#define TLS_MUST_MATCH(l) ((l) > TLS_LEV_ENCRYPT)
#define TLS_MUST_TRUST(l) ((l) >= TLS_LEV_HALF_DANE)
#define TLS_MUST_PKIX(l) ((l) >= TLS_LEV_VERIFY)
#define TLS_OPPORTUNISTIC(l) ((l) == TLS_LEV_MAY || (l) == TLS_LEV_DANE)
#define TLS_DANE_BASED(l) \
((l) >= TLS_LEV_HALF_DANE && (l) <= TLS_LEV_DANE_ONLY)
#define TLS_NEVER_SECURED(l) ((l) == TLS_LEV_HALF_DANE)
extern int tls_level_lookup(const char *);
extern const char *str_tls_level(int);
#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/crypto.h>
#include <openssl/opensslv.h>
#include <openssl/ssl.h>
#define x509_stack_t STACK_OF(X509)
#define general_name_stack_t STACK_OF(GENERAL_NAME)
#define ssl_cipher_stack_t STACK_OF(SSL_CIPHER)
#define ssl_comp_stack_t STACK_OF(SSL_COMP)
#if (OPENSSL_VERSION_NUMBER < 0x00090700f)
#error "need OpenSSL version 0.9.7 or later"
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define OpenSSL_version_num SSLeay
#define OpenSSL_version SSLeay_version
#define OPENSSL_VERSION SSLEAY_VERSION
#define X509_up_ref(x) \
CRYPTO_add(&((x)->references), 1, CRYPTO_LOCK_X509)
#define EVP_PKEY_up_ref(k) \
CRYPTO_add(&((k)->references), 1, CRYPTO_LOCK_EVP_PKEY)
#define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert)
#define X509_STORE_CTX_get0_untrusted(ctx) ((ctx)->untrusted)
#define X509_STORE_CTX_set0_untrusted X509_STORE_CTX_set_chain
#define X509_STORE_CTX_set0_trusted_stack X509_STORE_CTX_trusted_stack
#define ASN1_STRING_get0_data ASN1_STRING_data
#define X509_getm_notBefore X509_get_notBefore
#define X509_getm_notAfter X509_get_notAfter
#define TLS_method SSLv23_method
#define TLS_client_method SSLv23_client_method
#define TLS_server_method SSLv23_server_method
#endif
#if OPENSSL_VERSION_NUMBER >= 0x0090707fL
#define SSL_CIPHER_const const
#else
#define SSL_CIPHER_const
#endif
#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
#define D2I_const const
#else
#define D2I_const
#endif
#include <vstream.h>
#include <name_mask.h>
#include <name_code.h>
#include <dns.h>
#define TLS_MGR_SCACHE_SMTPD "smtpd"
#define TLS_MGR_SCACHE_SMTP "smtp"
#define TLS_MGR_SCACHE_LMTP "lmtp"
#define TLS_DANE_TA 0
#define TLS_DANE_EE 1
#define TLS_DANE_CERT 0
#define TLS_DANE_PKEY 1
#define TLS_DANE_FLAG_NORRS (1<<0)
#define TLS_DANE_FLAG_EMPTY (1<<1)
#define TLS_DANE_FLAG_ERROR (1<<2)
#define tls_dane_unusable(dane) ((dane)->flags & TLS_DANE_FLAG_EMPTY)
#define tls_dane_notfound(dane) ((dane)->flags & TLS_DANE_FLAG_NORRS)
#define TLS_DANE_CACHE_TTL_MIN 1
#define TLS_DANE_CACHE_TTL_MAX 100
typedef struct TLS_TLSA {
char *mdalg;
ARGV *certs;
ARGV *pkeys;
struct TLS_TLSA *next;
} TLS_TLSA;
typedef struct TLS_CERTS {
X509 *cert;
struct TLS_CERTS *next;
} TLS_CERTS;
typedef struct TLS_PKEYS {
EVP_PKEY *pkey;
struct TLS_PKEYS *next;
} TLS_PKEYS;
typedef struct TLS_DANE {
TLS_TLSA *ta;
TLS_TLSA *ee;
TLS_CERTS *certs;
TLS_PKEYS *pkeys;
char *base_domain;
int flags;
time_t expires;
int refs;
} TLS_DANE;
#define TLS_DANE_HASTA(d) ((d) ? (d)->ta : 0)
#define TLS_DANE_HASEE(d) ((d) ? (d)->ee : 0)
extern int tls_dane_avail(void);
extern void tls_dane_flush(void);
extern void tls_dane_verbose(int);
extern TLS_DANE *tls_dane_alloc(void);
extern void tls_dane_add_ee_digests(TLS_DANE *, const char *, const char *,
const char *);
extern void tls_dane_free(TLS_DANE *);
extern TLS_DANE *tls_dane_resolve(unsigned, const char *, DNS_RR *, int);
extern int tls_dane_load_trustfile(TLS_DANE *, const char *);
#define CCERT_BUFSIZ 256
typedef struct {
char *peer_CN;
char *issuer_CN;
char *peer_cert_fprint;
char *peer_pkey_fprint;
int peer_status;
const char *protocol;
const char *cipher_name;
int cipher_usebits;
int cipher_algbits;
SSL *con;
char *cache_type;
int ticketed;
char *serverid;
char *namaddr;
int log_mask;
int session_reused;
int am_server;
const char *mdalg;
VSTREAM *stream;
const TLS_DANE *dane;
int errordepth;
int tadepth;
int errorcode;
X509 *errorcert;
x509_stack_t *untrusted;
x509_stack_t *trusted;
} TLS_SESS_STATE;
#define TLS_CERT_FLAG_PRESENT (1<<0)
#define TLS_CERT_FLAG_ALTNAME (1<<1)
#define TLS_CERT_FLAG_TRUSTED (1<<2)
#define TLS_CERT_FLAG_MATCHED (1<<3)
#define TLS_CERT_FLAG_SECURED (1<<4)
#define TLS_CERT_IS_PRESENT(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_PRESENT))
#define TLS_CERT_IS_ALTNAME(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_ALTNAME))
#define TLS_CERT_IS_TRUSTED(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_TRUSTED))
#define TLS_CERT_IS_MATCHED(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_MATCHED))
#define TLS_CERT_IS_SECURED(c) ((c) && ((c)->peer_status&TLS_CERT_FLAG_SECURED))
typedef struct TLS_APPL_STATE TLS_APPL_STATE;
#ifdef TLS_INTERNAL
extern int tls_log_mask(const char *, const char *);
#define TLS_LOG_NONE (1<<0)
#define TLS_LOG_SUMMARY (1<<1)
#define TLS_LOG_UNTRUSTED (1<<2)
#define TLS_LOG_PEERCERT (1<<3)
#define TLS_LOG_CERTMATCH (1<<4)
#define TLS_LOG_VERBOSE (1<<5)
#define TLS_LOG_CACHE (1<<6)
#define TLS_LOG_DEBUG (1<<7)
#define TLS_LOG_TLSPKTS (1<<8)
#define TLS_LOG_ALLPKTS (1<<9)
struct TLS_APPL_STATE {
SSL_CTX *ssl_ctx;
int log_mask;
char *cache_type;
char *cipher_exclusions;
char *cipher_list;
int cipher_grade;
VSTRING *why;
};
extern void tls_update_app_logmask(TLS_APPL_STATE *, int);
extern void tls_free_app_context(TLS_APPL_STATE *);
extern void tls_param_init(void);
#define TLS_PROTOCOL_INVALID (~0)
#ifdef SSL_TXT_SSLV2
#define TLS_PROTOCOL_SSLv2 (1<<0)
#else
#define SSL_TXT_SSLV2 "SSLv2"
#define TLS_PROTOCOL_SSLv2 0
#undef SSL_OP_NO_SSLv2
#define SSL_OP_NO_SSLv2 0L
#endif
#ifdef SSL_TXT_SSLV3
#define TLS_PROTOCOL_SSLv3 (1<<1)
#else
#define SSL_TXT_SSLV3 "SSLv3"
#define TLS_PROTOCOL_SSLv3 0
#undef SSL_OP_NO_SSLv3
#define SSL_OP_NO_SSLv3 0L
#endif
#ifdef SSL_TXT_TLSV1
#define TLS_PROTOCOL_TLSv1 (1<<2)
#else
#define SSL_TXT_TLSV1 "TLSv1"
#define TLS_PROTOCOL_TLSv1 0
#undef SSL_OP_NO_TLSv1
#define SSL_OP_NO_TLSv1 0L
#endif
#ifdef SSL_TXT_TLSV1_1
#define TLS_PROTOCOL_TLSv1_1 (1<<3)
#else
#define SSL_TXT_TLSV1_1 "TLSv1.1"
#define TLS_PROTOCOL_TLSv1_1 0
#undef SSL_OP_NO_TLSv1_1
#define SSL_OP_NO_TLSv1_1 0L
#endif
#ifdef SSL_TXT_TLSV1_2
#define TLS_PROTOCOL_TLSv1_2 (1<<4)
#else
#define SSL_TXT_TLSV1_2 "TLSv1.2"
#define TLS_PROTOCOL_TLSv1_2 0
#undef SSL_OP_NO_TLSv1_2
#define SSL_OP_NO_TLSv1_2 0L
#endif
#ifdef SSL_TXT_TLSV1_3
#define TLS_PROTOCOL_TLSv1_3 (1<<5)
#else
#define SSL_TXT_TLSV1_3 "TLSv1.3"
#define TLS_PROTOCOL_TLSv1_3 0
#undef SSL_OP_NO_TLSv1_3
#define SSL_OP_NO_TLSv1_3 0L
#endif
#define TLS_KNOWN_PROTOCOLS \
( TLS_PROTOCOL_SSLv2 | TLS_PROTOCOL_SSLv3 | TLS_PROTOCOL_TLSv1 \
| TLS_PROTOCOL_TLSv1_1 | TLS_PROTOCOL_TLSv1_2 )
#define TLS_SSL_OP_PROTOMASK(m) \
((((m) & TLS_PROTOCOL_SSLv2) ? SSL_OP_NO_SSLv2 : 0L) \
| (((m) & TLS_PROTOCOL_SSLv3) ? SSL_OP_NO_SSLv3 : 0L) \
| (((m) & TLS_PROTOCOL_TLSv1) ? SSL_OP_NO_TLSv1 : 0L) \
| (((m) & TLS_PROTOCOL_TLSv1_1) ? SSL_OP_NO_TLSv1_1 : 0L) \
| (((m) & TLS_PROTOCOL_TLSv1_2) ? SSL_OP_NO_TLSv1_2 : 0L) \
| (((m) & TLS_PROTOCOL_TLSv1_3) ? SSL_OP_NO_TLSv1_3 : 0L))
#define TLS_SSL_OP_MANAGED_BITS \
(SSL_OP_CIPHER_SERVER_PREFERENCE | TLS_SSL_OP_PROTOMASK(~0))
extern int tls_protocol_mask(const char *);
#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 const NAME_CODE tls_cipher_grade_table[];
#define tls_cipher_grade(str) \
name_code(tls_cipher_grade_table, NAME_CODE_FLAG_NONE, (str))
#define str_tls_cipher_grade(gr) \
str_name_code(tls_cipher_grade_table, (gr))
extern const char *tls_set_ciphers(TLS_APPL_STATE *, const char *,
const char *, const char *);
#endif
typedef struct {
const char *log_param;
const char *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 *eccert_file;
const char *eckey_file;
const char *CAfile;
const char *CApath;
const char *mdalg;
} TLS_CLIENT_INIT_PROPS;
typedef struct {
TLS_APPL_STATE *ctx;
VSTREAM *stream;
int timeout;
int tls_level;
const char *nexthop;
const char *host;
const char *namaddr;
const char *serverid;
const char *helo;
const char *protocols;
const char *cipher_grade;
const char *cipher_exclusions;
const ARGV *matchargv;
const char *mdalg;
const TLS_DANE *dane;
} TLS_CLIENT_START_PROPS;
extern TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *);
extern TLS_SESS_STATE *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))
#define TLS_CLIENT_INIT(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \
a10, a11, a12, a13) \
tls_client_init((((props)->a1), ((props)->a2), ((props)->a3), \
((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
((props)->a12), ((props)->a13), (props)))
#define TLS_CLIENT_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \
a10, a11, a12, a13, a14, a15) \
tls_client_start((((props)->a1), ((props)->a2), ((props)->a3), \
((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), (props)))
typedef struct {
const char *log_param;
const char *log_level;
int verifydepth;
const char *cache_type;
int set_sessid;
const char *cert_file;
const char *key_file;
const char *dcert_file;
const char *dkey_file;
const char *eccert_file;
const char *eckey_file;
const char *CAfile;
const char *CApath;
const char *protocols;
const char *eecdh_grade;
const char *dh1024_param_file;
const char *dh512_param_file;
int ask_ccert;
const char *mdalg;
} TLS_SERVER_INIT_PROPS;
typedef struct {
TLS_APPL_STATE *ctx;
VSTREAM *stream;
int fd;
int timeout;
int requirecert;
const char *serverid;
const char *namaddr;
const char *cipher_grade;
const char *cipher_exclusions;
const char *mdalg;
} TLS_SERVER_START_PROPS;
extern TLS_APPL_STATE *tls_server_init(const TLS_SERVER_INIT_PROPS *);
extern TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props);
extern TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *);
#define tls_server_stop(ctx, stream, timeout, failure, TLScontext) \
tls_session_stop(ctx, (stream), (timeout), (failure), (TLScontext))
#define TLS_SERVER_INIT(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, \
a10, a11, a12, a13, a14, a15, a16, a17, a18, a19) \
tls_server_init((((props)->a1), ((props)->a2), ((props)->a3), \
((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), \
((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \
((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), (props)))
#define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \
tls_server_start((((props)->a1), ((props)->a2), ((props)->a3), \
((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \
((props)->a8), ((props)->a9), ((props)->a10), (props)))
extern void tls_session_stop(TLS_APPL_STATE *, VSTREAM *, int, int, TLS_SESS_STATE *);
extern const char *tls_compile_version(void);
extern const char *tls_run_version(void);
extern const char **tls_pkey_algorithms(void);
#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 *, TLS_SESS_STATE *);
extern void tls_stream_stop(VSTREAM *);
extern int tls_bio(int, int, TLS_SESS_STATE *,
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_from_file(const char *, int);
extern DH *tls_tmp_dh_cb(SSL *, int, int);
extern void tls_set_eecdh_curve(SSL_CTX *, const char *);
extern void tls_auto_eecdh_curves(SSL_CTX *);
extern RSA *tls_tmp_rsa_cb(SSL *, int, int);
extern char *tls_peer_CN(X509 *, const TLS_SESS_STATE *);
extern char *tls_issuer_CN(X509 *, const TLS_SESS_STATE *);
extern const char *tls_dns_name(const GENERAL_NAME *, const TLS_SESS_STATE *);
extern int tls_verify_certificate_callback(int, X509_STORE_CTX *);
extern void tls_log_verify_error(TLS_SESS_STATE *);
extern int tls_dane_match(TLS_SESS_STATE *, int, X509 *, int);
extern void tls_dane_set_callback(SSL_CTX *, TLS_SESS_STATE *);
extern char *tls_digest_encode(const unsigned char *, int);
extern char *tls_data_fprint(const char *, int, const char *);
extern char *tls_cert_fprint(X509 *, const char *);
extern char *tls_pkey_fprint(X509 *, const char *);
extern char *tls_serverid_digest(const TLS_CLIENT_START_PROPS *, long,
const char *);
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 *,
const char *, const char *);
extern int TLScontext_index;
extern TLS_APPL_STATE *tls_alloc_app_context(SSL_CTX *, int);
extern TLS_SESS_STATE *tls_alloc_sess_context(int, const char *);
extern void tls_free_context(TLS_SESS_STATE *);
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 int tls_validate_digest(const char *);
extern void tls_int_seed(void);
extern int tls_ext_seed(int);
#endif
#endif
#endif