1*3e07920fSDavid van Moolenbroek /* $NetBSD: tls.h,v 1.2 2008/11/07 07:36:38 minskim Exp $ */ 2*3e07920fSDavid van Moolenbroek 3*3e07920fSDavid van Moolenbroek /*- 4*3e07920fSDavid van Moolenbroek * Copyright (c) 2008 The NetBSD Foundation, Inc. 5*3e07920fSDavid van Moolenbroek * All rights reserved. 6*3e07920fSDavid van Moolenbroek * 7*3e07920fSDavid van Moolenbroek * This code is derived from software contributed to The NetBSD Foundation 8*3e07920fSDavid van Moolenbroek * by Martin Sch�tte. 9*3e07920fSDavid van Moolenbroek * 10*3e07920fSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without 11*3e07920fSDavid van Moolenbroek * modification, are permitted provided that the following conditions 12*3e07920fSDavid van Moolenbroek * are met: 13*3e07920fSDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright 14*3e07920fSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer. 15*3e07920fSDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright 16*3e07920fSDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the 17*3e07920fSDavid van Moolenbroek * documentation and/or other materials provided with the distribution. 18*3e07920fSDavid van Moolenbroek * 3. All advertising materials mentioning features or use of this software 19*3e07920fSDavid van Moolenbroek * must display the following acknowledgement: 20*3e07920fSDavid van Moolenbroek * This product includes software developed by the NetBSD 21*3e07920fSDavid van Moolenbroek * Foundation, Inc. and its contributors. 22*3e07920fSDavid van Moolenbroek * 4. Neither the name of The NetBSD Foundation nor the names of its 23*3e07920fSDavid van Moolenbroek * contributors may be used to endorse or promote products derived 24*3e07920fSDavid van Moolenbroek * from this software without specific prior written permission. 25*3e07920fSDavid van Moolenbroek * 26*3e07920fSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27*3e07920fSDavid van Moolenbroek * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28*3e07920fSDavid van Moolenbroek * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29*3e07920fSDavid van Moolenbroek * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30*3e07920fSDavid van Moolenbroek * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31*3e07920fSDavid van Moolenbroek * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32*3e07920fSDavid van Moolenbroek * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33*3e07920fSDavid van Moolenbroek * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34*3e07920fSDavid van Moolenbroek * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35*3e07920fSDavid van Moolenbroek * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36*3e07920fSDavid van Moolenbroek * POSSIBILITY OF SUCH DAMAGE. 37*3e07920fSDavid van Moolenbroek */ 38*3e07920fSDavid van Moolenbroek /* 39*3e07920fSDavid van Moolenbroek * tls.h 40*3e07920fSDavid van Moolenbroek * 41*3e07920fSDavid van Moolenbroek */ 42*3e07920fSDavid van Moolenbroek #ifndef _TLS_H 43*3e07920fSDavid van Moolenbroek #define _TLS_H 44*3e07920fSDavid van Moolenbroek #include <openssl/x509v3.h> 45*3e07920fSDavid van Moolenbroek #include <openssl/err.h> 46*3e07920fSDavid van Moolenbroek #include <openssl/rand.h> 47*3e07920fSDavid van Moolenbroek #include <openssl/pem.h> 48*3e07920fSDavid van Moolenbroek 49*3e07920fSDavid van Moolenbroek /* initial size for TLS inbuf, minimum prefix + linelength 50*3e07920fSDavid van Moolenbroek * guaranteed to be accepted */ 51*3e07920fSDavid van Moolenbroek #define TLS_MIN_LINELENGTH (2048 + 5) 52*3e07920fSDavid van Moolenbroek /* usually the inbuf is enlarged as needed and then kept. 53*3e07920fSDavid van Moolenbroek * if bigger than TLS_PERSIST_LINELENGTH, then shrink 54*3e07920fSDavid van Moolenbroek * to TLS_LARGE_LINELENGTH immediately */ 55*3e07920fSDavid van Moolenbroek #define TLS_LARGE_LINELENGTH 8192 56*3e07920fSDavid van Moolenbroek #define TLS_PERSIST_LINELENGTH 32768 57*3e07920fSDavid van Moolenbroek 58*3e07920fSDavid van Moolenbroek /* timeout to call non-blocking TLS operations again */ 59*3e07920fSDavid van Moolenbroek #define TLS_RETRY_EVENT_USEC 20000 60*3e07920fSDavid van Moolenbroek 61*3e07920fSDavid van Moolenbroek /* reconnect to lost server after n sec (initial value) */ 62*3e07920fSDavid van Moolenbroek #define TLS_RECONNECT_SEC 10 63*3e07920fSDavid van Moolenbroek /* backoff connection attempts */ 64*3e07920fSDavid van Moolenbroek #define TLS_RECONNECT_BACKOFF_FACTOR 15/10 65*3e07920fSDavid van Moolenbroek #define TLS_RECONNECT_BACKOFF(x) (x) = (x) * TLS_RECONNECT_BACKOFF_FACTOR 66*3e07920fSDavid van Moolenbroek /* abandon connection attempts after n sec 67*3e07920fSDavid van Moolenbroek * This has to be <= 5h (with 10sec initial interval), 68*3e07920fSDavid van Moolenbroek * otherwise a daily SIGHUP from newsylog will reset 69*3e07920fSDavid van Moolenbroek * all timers and the giveup time will never be reached 70*3e07920fSDavid van Moolenbroek * 71*3e07920fSDavid van Moolenbroek * set here: 2h, reached after ca. 7h of reconnecting 72*3e07920fSDavid van Moolenbroek */ 73*3e07920fSDavid van Moolenbroek #define TLS_RECONNECT_GIVEUP 60*60*2 74*3e07920fSDavid van Moolenbroek 75*3e07920fSDavid van Moolenbroek /* default algorithm for certificate fingerprints */ 76*3e07920fSDavid van Moolenbroek #define DEFAULT_FINGERPRINT_ALG "sha-1" 77*3e07920fSDavid van Moolenbroek 78*3e07920fSDavid van Moolenbroek /* default X.509 files */ 79*3e07920fSDavid van Moolenbroek #define DEFAULT_X509_CERTFILE "/etc/openssl/default.crt" 80*3e07920fSDavid van Moolenbroek #define DEFAULT_X509_KEYFILE "/etc/openssl/default.key" 81*3e07920fSDavid van Moolenbroek 82*3e07920fSDavid van Moolenbroek /* options for peer certificate verification */ 83*3e07920fSDavid van Moolenbroek #define X509VERIFY_ALWAYS 0 84*3e07920fSDavid van Moolenbroek #define X509VERIFY_IFPRESENT 1 85*3e07920fSDavid van Moolenbroek #define X509VERIFY_NONE 2 86*3e07920fSDavid van Moolenbroek 87*3e07920fSDavid van Moolenbroek /* attributes for self-generated keys/certificates */ 88*3e07920fSDavid van Moolenbroek #define TLS_GENCERT_BITS 1024 89*3e07920fSDavid van Moolenbroek #define TLS_GENCERT_SERIAL 1 90*3e07920fSDavid van Moolenbroek #define TLS_GENCERT_DAYS 5*365 91*3e07920fSDavid van Moolenbroek 92*3e07920fSDavid van Moolenbroek /* TLS connection states */ 93*3e07920fSDavid van Moolenbroek #define ST_NONE 0 94*3e07920fSDavid van Moolenbroek #define ST_TLS_EST 1 95*3e07920fSDavid van Moolenbroek #define ST_TCP_EST 2 96*3e07920fSDavid van Moolenbroek #define ST_CONNECTING 3 97*3e07920fSDavid van Moolenbroek #define ST_ACCEPTING 4 98*3e07920fSDavid van Moolenbroek #define ST_READING 5 99*3e07920fSDavid van Moolenbroek #define ST_WRITING 6 100*3e07920fSDavid van Moolenbroek #define ST_EOF 7 101*3e07920fSDavid van Moolenbroek #define ST_CLOSING0 8 102*3e07920fSDavid van Moolenbroek #define ST_CLOSING1 9 103*3e07920fSDavid van Moolenbroek #define ST_CLOSING2 10 104*3e07920fSDavid van Moolenbroek 105*3e07920fSDavid van Moolenbroek /* backlog for listen */ 106*3e07920fSDavid van Moolenbroek #define TLSBACKLOG 4 107*3e07920fSDavid van Moolenbroek /* close TLS connection after multiple 'soft' errors */ 108*3e07920fSDavid van Moolenbroek #define TLS_MAXERRORCOUNT 4 109*3e07920fSDavid van Moolenbroek 110*3e07920fSDavid van Moolenbroek /* 111*3e07920fSDavid van Moolenbroek * holds TLS related settings for one connection to be 112*3e07920fSDavid van Moolenbroek * included in the SSL object and available in callbacks 113*3e07920fSDavid van Moolenbroek * 114*3e07920fSDavid van Moolenbroek * Many fields have a slightly different semantic for 115*3e07920fSDavid van Moolenbroek * incoming and outgoing connections: 116*3e07920fSDavid van Moolenbroek * - for outgoing connections it contains the values from syslog.conf and 117*3e07920fSDavid van Moolenbroek * the server's cert is checked against these values by check_peer_cert() 118*3e07920fSDavid van Moolenbroek * - for incoming connections it is not used for checking, instead 119*3e07920fSDavid van Moolenbroek * dispatch_tls_accept() fills in the connected hostname/port and 120*3e07920fSDavid van Moolenbroek * check_peer_cert() fills in subject and fingerprint from the peer cert 121*3e07920fSDavid van Moolenbroek */ 122*3e07920fSDavid van Moolenbroek struct tls_conn_settings { 123*3e07920fSDavid van Moolenbroek unsigned send_queue:1, /* currently sending buffer */ 124*3e07920fSDavid van Moolenbroek errorcount:4, /* counter [0;TLS_MAXERRORCOUNT] */ 125*3e07920fSDavid van Moolenbroek accepted:1, /* workaround cf. check_peer_cert*/ 126*3e07920fSDavid van Moolenbroek shutdown:1, /* fast connection close on exit */ 127*3e07920fSDavid van Moolenbroek x509verify:2, /* kind of validation needed */ 128*3e07920fSDavid van Moolenbroek incoming:1, /* set if we are server */ 129*3e07920fSDavid van Moolenbroek state:4; /* outgoing connection state */ 130*3e07920fSDavid van Moolenbroek struct event *event; /* event for read/write activity */ 131*3e07920fSDavid van Moolenbroek struct event *retryevent; /* event for retries */ 132*3e07920fSDavid van Moolenbroek SSL *sslptr; /* active SSL object */ 133*3e07920fSDavid van Moolenbroek char *hostname; /* hostname or IP we connect to */ 134*3e07920fSDavid van Moolenbroek char *port; /* service name or port number */ 135*3e07920fSDavid van Moolenbroek char *subject; /* configured hostname in cert */ 136*3e07920fSDavid van Moolenbroek char *fingerprint; /* fingerprint of peer cert */ 137*3e07920fSDavid van Moolenbroek char *certfile; /* filename of peer cert */ 138*3e07920fSDavid van Moolenbroek unsigned reconnect; /* seconds between reconnects */ 139*3e07920fSDavid van Moolenbroek }; 140*3e07920fSDavid van Moolenbroek 141*3e07920fSDavid van Moolenbroek /* argument struct only used for tls_send() */ 142*3e07920fSDavid van Moolenbroek struct tls_send_msg { 143*3e07920fSDavid van Moolenbroek struct filed *f; 144*3e07920fSDavid van Moolenbroek struct buf_queue *qentry; 145*3e07920fSDavid van Moolenbroek char *line; /* formatted message */ 146*3e07920fSDavid van Moolenbroek size_t linelen; 147*3e07920fSDavid van Moolenbroek size_t offset; /* in case of partial writes */ 148*3e07920fSDavid van Moolenbroek }; 149*3e07920fSDavid van Moolenbroek 150*3e07920fSDavid van Moolenbroek /* return values for TLS_examine_error() */ 151*3e07920fSDavid van Moolenbroek #define TLS_OK 0 /* no real problem, just ignore */ 152*3e07920fSDavid van Moolenbroek #define TLS_RETRY_READ 1 /* just retry, non-blocking operation not finished yet */ 153*3e07920fSDavid van Moolenbroek #define TLS_RETRY_WRITE 2 /* just retry, non-blocking operation not finished yet */ 154*3e07920fSDavid van Moolenbroek #define TLS_TEMP_ERROR 4 /* recoverable error condition, but try again */ 155*3e07920fSDavid van Moolenbroek #define TLS_PERM_ERROR 8 /* non-recoverable error condition, closed TLS and socket */ 156*3e07920fSDavid van Moolenbroek 157*3e07920fSDavid van Moolenbroek /* global TLS setup and utility */ 158*3e07920fSDavid van Moolenbroek char *init_global_TLS_CTX(void); 159*3e07920fSDavid van Moolenbroek struct socketEvent *socksetup_tls(const int, const char *, const char *); 160*3e07920fSDavid van Moolenbroek int check_peer_cert(int, X509_STORE_CTX *); 161*3e07920fSDavid van Moolenbroek int accept_cert(const char* , struct tls_conn_settings *, char *, char *); 162*3e07920fSDavid van Moolenbroek int deny_cert(struct tls_conn_settings *, char *, char *); 163*3e07920fSDavid van Moolenbroek bool read_certfile(X509 **, const char *); 164*3e07920fSDavid van Moolenbroek bool write_x509files(EVP_PKEY *, X509 *, const char *, const char *); 165*3e07920fSDavid van Moolenbroek bool mk_x509_cert(X509 **, EVP_PKEY **, int, int, int); 166*3e07920fSDavid van Moolenbroek bool x509_cert_add_subjectAltName(X509 *, X509V3_CTX *); 167*3e07920fSDavid van Moolenbroek int tls_examine_error(const char *, const SSL *, struct tls_conn_settings *, const int); 168*3e07920fSDavid van Moolenbroek 169*3e07920fSDavid van Moolenbroek bool get_fingerprint(const X509 *, char **, const char *); 170*3e07920fSDavid van Moolenbroek bool get_commonname(X509 *, char **); 171*3e07920fSDavid van Moolenbroek bool match_hostnames(X509 *, const char *, const char *); 172*3e07920fSDavid van Moolenbroek bool match_fingerprint(const X509 *, const char *); 173*3e07920fSDavid van Moolenbroek bool match_certfile(const X509 *, const char *); 174*3e07920fSDavid van Moolenbroek 175*3e07920fSDavid van Moolenbroek /* configuration & parsing */ 176*3e07920fSDavid van Moolenbroek bool parse_tls_destination(const char *, struct filed *, size_t); 177*3e07920fSDavid van Moolenbroek /* event callbacks */ 178*3e07920fSDavid van Moolenbroek void dispatch_socket_accept(int, short, void *); 179*3e07920fSDavid van Moolenbroek void dispatch_tls_accept(int, short, void *); 180*3e07920fSDavid van Moolenbroek void dispatch_tls_read(int, short, void *); 181*3e07920fSDavid van Moolenbroek void dispatch_tls_send(int, short, void *); 182*3e07920fSDavid van Moolenbroek void dispatch_tls_eof(int, short, void *); 183*3e07920fSDavid van Moolenbroek void dispatch_SSL_connect(int, short, void *); 184*3e07920fSDavid van Moolenbroek void dispatch_SSL_shutdown(int, short, void *); 185*3e07920fSDavid van Moolenbroek void dispatch_force_tls_reconnect(int, short, void *); 186*3e07920fSDavid van Moolenbroek 187*3e07920fSDavid van Moolenbroek bool tls_connect(struct tls_conn_settings *); 188*3e07920fSDavid van Moolenbroek void tls_reconnect(int, short, void *); 189*3e07920fSDavid van Moolenbroek bool tls_send(struct filed *, char *, size_t, struct buf_queue*); 190*3e07920fSDavid van Moolenbroek void tls_split_messages(struct TLS_Incoming_Conn *); 191*3e07920fSDavid van Moolenbroek 192*3e07920fSDavid van Moolenbroek void free_tls_conn(struct tls_conn_settings *); 193*3e07920fSDavid van Moolenbroek void free_tls_sslptr(struct tls_conn_settings *); 194*3e07920fSDavid van Moolenbroek void free_tls_send_msg(struct tls_send_msg *); 195*3e07920fSDavid van Moolenbroek 196*3e07920fSDavid van Moolenbroek #endif /* !_TLS_H */ 197