1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
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.
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.
43 #include <openssl/x509v3.h>
44 #include <openssl/ssl.h>
45 #include <openssl/err.h>
46 #include <openssl/safestack.h>
49 static SSL_CTX *context;
50 static EVP_PKEY *pkey;
52 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx);
54 static int SSL_add_ext(X509 * crt, int nid, char *value) {
57 X509V3_set_ctx_nodb(&ctx);
58 X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
59 ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
63 X509_add_ext(crt, ex, -1);
64 X509_EXTENSION_free(ex);
68 static X509 *SSL_readcert(char *certfile)
73 /* open the certificate file */
74 fp = fopen(certfile, "r");
76 Log_warn("Unable to open the X509 file %s for reading.", certfile);
80 /* allocate memory for the cert structure */
83 if (PEM_read_X509(fp, &x509, NULL, NULL) == 0) {
84 /* error reading the x509 information - check the error stack */
85 Log_warn("Error trying to read X509 info.");
94 static RSA *SSL_readprivatekey(char *keyfile)
99 /* open the private key file for reading */
100 fp = fopen(keyfile, "r");
102 Log_warn("Unable to open the private key file %s for reading.", keyfile);
106 /* allocate memory for the RSA structure */
109 /* assign a callback function for the password */
111 /* read a private key from file */
112 if (PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) <= 0) {
113 /* error reading the key - check the error stack */
114 Log_warn("Error trying to read private key.");
123 static void SSL_writecert(char *certfile, X509 *x509)
127 /* open the private key file */
128 fp = fopen(certfile, "w");
130 Log_warn("Unable to open the X509 file %s for writing", certfile);
133 if (PEM_write_X509(fp, x509) == 0) {
134 Log_warn("Error trying to write X509 info.");
139 static void SSL_writekey(char *keyfile, RSA *rsa)
143 /* open the private key file for reading */
144 fp = fopen(keyfile, "w");
146 Log_warn("Unable to open the private key file %s for writing.", keyfile);
150 if (PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL) == 0) {
151 Log_warn("Error trying to write private key");
156 static void SSL_initializeCert() {
158 char *crt = (char *)getStrConf(CERTIFICATE);
159 char *key = (char *)getStrConf(KEY);
162 bool_t did_load_cert = SSL_CTX_use_certificate_chain_file(context, crt);
163 rsa = SSL_readprivatekey(key);
165 if (!rsa || !did_load_cert) {
166 Log_info("Generating new server certificate.");
169 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
172 pkey = EVP_PKEY_new();
173 rsa = RSA_generate_key(4096,RSA_F4,NULL,NULL);
174 EVP_PKEY_assign_RSA(pkey, rsa);
176 X509_set_version(x509, 2);
177 ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
178 X509_gmtime_adj(X509_get_notBefore(x509),0);
179 X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
180 X509_set_pubkey(x509, pkey);
182 X509_NAME *name=X509_get_subject_name(x509);
184 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
185 X509_set_issuer_name(x509, name);
186 SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
187 SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
188 SSL_add_ext(x509, NID_subject_key_identifier, "hash");
189 SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
191 X509_sign(x509, pkey, EVP_md5());
193 SSL_writecert(crt, x509);
194 SSL_writekey(key, rsa);
196 SSL_CTX_use_certificate(context, x509);
198 pkey = EVP_PKEY_new();
199 EVP_PKEY_assign_RSA(pkey, rsa);
202 SSL_CTX_use_PrivateKey(context, pkey);
205 Log_fatal("Failed to initialize TLS context.");
213 int i, offset = 0, cipherstringlen = 0;
214 STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
219 OpenSSL_add_all_algorithms();
220 SSL_load_error_strings();
221 ERR_load_crypto_strings();
223 context = SSL_CTX_new(SSLv23_server_method());
226 ERR_print_errors_fp(stderr);
230 char const * sslCAPath = getStrConf(CAPATH);
231 if(sslCAPath != NULL)
233 SSL_CTX_load_verify_locations(context, NULL, sslCAPath);
236 SSL_initializeCert();
238 /* Set cipher list */
239 ssl = SSL_new(context);
240 cipherlist = (STACK_OF(SSL_CIPHER) *) SSL_get_ciphers(ssl);
241 cipherlist_new = (STACK_OF(SSL_CIPHER) *) sk_SSL_CIPHER_new_null();
243 for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist, i)) != NULL; i++) {
244 if (SSL_CIPHER_get_bits(cipher, NULL) >= 128) {
245 sk_SSL_CIPHER_push(cipherlist_new, cipher);
248 Log_debug("List of ciphers:");
249 if (cipherlist_new) {
250 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
251 Log_debug("%s", SSL_CIPHER_get_name(cipher));
252 cipherstringlen += strlen(SSL_CIPHER_get_name(cipher)) + 1;
254 cipherstring = Memory_safeMalloc(1, cipherstringlen + 1);
255 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
256 offset += sprintf(cipherstring + offset, "%s:", SSL_CIPHER_get_name(cipher));
261 sk_SSL_CIPHER_free(cipherlist_new);
263 if (strlen(cipherstring) == 0)
264 Log_fatal("No suitable ciphers found!");
266 if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
267 Log_fatal("Failed to set cipher list!");
271 SSL_CTX_set_verify(context, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
275 Log_info("OpenSSL library initialized");
279 void SSLi_deinit(void)
281 SSL_CTX_free(context);
285 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
288 rc = SSL_accept(ssl);
290 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
291 SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
292 Log_debug("SSL not ready");
295 Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
303 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
308 ssl = SSL_new(context);
309 SSL_set_fd(ssl, *fd);
310 if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
317 /* Create SHA1 of last certificate in the peer's chain. */
318 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
324 x509 = SSL_get_peer_certificate(ssl);
329 len = i2d_X509(x509, NULL);
330 buf = Memory_safeMalloc(1, len);
335 SHA1(buf, len, hash);
340 void SSLi_closeconnection(SSL_handle_t *ssl)
345 void SSLi_shutdown(SSL_handle_t *ssl)
350 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
352 return SSL_read(ssl, buf, len);
355 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
357 return SSL_write(ssl, buf, len);
360 int SSLi_get_error(SSL_handle_t *ssl, int code)
362 return SSL_get_error(ssl, code);
365 bool_t SSLi_data_pending(SSL_handle_t *ssl)
367 return SSL_pending(ssl);
370 void SSLi_free(SSL_handle_t *ssl)
375 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
382 err_cert = X509_STORE_CTX_get_current_cert(ctx);
383 err = X509_STORE_CTX_get_error(ctx);
384 depth = X509_STORE_CTX_get_error_depth(ctx);
386 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
387 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
391 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
392 X509_STORE_CTX_set_error(ctx, err);
395 Log_warn("SSL: verify error:num=%d:%s:depth=%d:%s\n", err,
396 X509_verify_cert_error_string(err), depth, buf);
399 * At this point, err contains the last verification error. We can use
400 * it for something special
402 if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
403 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
404 Log_warn("issuer= %s", buf);