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.
42 #include <openssl/x509v3.h>
43 #include <openssl/ssl.h>
44 #include <openssl/err.h>
45 #include <openssl/safestack.h>
48 static SSL_CTX *context;
49 static EVP_PKEY *pkey;
51 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx);
53 static int SSL_add_ext(X509 * crt, int nid, char *value) {
56 X509V3_set_ctx_nodb(&ctx);
57 X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
58 ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
62 X509_add_ext(crt, ex, -1);
63 X509_EXTENSION_free(ex);
67 static X509 *SSL_readcert(char *certfile)
72 /* open the certificate file */
73 fp = fopen(certfile, "r");
75 Log_warn("Unable to open the X509 file %s for reading.", certfile);
79 /* allocate memory for the cert structure */
82 if (PEM_read_X509(fp, &x509, NULL, NULL) == 0) {
83 /* error reading the x509 information - check the error stack */
84 Log_warn("Error trying to read X509 info.");
93 static RSA *SSL_readprivatekey(char *keyfile)
98 /* open the private key file for reading */
99 fp = fopen(keyfile, "r");
101 Log_warn("Unable to open the private key file %s for reading.", keyfile);
105 /* allocate memory for the RSA structure */
108 /* assign a callback function for the password */
110 /* read a private key from file */
111 if (PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) <= 0) {
112 /* error reading the key - check the error stack */
113 Log_warn("Error trying to read private key.");
122 static void SSL_writecert(char *certfile, X509 *x509)
126 /* open the private key file */
127 fp = fopen(certfile, "w");
129 Log_warn("Unable to open the X509 file %s for writing", certfile);
132 if (PEM_write_X509(fp, x509) == 0) {
133 Log_warn("Error trying to write X509 info.");
138 static void SSL_writekey(char *keyfile, RSA *rsa)
142 /* open the private key file for reading */
143 fp = fopen(keyfile, "w");
145 Log_warn("Unable to open the private key file %s for writing.", keyfile);
149 if (PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL) == 0) {
150 Log_warn("Error trying to write private key");
155 static void SSL_initializeCert() {
157 char *crt = (char *)getStrConf(CERTIFICATE);
158 char *key = (char *)getStrConf(KEY);
161 bool did_load_cert = SSL_CTX_use_certificate_chain_file(context, crt);
162 rsa = SSL_readprivatekey(key);
164 if (!rsa || !did_load_cert) {
165 Log_info("Generating new server certificate.");
168 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
171 pkey = EVP_PKEY_new();
172 rsa = RSA_generate_key(4096,RSA_F4,NULL,NULL);
173 EVP_PKEY_assign_RSA(pkey, rsa);
175 X509_set_version(x509, 2);
176 ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
177 X509_gmtime_adj(X509_get_notBefore(x509),0);
178 X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
179 X509_set_pubkey(x509, pkey);
181 X509_NAME *name=X509_get_subject_name(x509);
183 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
184 X509_set_issuer_name(x509, name);
185 SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
186 SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
187 SSL_add_ext(x509, NID_subject_key_identifier, "hash");
188 SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
190 X509_sign(x509, pkey, EVP_md5());
192 SSL_writecert(crt, x509);
193 SSL_writekey(key, rsa);
195 SSL_CTX_use_certificate(context, x509);
197 pkey = EVP_PKEY_new();
198 EVP_PKEY_assign_RSA(pkey, rsa);
201 SSL_CTX_use_PrivateKey(context, pkey);
204 Log_fatal("Failed to initialize TLS context.");
212 int i, offset = 0, cipherstringlen = 0;
213 STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
218 OpenSSL_add_all_algorithms();
219 SSL_load_error_strings();
220 ERR_load_crypto_strings();
222 context = SSL_CTX_new(SSLv23_server_method());
225 ERR_print_errors_fp(stderr);
229 char const * sslCAPath = getStrConf(CAPATH);
230 if(sslCAPath != NULL)
232 SSL_CTX_load_verify_locations(context, NULL, sslCAPath);
235 SSL_initializeCert();
237 /* Set cipher list */
238 ssl = SSL_new(context);
239 cipherlist = (STACK_OF(SSL_CIPHER) *) SSL_get_ciphers(ssl);
240 cipherlist_new = (STACK_OF(SSL_CIPHER) *) sk_SSL_CIPHER_new_null();
242 for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist, i)) != NULL; i++) {
243 if (SSL_CIPHER_get_bits(cipher, NULL) >= 128) {
244 sk_SSL_CIPHER_push(cipherlist_new, cipher);
247 Log_debug("List of ciphers:");
248 if (cipherlist_new) {
249 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
250 Log_debug("%s", SSL_CIPHER_get_name(cipher));
251 cipherstringlen += strlen(SSL_CIPHER_get_name(cipher)) + 1;
253 cipherstring = malloc(cipherstringlen + 1);
254 if (cipherstring == NULL)
255 Log_fatal("Out of memory");
256 for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
257 offset += sprintf(cipherstring + offset, "%s:", SSL_CIPHER_get_name(cipher));
262 sk_SSL_CIPHER_free(cipherlist_new);
264 if (strlen(cipherstring) == 0)
265 Log_fatal("No suitable ciphers found!");
267 if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
268 Log_fatal("Failed to set cipher list!");
272 SSL_CTX_set_verify(context, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
276 Log_info("OpenSSL library initialized");
280 void SSLi_deinit(void)
282 SSL_CTX_free(context);
286 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
289 rc = SSL_accept(ssl);
291 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
292 SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
293 Log_debug("SSL not ready");
296 Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
304 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
309 ssl = SSL_new(context);
310 SSL_set_fd(ssl, *fd);
311 if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
318 /* Create SHA1 of last certificate in the peer's chain. */
319 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
325 x509 = SSL_get_peer_certificate(ssl);
330 len = i2d_X509(x509, NULL);
339 SHA1(buf, len, hash);
344 void SSLi_closeconnection(SSL_handle_t *ssl)
349 void SSLi_shutdown(SSL_handle_t *ssl)
354 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
356 return SSL_read(ssl, buf, len);
359 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
361 return SSL_write(ssl, buf, len);
364 int SSLi_get_error(SSL_handle_t *ssl, int code)
366 return SSL_get_error(ssl, code);
369 bool_t SSLi_data_pending(SSL_handle_t *ssl)
371 return SSL_pending(ssl);
374 void SSLi_free(SSL_handle_t *ssl)
379 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
386 err_cert = X509_STORE_CTX_get_current_cert(ctx);
387 err = X509_STORE_CTX_get_error(ctx);
388 depth = X509_STORE_CTX_get_error_depth(ctx);
390 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
391 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
395 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
396 X509_STORE_CTX_set_error(ctx, err);
399 Log_warn("SSL: verify error:num=%d:%s:depth=%d:%s\n", err,
400 X509_verify_cert_error_string(err), depth, buf);
403 * At this point, err contains the last verification error. We can use
404 * it for something special
406 if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) {
407 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
408 Log_warn("issuer= %s", buf);