1 /*
2 **  tls.c -- TLS functions.
3 **  Copyright (C) 2000 Kenichi Okada <okada@opaopa.org>.
4 **
5 **  Author: Kenichi Okada <okada@opaopa.org>
6 **  Created: 2000-02-22
7 */
8 
9 #include "portable/system.h"
10 
11 #include <sys/stat.h>
12 #include <sys/uio.h>
13 #include <syslog.h>
14 
15 #include "inn/innconf.h"
16 #include "nnrpd.h"
17 
18 /* Outside the ifdef so that make depend works even ifndef HAVE_OPENSSL. */
19 #include "tls.h"
20 
21 #ifdef HAVE_OPENSSL
22 
23 /* We must keep some of the info available. */
24 static bool tls_initialized = false;
25 
26 static int verify_depth;
27 static int verify_error = X509_V_OK;
28 static int do_dump = 0;
29 static SSL_CTX *CTX = NULL;
30 SSL *tls_conn = NULL;
31 
32 static int tls_serverengine = 0;
33 static int tls_serveractive = 0; /* Available or not. */
34 char *tls_peer_CN = NULL;
35 
36 static const char *tls_protocol = NULL;
37 static const char *tls_cipher_name = NULL;
38 static int tls_cipher_algbits = 0;
39 int tls_cipher_usebits = 0;
40 
41 /* Set this value higher (from 1 to 4) to obtain more logs. */
42 static int tls_loglevel = 0;
43 
44 
45 /*
46 **  Taken from OpenSSL apps/s_cb.c.
47 **  Tim -- this seems to just be giving logging messages.
48 */
49 static void
apps_ssl_info_callback(const SSL * s,int where,int ret)50 apps_ssl_info_callback(const SSL *s, int where, int ret)
51 {
52     const char *str;
53     int w;
54 
55     if (tls_loglevel == 0)
56         return;
57 
58     w = where & ~SSL_ST_MASK;
59 
60     if (w & SSL_ST_CONNECT)
61         str = "SSL_connect";
62     else if (w & SSL_ST_ACCEPT)
63         str = "SSL_accept";
64     else
65         str = "undefined";
66 
67     if (where & SSL_CB_LOOP) {
68         if (tls_serverengine && (tls_loglevel >= 2))
69             syslog(L_NOTICE, "%s:%s", str, SSL_state_string_long(s));
70     } else if (where & SSL_CB_ALERT) {
71         str = (where & SSL_CB_READ) ? "read" : "write";
72         if ((tls_serverengine && (tls_loglevel >= 2))
73             || ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY))
74             syslog(L_NOTICE, "SSL3 alert %s:%s:%s", str,
75                    SSL_alert_type_string_long(ret),
76                    SSL_alert_desc_string_long(ret));
77     } else if (where & SSL_CB_EXIT) {
78         if (ret == 0)
79             syslog(L_ERROR, "%s:failed in %s", str, SSL_state_string_long(s));
80         else if (ret < 0) {
81             syslog(L_ERROR, "%s:error in %s", str, SSL_state_string_long(s));
82         }
83     }
84 }
85 
86 
87 /*
88 **  Now that safe prime groups have been supported since OpenSSL 1.1.0 and
89 **  LibreSSL 2.1.2 (but as LIBRESSL_VERSION_NUMBER was not bumped at that time,
90 **  use the 2.3.2 release which introduced the new numbering format), these
91 **  groups and the following functions to deal with them are only kept for
92 **  older versions.
93 */
94 #    if OPENSSL_VERSION_NUMBER < 0x010100000L \
95         || LIBRESSL_VERSION_NUMBER < 0x020302000L
96 /*
97 **  Hardcoded DH parameter files.
98 **  These are pre-defined DH groups recommended by RFC 7919 (Appendix A),
99 **  that have been audited and therefore supposed to be more
100 **  resistant to attacks than ones randomly generated.
101 **  They are FIPS-140 compliant and impractical to attack by construction.
102 **
103 **  There isn't any need to support user-specific files because of the
104 **  safe choice of these domain parameters from RFC 7919.
105 **  In case they appear to no longer be secure in the future, they'll
106 **  be changed in a future INN release.
107 */
108 /* clang-format off */
109 static const char file_ffdhe2048[] =
110 "-----BEGIN DH PARAMETERS-----\n\
111 MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n\
112 +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a\n\
113 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7\n\
114 YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi\n\
115 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD\n\
116 ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==\n\
117 -----END DH PARAMETERS-----\n";
118 
119 static const char file_ffdhe4096[] =
120 "-----BEGIN DH PARAMETERS-----\n\
121 MIICCAKCAgEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n\
122 +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a\n\
123 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7\n\
124 YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi\n\
125 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD\n\
126 ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3\n\
127 7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32\n\
128 nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e\n\
129 8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx\n\
130 iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K\n\
131 zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eZV9q//////////8CAQI=\n\
132 -----END DH PARAMETERS-----\n";
133 
134 static const char file_ffdhe8192[] =
135 "-----BEGIN DH PARAMETERS-----\n\
136 MIIECAKCBAEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n\
137 +8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a\n\
138 87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7\n\
139 YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi\n\
140 7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD\n\
141 ssbzSibBsu/6iGtCOGEfz9zeNVs7ZRkDW7w09N75nAI4YbRvydbmyQd62R0mkff3\n\
142 7lmMsPrBhtkcrv4TCYUTknC0EwyTvEN5RPT9RFLi103TZPLiHnH1S/9croKrnJ32\n\
143 nuhtK8UiNjoNq8Uhl5sN6todv5pC1cRITgq80Gv6U93vPBsg7j/VnXwl5B0rZp4e\n\
144 8W5vUsMWTfT7eTDp5OWIV7asfV9C1p9tGHdjzx1VA0AEh/VbpX4xzHpxNciG77Qx\n\
145 iu1qHgEtnmgyqQdgCpGBMMRtx3j5ca0AOAkpmaMzy4t6Gh25PXFAADwqTs6p+Y0K\n\
146 zAqCkc3OyX3Pjsm1Wn+IpGtNtahR9EGC4caKAH5eDdkCC/1ktkUDbHpOZ30sOFMq\n\
147 OiO6RELK9T6mO7RUMpt2JMiRe91kscD9TLOOjDNMcBw6za0GV/zP7HGbH1w+TkYE\n\
148 HziBR/tM/bR3pSRx96mpaRC4VTIu22NA2KAO8JI1BRHjCr7B//njom5/sp+MGDAj\n\
149 w1h+ONoAd9m0dj5OS5Syu8GUxmUed8r5ku6qwCMqKBv2s6c5wSJhFoIK6NtYR6Z8\n\
150 vvnJCRtGLVOM1ysDdGrnf15iKSwxFWKoRlBdyC24VDOK5J9SNclbkReMzy3Vys70\n\
151 A+ydGBDGJysEWztx+dxrgNY/3UqOmtseaWKmlSbUMWHBpB1XDXk42tSkDjKcz/Rq\n\
152 qjatAEz2AMg4HkJaMdlRrmT9sj/OyVCdQ2h/62nt0cxeC4zDvfZLEO+GtjFCo6uI\n\
153 KVVbL3R8kyZlyywPHMAb1wIpOIg50q8F5FRQSseLdYKCKEbAujXDX1xZFgzARv2C\n\
154 UVQfxoychrAiu3CZh2pGDnRRqKkxCXA/7hwhfmw4JuUsUappHg5CPPyZ6eMWUMEh\n\
155 e2JIFs2tmpX51bgBlIjZwKCh/jB1pXfiMYP4HUo/L6RXHvyM4LqKT+i2hV3+crCm\n\
156 bt7S+6v75Yow+vq+HF1xqH4vdB74wf6G/qa7/eUwZ38Nl9EdSfeoRD0IIuUGqfRh\n\
157 TgEeKpSDj/iM1oyLt8XGQkz//////////wIBAg==\n\
158 -----END DH PARAMETERS-----\n";
159 /* clang-format on */
160 
161 
162 /*
163 **  Load hardcoded DH parameters.
164 */
165 static DH *
load_dh_buffer(const char * buffer,size_t len)166 load_dh_buffer(const char *buffer, size_t len)
167 {
168     BIO *bio;
169     DH *dh = NULL;
170 
171     bio = BIO_new_mem_buf((char *) buffer, len);
172     if (bio == NULL)
173         return NULL;
174     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
175     /* If (dh == NULL) log error? */
176     BIO_free(bio);
177 
178     return dh;
179 }
180 
181 
182 /*
183 **  Generate ephemeral DH key.  Because this can take a long
184 **  time to compute, we use precomputed parameters of the common
185 **  key sizes.
186 **  Depending on OpenSSL Security Level, a minimal length for
187 **  DH parameters is required:
188 ** <https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_security_level.html>
189 **
190 **  These values can be static (once loaded or computed) since
191 **  the OpenSSL library can effectively generate random keys
192 **  from the information provided.
193 **
194 **  EDH keying is slightly less efficient than static RSA keying,
195 **  but it offers Perfect Forward Secrecy (PFS).
196 */
197 static DH *
tmp_dh_cb(SSL * s UNUSED,int export UNUSED,int keylength UNUSED)198 tmp_dh_cb(SSL *s UNUSED, int export UNUSED, int keylength UNUSED)
199 {
200     DH *r = NULL;
201 
202     static DH *ffdhe2048 = NULL;
203     static DH *ffdhe4096 = NULL;
204     static DH *ffdhe8192 = NULL;
205     int level = 2; /* Default security level. */
206 
207     /* Security levels have been introduced in OpenSSL 1.1.0, and still
208      * not present in LibreSSL 3.4.2.
209      * Well, as this part of code is no longer active for these versions,
210      * only keep it for possible future re-use. */
211 #        if OPENSSL_VERSION_NUMBER >= 0x010100000L \
212             && !defined(LIBRESSL_VERSION_NUMBER)
213     level = SSL_get_security_level(s);
214 #        endif
215 
216     switch (level) {
217     case 0: /* Everything is permitted. */
218     case 1: /* DH keys shorter than 1024 bits are prohibited. */
219     case 2: /* DH keys shorter than 2048 bits are prohibited. */
220         if (ffdhe2048 == NULL) {
221             ffdhe2048 = load_dh_buffer(file_ffdhe2048, sizeof(file_ffdhe2048));
222         }
223         r = ffdhe2048;
224         break;
225 
226     case 3: /* DH keys shorter than 3072 bits are prohibited. */
227         if (ffdhe4096 == NULL) {
228             ffdhe4096 = load_dh_buffer(file_ffdhe4096, sizeof(file_ffdhe4096));
229         }
230         r = ffdhe4096;
231         break;
232 
233     case 4: /* DH keys shorter than 7680 bits are prohibited. */
234     default:
235         if (ffdhe8192 == NULL) {
236             ffdhe8192 = load_dh_buffer(file_ffdhe8192, sizeof(file_ffdhe8192));
237         }
238         r = ffdhe8192;
239     }
240 
241     return r;
242 }
243 #    endif /* OpenSSL < 1.1.0 */
244 
245 
246 /*
247 **  Taken from OpenSSL apps/s_cb.c.
248 */
249 static int
verify_callback(int ok,X509_STORE_CTX * ctx)250 verify_callback(int ok, X509_STORE_CTX *ctx)
251 {
252     char buf[256];
253     X509 *err_cert;
254     int err;
255     int depth;
256 
257     syslog(L_NOTICE, "Doing a peer verify");
258 
259     err_cert = X509_STORE_CTX_get_current_cert(ctx);
260     err = X509_STORE_CTX_get_error(ctx);
261     depth = X509_STORE_CTX_get_error_depth(ctx);
262 
263     if ((tls_serveractive) && (tls_loglevel >= 1)) {
264         if (err_cert != NULL) {
265             X509_NAME_oneline(X509_get_subject_name(err_cert), buf,
266                               sizeof(buf));
267             syslog(L_NOTICE, "Peer cert verify depth=%d %s", depth, buf);
268         } else {
269             syslog(L_NOTICE, "Peer cert verify depth=%d <no cert>", depth);
270         }
271     }
272 
273     if (ok == 0) {
274         syslog(L_NOTICE, "verify error:num=%d:%s", err,
275                X509_verify_cert_error_string(err));
276 
277         if (verify_depth >= depth) {
278             ok = 1;
279             verify_error = X509_V_OK;
280         } else {
281             ok = 0;
282             verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
283         }
284     }
285 
286     switch (err) {
287     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
288         X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof(buf));
289         syslog(L_NOTICE, "issuer= %s", buf);
290         break;
291     case X509_V_ERR_CERT_NOT_YET_VALID:
292     case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
293         syslog(L_NOTICE, "cert not yet valid");
294         break;
295     case X509_V_ERR_CERT_HAS_EXPIRED:
296     case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
297         syslog(L_NOTICE, "cert has expired");
298         break;
299     }
300     if ((tls_serveractive) && (tls_loglevel >= 1))
301         syslog(L_NOTICE, "verify return:%d", ok);
302 
303     return (ok);
304 }
305 
306 
307 /*
308 **  Taken from OpenSSL crypto/bio/b_dump.c, modified to save a lot of strcpy
309 **  and strcat by Matti Aarnio.
310 */
311 #    define TRUNCATE
312 #    define DUMP_WIDTH 16
313 
314 static int
tls_dump(const char * s,int len)315 tls_dump(const char *s, int len)
316 {
317     int ret = 0;
318     char buf[160 + 1];
319     char *ss;
320     int i;
321     int j;
322     int rows;
323     int trunc;
324     unsigned char ch;
325 
326     trunc = 0;
327 
328 
329 #    ifdef TRUNCATE
330     for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
331         trunc++;
332 #    endif
333 
334     rows = (len / DUMP_WIDTH);
335     if ((rows * DUMP_WIDTH) < len)
336         rows++;
337 
338     for (i = 0; i < rows; i++) {
339         buf[0] = '\0'; /* Start with empty string. */
340         ss = buf;
341 
342         snprintf(ss, sizeof(buf), "%04x ", i * DUMP_WIDTH);
343         ss += strlen(ss);
344         for (j = 0; j < DUMP_WIDTH; j++) {
345             if (((i * DUMP_WIDTH) + j) >= len) {
346                 strlcpy(ss, "   ", sizeof(buf) - (ss - buf));
347             } else {
348                 ch = ((unsigned char) *((const char *) (s) + i * DUMP_WIDTH
349                                         + j))
350                      & 0xff;
351                 snprintf(ss, sizeof(buf) - (ss - buf), "%02x%c", ch,
352                          j == 7 ? '|' : ' ');
353                 ss += 3;
354             }
355         }
356         ss += strlen(ss);
357         *ss += ' ';
358         for (j = 0; j < DUMP_WIDTH; j++) {
359             if (((i * DUMP_WIDTH) + j) >= len)
360                 break;
361             ch = ((unsigned char) *((const char *) (s) + i * DUMP_WIDTH + j))
362                  & 0xff;
363             *ss += (((ch >= ' ') && (ch <= '~')) ? ch : '.');
364             if (j == 7)
365                 *ss += ' ';
366         }
367         *ss = 0;
368         /* If this is the last call, then update the ddt_dump thing so that
369          * we will move the selection point in the debug window. */
370         if (tls_loglevel > 0)
371             syslog(L_NOTICE, "%s", buf);
372         ret += strlen(buf);
373     }
374 #    ifdef TRUNCATE
375     if (trunc > 0) {
376         snprintf(buf, sizeof(buf), "%04x - <SPACES/NULS>\n", len + trunc);
377         if (tls_loglevel > 0)
378             syslog(L_NOTICE, "%s", buf);
379         ret += strlen(buf);
380     }
381 #    endif
382     return (ret);
383 }
384 
385 
386 /*
387 **  Set up the cert things on the server side. We do need both the
388 **  private key (in key_file) and the cert (in cert_file).
389 **  Both files may be identical.
390 **
391 **  This function is taken from OpenSSL apps/s_cb.c.
392 */
393 static int
set_cert_stuff(SSL_CTX * ctx,char * cert_file,char * key_file)394 set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
395 {
396     struct stat buf;
397 
398     if (cert_file != NULL) {
399         if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) {
400             syslog(L_ERROR, "unable to get certificates from '%s'", cert_file);
401             return (0);
402         }
403         if (key_file == NULL)
404             key_file = cert_file;
405 
406         /* Check ownership and permissions of key file.
407          * Look at the real file (stat) and not a possible symlink (lstat). */
408         if (stat(key_file, &buf) == -1) {
409             syslog(L_ERROR, "unable to stat private key '%s'", key_file);
410             return (0);
411         }
412 
413         /* Check that the key file is a real file, isn't world-readable, and
414          * that we can read it. */
415         if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0007) != 0
416             || access(key_file, R_OK) < 0) {
417             syslog(L_ERROR,
418                    "bad ownership or permissions on private key"
419                    " '%s': private key must be a regular file, readable by"
420                    " nnrpd, and not world-readable",
421                    key_file);
422             return (0);
423         }
424 
425         if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM)
426             <= 0) {
427             syslog(L_ERROR, "unable to get private key from '%s'", key_file);
428             return (0);
429         }
430         /* Now we know that a key and cert have been set against
431          * the SSL context. */
432         if (!SSL_CTX_check_private_key(ctx)) {
433             syslog(L_ERROR,
434                    "private key does not match the certificate public key");
435             return (0);
436         }
437     }
438     return (1);
439 }
440 
441 
442 #    if defined(HAVE_OPENSSL_ECC)                 \
443         && (OPENSSL_VERSION_NUMBER < 0x01010100fL \
444             || LIBRESSL_VERSION_NUMBER < 0x02050100fL)
445 /*
446 **  Provide an ECKEY from a curve name.
447 **  Accepts a NULL pointer as the name.
448 **  The EC_KEY_new_by_curve_name() function has been deprecated in
449 **  OpenSSL 3.0.0; another mechanism to select groups has been available
450 **  since OpenSSL 1.1.1 and LibreSSL 2.5.1.
451 **
452 **  Returns the key, or NULL on error.
453 */
454 static EC_KEY *
eckey_from_name(char * name)455 eckey_from_name(char *name)
456 {
457     EC_KEY *eckey;
458     size_t ncurves, nitems, i;
459     EC_builtin_curve *builtin_curves;
460     const char *sname;
461 
462     if (name == NULL) {
463         return (NULL);
464     }
465 
466     /* See EC_GROUP_new(3) for the details of this expressive dance. */
467     ncurves = EC_get_builtin_curves(NULL, 0); /* Number of curves. */
468 
469     builtin_curves = xmalloc(ncurves * sizeof(EC_builtin_curve));
470     nitems = EC_get_builtin_curves(builtin_curves, ncurves);
471     if (nitems != ncurves) {
472         syslog(L_ERROR,
473                "got %lu curves from EC_get_builtin_curves, "
474                "expected %lu",
475                (unsigned long) nitems, (unsigned long) ncurves);
476     }
477     for (i = 0; i < nitems; i++) {
478         sname = OBJ_nid2sn(builtin_curves[i].nid);
479         if (strcmp(sname, name) == 0) {
480             break;
481         }
482     }
483     if (i == nitems) {
484         syslog(L_ERROR, "tlseccurve '%s' not found", name);
485         free(builtin_curves);
486         return (NULL);
487     }
488 
489     eckey = EC_KEY_new_by_curve_name(builtin_curves[i].nid);
490     free(builtin_curves);
491     return (eckey);
492 }
493 #    endif /* HAVE_OPENSSL_ECC */
494 
495 /*
496 **  This is the setup routine for the SSL server.  As nnrpd might be called
497 **  more than once, we only want to do the initialization one time.
498 **
499 **  The skeleton of this function is taken from OpenSSL apps/s_server.c.
500 **
501 **  Returns -1 on error.
502 */
503 
504 int
tls_init_serverengine(int verifydepth,int askcert,int requirecert,char * tls_CAfile,char * tls_CApath,char * tls_cert_file,char * tls_key_file,bool prefer_server_ciphers,bool tls_compression,struct vector * tls_proto_vect,char * tls_ciphers,char * tls_ciphers13 UNUSED,char * tls_ec_curve UNUSED)505 tls_init_serverengine(int verifydepth, int askcert, int requirecert,
506                       char *tls_CAfile, char *tls_CApath, char *tls_cert_file,
507                       char *tls_key_file, bool prefer_server_ciphers,
508                       bool tls_compression, struct vector *tls_proto_vect,
509                       char *tls_ciphers, char *tls_ciphers13 UNUSED,
510                       char *tls_ec_curve UNUSED)
511 {
512     int off = 0;
513     int verify_flags = SSL_VERIFY_NONE;
514     char *CApath;
515     char *CAfile;
516     char *s_cert_file;
517     char *s_key_file;
518     struct stat buf;
519     size_t tls_protos = 0;
520     size_t i;
521 
522     if (tls_serverengine)
523         return (0); /* Already running. */
524 
525     if (tls_loglevel >= 2)
526         syslog(L_NOTICE, "starting TLS engine");
527 
528 /* New functions have been introduced in OpenSSL 1.1.0 and LibreSSL 2.7.0. */
529 #    if OPENSSL_VERSION_NUMBER < 0x010100000L \
530         || LIBRESSL_VERSION_NUMBER < 0x020700000L
531     SSL_load_error_strings();
532     SSLeay_add_ssl_algorithms();
533     CTX = SSL_CTX_new(SSLv23_server_method());
534 #    else
535     OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
536                          | OPENSSL_INIT_LOAD_CRYPTO_STRINGS,
537                      NULL);
538     CTX = SSL_CTX_new(TLS_server_method());
539 #    endif
540 
541     if (CTX == NULL) {
542         return (-1);
543     }
544 
545     off |= SSL_OP_ALL; /* Work around all known bugs. */
546     SSL_CTX_set_options(CTX, off);
547     SSL_CTX_set_info_callback(CTX, apps_ssl_info_callback);
548     SSL_CTX_sess_set_cache_size(CTX, 128);
549 
550     if (strlen(tls_CAfile) == 0)
551         CAfile = NULL;
552     else
553         CAfile = tls_CAfile;
554     if (strlen(tls_CApath) == 0)
555         CApath = NULL;
556     else
557         CApath = tls_CApath;
558 
559     if ((!SSL_CTX_load_verify_locations(CTX, CAfile, CApath))
560         || (!SSL_CTX_set_default_verify_paths(CTX))) {
561         if (tls_loglevel >= 2)
562             syslog(L_ERROR, "TLS engine: cannot load CA data");
563         return (-1);
564     }
565 
566     if (strlen(tls_cert_file) == 0)
567         s_cert_file = NULL;
568     else
569         s_cert_file = tls_cert_file;
570     if (strlen(tls_key_file) == 0)
571         s_key_file = NULL;
572     else
573         s_key_file = tls_key_file;
574 
575     if (!set_cert_stuff(CTX, s_cert_file, s_key_file)) {
576         if (tls_loglevel >= 2)
577             syslog(L_ERROR, "TLS engine: cannot load cert/key data");
578         return (-1);
579     }
580 
581     /* Load some randomization data from /dev/urandom, if it exists.
582      * FIXME: should also check for ".rand" file, update it on exit. */
583     if (stat("/dev/urandom", &buf) == 0)
584         RAND_load_file("/dev/urandom", 16 * 1024);
585 
586 /* Safe prime groups were introduced in OpenSSL 1.1.0, and have also been
587  * present since LibreSSL 2.1.2 (but as LIBRESSL_VERSION_NUMBER was not bumped
588  * at that time, use the 2.3.2 release which introduced the new numbering
589  * format). */
590 #    if OPENSSL_VERSION_NUMBER < 0x010100000L \
591         || LIBRESSL_VERSION_NUMBER < 0x020302000L
592     SSL_CTX_set_tmp_dh_callback(CTX, tmp_dh_cb);
593 #    else
594     SSL_CTX_set_dh_auto(CTX, 1);
595 #    endif
596 
597     SSL_CTX_set_options(CTX, SSL_OP_SINGLE_DH_USE);
598 
599 #    ifdef HAVE_OPENSSL_ECC
600     SSL_CTX_set_options(CTX, SSL_OP_SINGLE_ECDH_USE);
601 
602     /* We set a curve here by name if provided
603      * or we use OpenSSL (>= 1.0.2) auto-selection
604      * or we default to NIST P-256. */
605     if (tls_ec_curve != NULL) {
606 #        if OPENSSL_VERSION_NUMBER < 0x01010100fL \
607             || LIBRESSL_VERSION_NUMBER < 0x02050100fL
608         /* A new mechanism to select groups has been introduced
609          * in OpenSSL 1.1.1 and LibreSSL 2.5.1. */
610         EC_KEY *eckey;
611         eckey = eckey_from_name(tls_ec_curve);
612         if (eckey != NULL) {
613             SSL_CTX_set_tmp_ecdh(CTX, eckey);
614         }
615 #        else
616         if (!SSL_CTX_set1_groups_list(CTX, tls_ec_curve))
617             syslog(L_ERROR, "tlseccurve '%s' not found", tls_ec_curve);
618 #        endif
619     } else {
620 #        if OPENSSL_VERSION_NUMBER < 0x010100000L
621 #            if OPENSSL_VERSION_NUMBER >= 0x01000200fL
622         /* Function supported since OpenSSL 1.0.2.
623          * Removed since OpenSSL 1.1.0, supporting ECDH by default with
624          * the most appropriate parameters. (So does LibreSSL.) */
625         SSL_CTX_set_ecdh_auto(CTX, 1);
626 #            else
627         SSL_CTX_set_tmp_ecdh(CTX,
628                              EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
629 #            endif /* SSL_CTX_set_ecdh_auto */
630 #        endif     /* OpenSSL version < 1.1.0 */
631     }
632 #    endif /* HAVE_OPENSSL_ECC */
633 
634 #    ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
635     if (prefer_server_ciphers) {
636         SSL_CTX_set_options(CTX, SSL_OP_CIPHER_SERVER_PREFERENCE);
637     } else {
638 #        if (OPENSSL_VERSION_NUMBER >= 0x0009080dfL     \
639              && OPENSSL_VERSION_NUMBER != 0x000909000L) \
640             || defined(LIBRESSL_VERSION_NUMBER)
641         /* Function first added in OpenSSL 0.9.8m and not present
642          * in OpenSSL 0.9.9-dev.  Always present in LibreSSL. */
643         SSL_CTX_clear_options(CTX, SSL_OP_CIPHER_SERVER_PREFERENCE);
644 #        endif
645     }
646 #    endif
647 
648     if ((tls_proto_vect != NULL) && (tls_proto_vect->count > 0)) {
649         for (i = 0; i < tls_proto_vect->count; i++) {
650             if (tls_proto_vect->strings[i] != NULL) {
651                 if (strcmp(tls_proto_vect->strings[i], "SSLv2") == 0) {
652                     tls_protos |= INN_TLS_SSLv2;
653                 } else if (strcmp(tls_proto_vect->strings[i], "SSLv3") == 0) {
654                     tls_protos |= INN_TLS_SSLv3;
655                 } else if (strcmp(tls_proto_vect->strings[i], "TLSv1") == 0) {
656                     tls_protos |= INN_TLS_TLSv1;
657                 } else if (strcmp(tls_proto_vect->strings[i], "TLSv1.1")
658                            == 0) {
659                     tls_protos |= INN_TLS_TLSv1_1;
660                 } else if (strcmp(tls_proto_vect->strings[i], "TLSv1.2")
661                            == 0) {
662                     tls_protos |= INN_TLS_TLSv1_2;
663                 } else if (strcmp(tls_proto_vect->strings[i], "TLSv1.3")
664                            == 0) {
665                     tls_protos |= INN_TLS_TLSv1_3;
666                 } else {
667                     syslog(L_ERROR,
668                            "TLS engine: unknown protocol '%s' in tlsprotocols",
669                            tls_proto_vect->strings[i]);
670                 }
671             }
672         }
673     } else {
674         /* Default value: allow only secure TLS protocols. */
675         tls_protos = (INN_TLS_TLSv1_2 | INN_TLS_TLSv1_3);
676     }
677 
678     if ((tls_protos & INN_TLS_SSLv2) == 0) {
679 #    ifdef SSL_OP_NO_SSLv2
680         SSL_CTX_set_options(CTX, SSL_OP_NO_SSLv2);
681 #    endif
682     }
683 
684     if ((tls_protos & INN_TLS_SSLv3) == 0) {
685 #    ifdef SSL_OP_NO_SSLv3
686         SSL_CTX_set_options(CTX, SSL_OP_NO_SSLv3);
687 #    endif
688     }
689 
690     if ((tls_protos & INN_TLS_TLSv1) == 0) {
691 #    ifdef SSL_OP_NO_TLSv1
692         SSL_CTX_set_options(CTX, SSL_OP_NO_TLSv1);
693 #    endif
694     }
695 
696     if ((tls_protos & INN_TLS_TLSv1_1) == 0) {
697 #    ifdef SSL_OP_NO_TLSv1_1
698         SSL_CTX_set_options(CTX, SSL_OP_NO_TLSv1_1);
699 #    endif
700     }
701 
702     if ((tls_protos & INN_TLS_TLSv1_2) == 0) {
703 #    ifdef SSL_OP_NO_TLSv1_2
704         SSL_CTX_set_options(CTX, SSL_OP_NO_TLSv1_2);
705 #    endif
706     }
707 
708     if ((tls_protos & INN_TLS_TLSv1_3) == 0) {
709 #    ifdef SSL_OP_NO_TLSv1_3
710         SSL_CTX_set_options(CTX, SSL_OP_NO_TLSv1_3);
711 #    endif
712     }
713 
714     if (tls_ciphers != NULL) {
715         if (SSL_CTX_set_cipher_list(CTX, tls_ciphers) == 0) {
716             syslog(L_ERROR, "TLS engine: cannot set cipher list");
717             return (-1);
718         }
719     }
720 
721 #    if (OPENSSL_VERSION_NUMBER >= 0x01010100fL \
722          && defined(SSL_OP_NO_TLSv1_3))         \
723         || LIBRESSL_VERSION_NUMBER >= 0x03040100fL
724     /* New API added in OpenSSL 1.1.1 for TLSv1.3 cipher suites.
725      * Also check that SSL_OP_NO_TLSv1_3 is defined (so as not to match
726      * with LibreSSL versions prior to 3.4.1, which introduced the function).
727      */
728     if (tls_ciphers13 != NULL) {
729         if (SSL_CTX_set_ciphersuites(CTX, tls_ciphers13) == 0) {
730             syslog(L_ERROR, "TLS engine: cannot set ciphersuites");
731             return (-1);
732         }
733     }
734 #    endif
735 
736     if (tls_compression) {
737 #    if defined(SSL_OP_NO_COMPRESSION)                  \
738         && ((OPENSSL_VERSION_NUMBER >= 0x0009080dfL     \
739              && OPENSSL_VERSION_NUMBER != 0x000909000L) \
740             || defined(LIBRESSL_VERSION_NUMBER))
741         /* Function first added in OpenSSL 0.9.8m, and not present
742          * in OpenSSL 0.9.9-dev.  Always present in LibreSSL. */
743         SSL_CTX_clear_options(CTX, SSL_OP_NO_COMPRESSION);
744 #    endif
745     } else {
746 #    ifdef SSL_OP_NO_COMPRESSION
747         /* Option implemented in OpenSSL 1.0.0 and LibreSSL. */
748         SSL_CTX_set_options(CTX, SSL_OP_NO_COMPRESSION);
749 #    elif OPENSSL_VERSION_NUMBER >= 0x00090800fL
750         /* Workaround for OpenSSL 0.9.8. */
751         sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
752 #    endif
753     }
754 
755     verify_depth = verifydepth;
756     if (askcert != 0)
757         verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
758     if (requirecert)
759         verify_flags |= SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
760                         | SSL_VERIFY_CLIENT_ONCE;
761     SSL_CTX_set_verify(CTX, verify_flags, verify_callback);
762 
763     SSL_CTX_set_client_CA_list(CTX, SSL_load_client_CA_file(CAfile));
764 
765     tls_serverengine = 1;
766     return (0);
767 }
768 
769 
770 /*
771 **  The function called by nnrpd to initialize the TLS support.  Calls
772 **  tls_init_serverengine and checks the result.  On any sort of failure,
773 **  nnrpd will exit.
774 **
775 **  Returns -1 on error.
776 */
777 int
tls_init(void)778 tls_init(void)
779 {
780     int ssl_result;
781 
782     if (tls_initialized)
783         return 0;
784 
785     ssl_result = tls_init_serverengine(
786         5, /* Depth to verify. */
787         0, /* Can client auth? */
788         0, /* Required client to auth? */
789         innconf->tlscafile, innconf->tlscapath, innconf->tlscertfile,
790         innconf->tlskeyfile, innconf->tlspreferserverciphers,
791         innconf->tlscompression, innconf->tlsprotocols, innconf->tlsciphers,
792         innconf->tlsciphers13, innconf->tlseccurve);
793 
794     if (ssl_result == -1) {
795         Reply("%d Error initializing TLS\r\n",
796               initialSSL ? NNTP_FAIL_TERMINATING : NNTP_ERR_STARTTLS);
797         syslog(L_ERROR,
798                "error initializing TLS: "
799                "[CA_file: %s] [CA_path: %s] [cert_file: %s] [key_file: %s]",
800                innconf->tlscafile, innconf->tlscapath, innconf->tlscertfile,
801                innconf->tlskeyfile);
802         if (initialSSL)
803             ExitWithStats(1, false);
804         return -1;
805     }
806 
807     tls_initialized = true;
808     return 0;
809 }
810 
811 
812 /*
813 **  Taken from OpenSSL apps/lib/s_cb.c.
814 **
815 **  The prototype of the callback function changed with BIO_set_callback_ex()
816 **  introduced in OpenSSL 1.1.1, but still not present in LibreSSL (last
817 **  checked version is LibreSSL 3.4.2).
818 */
819 #    if OPENSSL_VERSION_NUMBER < 0x01010100fL \
820         || defined(LIBRESSL_VERSION_NUMBER)
821 static long
bio_dump_cb(BIO * bio,int cmd,const char * argp,int argi,long argl UNUSED,long ret)822 bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi, long argl UNUSED,
823             long ret)
824 {
825     if (!do_dump)
826         return (ret);
827 
828     if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
829         syslog(L_NOTICE, "read from %08lX [%08lX] (%d bytes => %ld (0x%lX))",
830                (unsigned long) bio, (unsigned long) argp, argi, ret,
831                (unsigned long) ret);
832         tls_dump(argp, (int) ret);
833         return (ret);
834     } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
835         syslog(L_NOTICE, "write to %08lX [%08lX] (%d bytes => %ld (0x%lX))",
836                (unsigned long) bio, (unsigned long) argp, argi, ret,
837                (unsigned long) ret);
838         tls_dump(argp, (int) ret);
839     }
840     return (ret);
841 }
842 #    else
843 static long
bio_dump_cb(BIO * bio,int cmd,const char * argp,size_t len,int argi UNUSED,long argl UNUSED,int ret,size_t * processed)844 bio_dump_cb(BIO *bio, int cmd, const char *argp, size_t len, int argi UNUSED,
845             long argl UNUSED, int ret, size_t *processed)
846 {
847     if (!do_dump)
848         return (ret);
849 
850     if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
851         if (ret > 0 && processed != NULL) {
852             syslog(
853                 L_NOTICE, "read from %08lX [%08lX] (%lu bytes => %lu (0x%lX))",
854                 (unsigned long) bio, (unsigned long) argp, (unsigned long) len,
855                 (unsigned long) *processed, (unsigned long) *processed);
856             tls_dump(argp, (int) *processed);
857         } else {
858             syslog(L_NOTICE,
859                    "read from %08lX [%08lX] (%lu bytes => %d (0x%lX))",
860                    (unsigned long) bio, (unsigned long) argp,
861                    (unsigned long) len, ret, (unsigned long) ret);
862         }
863     } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
864         if (ret > 0 && processed != NULL) {
865             syslog(
866                 L_NOTICE, "write to %08lX [%08lX] (%lu bytes => %lu (0x%lX))",
867                 (unsigned long) bio, (unsigned long) argp, (unsigned long) len,
868                 (unsigned long) *processed, (unsigned long) *processed);
869             tls_dump(argp, (int) *processed);
870         } else {
871             syslog(L_NOTICE,
872                    "write to %08lX [%08lX] (%lu bytes => %d (0x%lX))",
873                    (unsigned long) bio, (unsigned long) argp,
874                    (unsigned long) len, ret, (unsigned long) ret);
875         }
876     }
877     return (ret);
878 }
879 #    endif
880 
881 /*
882 **  This is the actual startup routine for the connection.  We expect
883 **  that the buffers are flushed and the "382 Continue with TLS negociation"
884 **  was sent to the client (if using STARTTLS), so that we can immediately
885 **  start the TLS handshake process.
886 **
887 **  layerbits and authid are filled in on success; authid is only
888 **  filled in if the client authenticated.
889 */
890 int
tls_start_servertls(int readfd,int writefd)891 tls_start_servertls(int readfd, int writefd)
892 {
893     int sts;
894     int keepalive;
895     SSL_SESSION *session;
896     SSL_CIPHER *cipher;
897 
898     if (!tls_serverengine) {
899         /* It should never happen. */
900         syslog(L_ERROR, "tls_engine not running");
901         return (-1);
902     }
903     if (tls_loglevel >= 1)
904         syslog(L_NOTICE, "setting up TLS connection");
905 
906     if (tls_conn == NULL) {
907         tls_conn = (SSL *) SSL_new(CTX);
908     }
909     if (tls_conn == NULL) {
910         return (-1);
911     }
912     SSL_clear(tls_conn);
913 
914 #    if defined(SOL_SOCKET) && defined(SO_KEEPALIVE)
915     /* Set KEEPALIVE to catch broken socket connections. */
916     keepalive = 1;
917     if (setsockopt(readfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
918                    sizeof(keepalive))
919         < 0)
920         syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", readfd);
921     if (setsockopt(writefd, SOL_SOCKET, SO_KEEPALIVE, &keepalive,
922                    sizeof(keepalive))
923         < 0)
924         syslog(L_ERROR, "fd %d can't setsockopt(KEEPALIVE) %m", writefd);
925 #    endif /* SOL_SOCKET && SO_KEEPALIVE */
926 
927     /* Set the file descriptors for SSL to use. */
928     if (SSL_set_rfd(tls_conn, readfd) == 0) {
929         return (-1);
930     }
931 
932     if (SSL_set_wfd(tls_conn, writefd) == 0) {
933         return (-1);
934     }
935 
936     /* This is the actual handshake routine.  It will do all the negotiations
937      * and will check the client cert etc. */
938     SSL_set_accept_state(tls_conn);
939 
940     /* We do have an SSL_set_fd() and now suddenly a BIO_ routine is called?
941      * Well there is a BIO below the SSL routines that is automatically
942      * created for us, so we can use it for debugging purposes. */
943     if (tls_loglevel >= 3) {
944         /* BIO_set_callback() was deprecated in OpenSSL 3.0.0.
945          * BIO_set_callback_ex() was introduced in OpenSSL 1.1.1 but still
946          * not available in LibreSSL (last checked version is LibreSSL 3.4.2).
947          */
948 #    if OPENSSL_VERSION_NUMBER < 0x01010100fL \
949         || defined(LIBRESSL_VERSION_NUMBER)
950         BIO_set_callback(SSL_get_rbio(tls_conn), bio_dump_cb);
951 #    else
952         BIO_set_callback_ex(SSL_get_rbio(tls_conn), bio_dump_cb);
953 #    endif
954     }
955 
956     /* Dump the negotiation for loglevels 3 and 4. */
957     if (tls_loglevel >= 3)
958         do_dump = 1;
959 
960     if ((sts = SSL_accept(tls_conn)) <= 0) {
961         session = SSL_get_session(tls_conn);
962 
963         if (session) {
964             SSL_CTX_remove_session(CTX, session);
965         }
966         if (tls_conn)
967             SSL_free(tls_conn);
968         tls_conn = NULL;
969         return (-1);
970     }
971     /* Only loglevel 4 dumps everything. */
972     if (tls_loglevel < 4)
973         do_dump = 0;
974 
975     tls_protocol = SSL_get_version(tls_conn);
976     cipher = (SSL_CIPHER *) SSL_get_current_cipher(tls_conn);
977 
978     tls_cipher_name = SSL_CIPHER_get_name(cipher);
979     tls_cipher_usebits = SSL_CIPHER_get_bits(cipher, &tls_cipher_algbits);
980     tls_serveractive = 1;
981 
982     syslog(
983         L_NOTICE, "starttls: %s with cipher %s (%d/%d bits) no authentication",
984         tls_protocol, tls_cipher_name, tls_cipher_usebits, tls_cipher_algbits);
985 
986     return (0);
987 }
988 
989 
990 ssize_t
SSL_writev(SSL * ssl,const struct iovec * vector,int count)991 SSL_writev(SSL *ssl, const struct iovec *vector, int count)
992 {
993     static char *buffer = NULL;
994     static size_t allocsize = 0;
995     char *bp;
996     size_t bytes, to_copy;
997     int i;
998     /* Find the total number of bytes to be written. */
999     bytes = 0;
1000     for (i = 0; i < count; ++i)
1001         bytes += vector[i].iov_len;
1002     /* Allocate a buffer to hold the data. */
1003     if (NULL == buffer) {
1004         size_t to_alloc = (bytes > 0 ? bytes : 1);
1005         buffer = (char *) xmalloc(to_alloc);
1006         allocsize = to_alloc;
1007     } else if (bytes > allocsize) {
1008         buffer = (char *) xrealloc(buffer, bytes);
1009         allocsize = bytes;
1010     }
1011     /* Copy the data into BUFFER. */
1012     to_copy = bytes;
1013     bp = buffer;
1014     for (i = 0; i < count; ++i) {
1015 #    define min(a, b) ((a) > (b) ? (b) : (a))
1016         size_t copy = min(vector[i].iov_len, to_copy);
1017         memcpy(bp, vector[i].iov_base, copy);
1018         bp += copy;
1019         to_copy -= copy;
1020         if (to_copy == 0)
1021             break;
1022     }
1023     return SSL_write(ssl, buffer, bytes);
1024 }
1025 
1026 #endif /* HAVE_OPENSSL */
1027