Upgrade TLS suites for GnuTLS, mbedTLS and OpenSSL
[umurmur.git] / src / ssli_openssl.c
1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include <stdlib.h>
32 #include <fcntl.h>
33
34 #include "conf.h"
35 #include "log.h"
36 #include "memory.h"
37 #include "ssl.h"
38
39 /*
40  * OpenSSL interface
41  */
42
43 #include <openssl/x509v3.h>
44 #include <openssl/ssl.h>
45 #include <openssl/err.h>
46 #include <openssl/safestack.h>
47 static X509 *x509;
48 static RSA *rsa;
49 static SSL_CTX *context;
50 static EVP_PKEY *pkey;
51
52 static char const * ciphers = "EECDH+AESGCM:AES256-SHA:AES128-SHA";
53
54 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx);
55
56 static int SSL_add_ext(X509 * crt, int nid, char *value) {
57         X509_EXTENSION *ex;
58         X509V3_CTX ctx;
59         X509V3_set_ctx_nodb(&ctx);
60         X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
61         ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
62         if (!ex)
63                 return 0;
64
65         X509_add_ext(crt, ex, -1);
66         X509_EXTENSION_free(ex);
67         return 1;
68 }
69
70 static X509 *SSL_readcert(char *certfile)
71 {
72         FILE *fp;
73         X509 *x509;
74
75         /* open the certificate file */
76         fp = fopen(certfile, "r");
77         if (fp == NULL) {
78                 Log_warn("Unable to open the X509 file %s for reading.", certfile);
79                 return NULL;
80         }
81
82         /* allocate memory for the cert structure */
83         x509 = X509_new();
84
85         if (PEM_read_X509(fp, &x509, NULL, NULL) == 0) {
86                 /* error reading the x509 information - check the error stack */
87                 Log_warn("Error trying to read X509 info.");
88                 fclose(fp);
89                 X509_free(x509);
90                 return NULL;
91         }
92         fclose(fp);
93         return x509;
94 }
95
96 static RSA *SSL_readprivatekey(char *keyfile)
97 {
98         FILE *fp;
99         RSA *rsa;
100
101 /* open the private key file for reading */
102         fp = fopen(keyfile, "r");
103         if (fp == NULL) {
104                 Log_warn("Unable to open the private key file %s for reading.", keyfile);
105                 return NULL;
106         }
107
108 /* allocate memory for the RSA structure */
109         rsa = RSA_new();
110
111         /* assign a callback function for the password */
112
113         /* read a private key from file */
114         if (PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) <= 0) {
115                 /* error reading the key - check the error stack */
116                 Log_warn("Error trying to read private key.");
117                 RSA_free(rsa);
118                 fclose(fp);
119                 return NULL;
120         }
121         fclose(fp);
122         return rsa;
123 }
124
125 static void SSL_writecert(char *certfile, X509 *x509)
126 {
127         FILE *fp;
128
129         /* open the private key file */
130         fp = fopen(certfile, "w");
131         if (fp == NULL) {
132                 Log_warn("Unable to open the X509 file %s for writing", certfile);
133                 return;
134         }
135         if (PEM_write_X509(fp, x509) == 0) {
136                 Log_warn("Error trying to write X509 info.");
137         }
138         fclose(fp);
139 }
140
141 static void SSL_writekey(char *keyfile, RSA *rsa)
142 {
143         FILE *fp;
144
145         /* open the private key file for reading */
146         fp = fopen(keyfile, "w");
147         if (fp == NULL) {
148                 Log_warn("Unable to open the private key file %s for writing.", keyfile);
149                 return;
150         }
151
152         if (PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL) == 0) {
153                 Log_warn("Error trying to write private key");
154         }
155         fclose(fp);
156 }
157
158 static void SSL_initializeCert() {
159
160         char *crt = (char *)getStrConf(CERTIFICATE);
161         char *key = (char *)getStrConf(KEY);
162
163         if (context) {
164                 bool_t did_load_cert = SSL_CTX_use_certificate_chain_file(context, crt);
165                 rsa = SSL_readprivatekey(key);
166
167                 if (!rsa || !did_load_cert) {
168                         Log_info("Generating new server certificate.");
169
170
171                         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
172
173                         x509 = X509_new();
174                         pkey = EVP_PKEY_new();
175                         rsa = RSA_generate_key(4096,RSA_F4,NULL,NULL);
176                         EVP_PKEY_assign_RSA(pkey, rsa);
177
178                         X509_set_version(x509, 2);
179                         ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
180                         X509_gmtime_adj(X509_get_notBefore(x509),0);
181                         X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
182                         X509_set_pubkey(x509, pkey);
183
184                         X509_NAME *name=X509_get_subject_name(x509);
185
186                         X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
187                         X509_set_issuer_name(x509, name);
188                         SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
189                         SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
190                         SSL_add_ext(x509, NID_subject_key_identifier, "hash");
191                         SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
192
193                         X509_sign(x509, pkey, EVP_md5());
194
195                         SSL_writecert(crt, x509);
196                         SSL_writekey(key, rsa);
197
198                         SSL_CTX_use_certificate(context, x509);
199                 } else {
200                   pkey = EVP_PKEY_new();
201                   EVP_PKEY_assign_RSA(pkey, rsa);
202                 }
203
204                 SSL_CTX_use_PrivateKey(context, pkey);
205
206         } else {
207                 Log_fatal("Failed to initialize TLS context.");
208         }
209
210 }
211
212 void SSLi_init(void)
213 {
214         SSL *ssl;
215         int i, offset = 0, cipherstringlen = 0;
216         STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
217         SSL_CIPHER *cipher;
218         char *cipherstring;
219
220         SSL_library_init();
221         OpenSSL_add_all_algorithms();
222         SSL_load_error_strings();
223         ERR_load_crypto_strings();
224
225         context = SSL_CTX_new(TLSv1_2_server_method());
226         if (context == NULL)
227         {
228                 ERR_print_errors_fp(stderr);
229                 abort();
230         }
231
232         SSL_CTX_set_cipher_list(context, ciphers);
233
234         EC_KEY *ecdhkey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
235         SSL_CTX_set_tmp_ecdh(context, ecdhkey);
236         EC_KEY_free(ecdhkey);
237
238         char const * sslCAPath = getStrConf(CAPATH);
239         if(sslCAPath != NULL)
240         {
241                 SSL_CTX_load_verify_locations(context, NULL, sslCAPath);
242         }
243
244         SSL_initializeCert();
245
246         /* Set cipher list */
247         ssl = SSL_new(context);
248         cipherlist = (STACK_OF(SSL_CIPHER) *) SSL_get_ciphers(ssl);
249         cipherlist_new = (STACK_OF(SSL_CIPHER) *) sk_SSL_CIPHER_new_null();
250
251         for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist, i)) != NULL; i++) {
252                 if (SSL_CIPHER_get_bits(cipher, NULL) >= 128) {
253                         sk_SSL_CIPHER_push(cipherlist_new, cipher);
254                 }
255         }
256         Log_debug("List of ciphers:");
257         if (cipherlist_new) {
258                 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
259                         Log_debug("%s", SSL_CIPHER_get_name(cipher));
260                         cipherstringlen += strlen(SSL_CIPHER_get_name(cipher)) + 1;
261                 }
262                 cipherstring = Memory_safeMalloc(1, cipherstringlen + 1);
263                 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
264                         offset += sprintf(cipherstring + offset, "%s:", SSL_CIPHER_get_name(cipher));
265                 }
266         }
267
268         if (cipherlist_new)
269                 sk_SSL_CIPHER_free(cipherlist_new);
270
271         if (strlen(cipherstring) == 0)
272                 Log_fatal("No suitable ciphers found!");
273
274         if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
275                 Log_fatal("Failed to set cipher list!");
276
277         free(cipherstring);
278
279         SSL_CTX_set_verify(context, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
280                            verify_callback);
281
282         SSL_free(ssl);
283         Log_info("OpenSSL library initialized");
284
285 }
286
287 void SSLi_deinit(void)
288 {
289         SSL_CTX_free(context);
290         EVP_cleanup();
291 }
292
293 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
294 {
295         int rc;
296         rc = SSL_accept(ssl);
297         if (rc < 0) {
298                 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
299                         SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
300                         Log_debug("SSL not ready");
301                         return 0;
302                 } else {
303                         Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
304                         return -1;
305                 }
306         }
307         *SSLready = true;
308         return 0;
309 }
310
311 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
312 {
313         SSL *ssl;
314
315         *SSLready = false;
316         ssl = SSL_new(context);
317         SSL_set_fd(ssl, *fd);
318         if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
319                 SSL_free(ssl);
320                 return NULL;
321         }
322         return ssl;
323 }
324
325 /* Create SHA1 of last certificate in the peer's chain. */
326 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
327 {
328         X509 *x509;
329         uint8_t *buf, *p;
330         int len;
331
332         x509 = SSL_get_peer_certificate(ssl);
333         if (!x509) {
334                 return false;
335         }
336
337         len = i2d_X509(x509, NULL);
338         buf = Memory_safeMalloc(1, len);
339
340         p = buf;
341         i2d_X509(x509, &p);
342
343         SHA1(buf, len, hash);
344         free(buf);
345         return true;
346 }
347
348 void SSLi_closeconnection(SSL_handle_t *ssl)
349 {
350         SSL_free(ssl);
351 }
352
353 void SSLi_shutdown(SSL_handle_t *ssl)
354 {
355         SSL_shutdown(ssl);
356 }
357
358 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
359 {
360         return SSL_read(ssl, buf, len);
361 }
362
363 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
364 {
365         return SSL_write(ssl, buf, len);
366 }
367
368 int SSLi_get_error(SSL_handle_t *ssl, int code)
369 {
370         return SSL_get_error(ssl, code);
371 }
372
373 bool_t SSLi_data_pending(SSL_handle_t *ssl)
374 {
375         return SSL_pending(ssl);
376 }
377
378 void SSLi_free(SSL_handle_t *ssl)
379 {
380         SSL_free(ssl);
381 }
382
383 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
384 {
385         char    buf[256];
386         X509   *err_cert;
387         int     err, depth;
388         SSL    *ssl;
389
390     err_cert = X509_STORE_CTX_get_current_cert(ctx);
391     err = X509_STORE_CTX_get_error(ctx);
392     depth = X509_STORE_CTX_get_error_depth(ctx);
393
394     ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
395     X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
396
397     if (depth > 5) {
398         preverify_ok = 0;
399         err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
400         X509_STORE_CTX_set_error(ctx, err);
401     }
402     if (!preverify_ok) {
403             Log_warn("SSL: verify error:num=%d:%s:depth=%d:%s\n", err,
404                      X509_verify_cert_error_string(err), depth, buf);
405     }
406     /*
407      * At this point, err contains the last verification error. We can use
408      * it for something special
409      */
410     if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
411             X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
412             Log_warn("issuer= %s", buf);
413     }
414     return 1;
415 }