1 /* Copyright (C) 2009-2010, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2010, 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 <polarssl/havege.h>
44 #include <polarssl/certs.h>
45 #include <polarssl/x509.h>
46 #include <polarssl/ssl.h>
47 #include <polarssl/net.h>
49 #define CA_CRT_FILENAME "ca.crt"
53 SSL_EDH_RSA_AES_256_SHA,
54 SSL_EDH_RSA_CAMELLIA_256_SHA,
55 SSL_EDH_RSA_DES_168_SHA,
57 SSL_RSA_CAMELLIA_256_SHA,
59 SSL_RSA_CAMELLIA_128_SHA,
65 static x509_cert certificate;
66 static rsa_context key;
67 havege_state hs; /* exported to crypt.c */
71 "9CE85640903BF123906947FEDE767261" \
72 "D9B4A973EB8F7D984A8C656E2BCC161C" \
73 "183D4CA471BA78225F940F16D1D99CA3" \
74 "E66152CC68EDCE1311A390F307741835" \
75 "44FF6AB553EC7073AD0CB608F2A3B480" \
76 "19E6C02BCED40BD30E91BB2469089670" \
77 "DEF409C08E8AC24D1732A6128D2220DC53";
80 static void initCert()
83 char *crtfile = (char *)getStrConf(CERTIFICATE);
87 Log_fatal("No certificate file specified");
88 rc = x509parse_crtfile(&certificate, crtfile);
90 Log_fatal("Could not read certificate file %s", crtfile);
92 /* Look for CA certificate file in same dir */
93 ca_file = malloc(strlen(crtfile) + strlen(CA_CRT_FILENAME) + 1);
94 strcpy(ca_file, crtfile);
95 p = strrchr(ca_file, '/');
97 strcpy(p + 1, CA_CRT_FILENAME);
99 strcpy(ca_file, CA_CRT_FILENAME);
101 rc = x509parse_crtfile(&certificate, ca_file);
102 if (rc != 0) { /* No CA certifiacte found. Assume self-signed. */
103 Log_info("CA certificate file %s not found. Assuming self-signed certificate.", ca_file);
105 * Apparently PolarSSL needs to read something more into certificate chain.
106 * Doesn't seem to matter what. Read own certificate again.
108 rc = x509parse_crtfile(&certificate, crtfile);
110 Log_fatal("Could not read certificate file %s", crtfile);
114 static void initKey()
117 char *keyfile = (char *)getStrConf(KEY);
120 Log_fatal("No key file specified");
121 rc = x509parse_keyfile(&key, keyfile, NULL);
123 Log_fatal("Could not read RSA key file %s", keyfile);
126 #define DEBUG_LEVEL 0
127 static void pssl_debug(void *ctx, int level, char *str)
129 if (level <= DEBUG_LEVEL)
130 Log_debug("PolarSSL [level %d]: %s", level, str);
138 Log_info("PolarSSL library initialized");
141 void SSLi_deinit(void)
143 x509_free(&certificate);
147 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
153 ssl = malloc(sizeof(ssl_context));
154 ssn = malloc(sizeof(ssl_session));
156 Log_fatal("Out of memory");
157 memset(ssl, 0, sizeof(ssl_context));
158 memset(ssn, 0, sizeof(ssl_session));
162 Log_fatal("Failed to initalize: %d", rc);
164 ssl_set_endpoint(ssl, SSL_IS_SERVER);
165 ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL);
167 ssl_set_rng(ssl, havege_rand, &hs);
168 ssl_set_dbg(ssl, pssl_debug, NULL);
169 ssl_set_bio(ssl, net_recv, fd, net_send, fd);
171 ssl_set_ciphers(ssl, ciphers);
172 ssl_set_session(ssl, 0, 0, ssn);
174 ssl_set_ca_chain(ssl, certificate.next, NULL, NULL);
175 ssl_set_own_cert(ssl, &certificate, &key);
176 ssl_set_dh_param(ssl, my_dhm_P, my_dhm_G);
181 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
185 rc = ssl_handshake(ssl);
187 if (rc == POLARSSL_ERR_NET_TRY_AGAIN) {
190 Log_warn("SSL handshake failed: %d", rc);
198 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
201 rc = ssl_read(ssl, buf, len);
202 if (rc == POLARSSL_ERR_NET_TRY_AGAIN)
203 return SSLI_ERROR_WANT_READ;
207 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
210 rc = ssl_write(ssl, buf, len);
211 if (rc == POLARSSL_ERR_NET_TRY_AGAIN)
212 return SSLI_ERROR_WANT_WRITE;
216 int SSLi_get_error(SSL_handle_t *ssl, int code)
221 bool_t SSLi_data_pending(SSL_handle_t *ssl)
223 return ssl_get_bytes_avail(ssl) > 0;
226 void SSLi_shutdown(SSL_handle_t *ssl)
228 ssl_close_notify(ssl);
231 void SSLi_free(SSL_handle_t *ssl)
242 #include <openssl/x509v3.h>
243 #include <openssl/ssl.h>
244 #include <openssl/err.h>
245 #include <openssl/safestack.h>
248 static SSL_CTX *context;
249 static EVP_PKEY *pkey;
251 static int SSL_add_ext(X509 * crt, int nid, char *value) {
254 X509V3_set_ctx_nodb(&ctx);
255 X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
256 ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
260 X509_add_ext(crt, ex, -1);
261 X509_EXTENSION_free(ex);
265 static X509 *SSL_readcert(char *certfile)
270 /* open the private key file */
271 fp = fopen(certfile, "r");
273 Log_warn("Unable to open the X509 file %s for reading.", certfile);
277 /* allocate memory for the cert structure */
280 if (PEM_read_X509(fp, &x509, NULL, NULL) == 0) {
281 /* error reading the x509 information - check the error stack */
282 Log_warn("Error trying to read X509 info.");
291 static RSA *SSL_readprivatekey(char *keyfile)
296 /* open the private key file for reading */
297 fp = fopen(keyfile, "r");
299 Log_warn("Unable to open the private key file %s for reading.", keyfile);
303 /* allocate memory for the RSA structure */
306 /* assign a callback function for the password */
308 /* read a private key from file */
309 if (PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) <= 0) {
310 /* error reading the key - check the error stack */
311 Log_warn("Error trying to read private key.");
320 static void SSL_writecert(char *certfile, X509 *x509)
325 /* prepare a BIO for outputting error messages */
327 err_output = BIO_new_fp(stderr,BIO_NOCLOSE);
329 /* open the private key file */
330 fp = fopen(certfile, "w");
332 BIO_printf(err_output, "Unable to open the X509 file for writing.\n");
333 BIO_free(err_output);
337 if (PEM_write_X509(fp, x509) == 0) {
338 BIO_printf(err_output, "Error trying to write X509 info.\n");
339 ERR_print_errors(err_output);
344 static void SSL_writekey(char *keyfile, RSA *rsa)
348 /* prepare a BIO for outputing error messages */
349 err_output = BIO_new_fp(stderr, BIO_NOCLOSE);
351 /* open the private key file for reading */
352 fp = fopen(keyfile, "w");
354 BIO_printf(err_output, "Unable to open the private key file %s for writing.\n", keyfile);
355 BIO_free(err_output);
359 if (PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL) == 0) {
360 /* error reading the key - check the error stack */
361 BIO_printf(err_output, "Error trying to write private key\n");
362 ERR_print_errors(err_output);
367 static void SSL_initializeCert() {
368 char *crt, *key, *pass;
370 crt = (char *)getStrConf(CERTIFICATE);
371 key = (char *)getStrConf(KEY);
372 pass = (char *)getStrConf(PASSPHRASE);
374 x509 = SSL_readcert(crt);
375 rsa = SSL_readprivatekey(key);
377 pkey = EVP_PKEY_new();
378 EVP_PKEY_assign_RSA(pkey, rsa);
384 qscCert = QSslCertificate(key);
385 if (! qscCert.isNull()) {
386 logthis("Using certificate from key.");
390 if (! qscCert.isNull()) {
391 QSsl::KeyAlgorithm alg = qscCert.publicKey().algorithm();
392 /* Fetch algorith from cert */
393 if (! key.isEmpty()) {
395 qskKey = QSslKey(key, alg, QSsl::Pem, QSsl::PrivateKey, pass);
396 if (qskKey.isNull()) {
397 logthis("Failed to parse key.");
401 if (! crt.isEmpty() && qskKey.isNull()) {
402 /* get key from certificate */
403 qskKey = QSslKey(crt, alg, QSsl::Pem, QSsl::PrivateKey, pass);
404 if (! qskKey.isNull()) {
405 logthis("Using key from certificate.");
413 logthis("Generating new server certificate.");
417 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
419 bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
422 pkey = EVP_PKEY_new();
423 rsa = RSA_generate_key(1024,RSA_F4,NULL,NULL);
424 EVP_PKEY_assign_RSA(pkey, rsa);
426 X509_set_version(x509, 2);
427 ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
428 X509_gmtime_adj(X509_get_notBefore(x509),0);
429 X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
430 X509_set_pubkey(x509, pkey);
432 X509_NAME *name=X509_get_subject_name(x509);
434 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
435 X509_set_issuer_name(x509, name);
436 SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
437 SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
438 SSL_add_ext(x509, NID_subject_key_identifier, "hash");
439 SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
441 X509_sign(x509, pkey, EVP_md5());
443 SSL_writecert(crt, x509);
444 SSL_writekey(key, rsa);
451 const SSL_METHOD *method;
454 STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
456 char cipherstring[1024];
459 OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
460 SSL_load_error_strings(); /* load all error messages */
461 ERR_load_crypto_strings(); /* load all error messages */
462 method = SSLv23_server_method(); /* create new server-method instance */
463 context = SSL_CTX_new(method); /* create new context from method */
466 ERR_print_errors_fp(stderr);
469 SSL_initializeCert();
470 if (SSL_CTX_use_certificate(context, x509) <= 0)
471 Log_fatal("Failed to initialize cert");
472 if (SSL_CTX_use_PrivateKey(context, pkey) <= 0) {
473 ERR_print_errors_fp(stderr);
474 Log_fatal("Failed to initialize private key");
477 /* Set cipher list */
478 ssl = SSL_new(context);
479 cipherlist = (STACK_OF(SSL_CIPHER) *) SSL_get_ciphers(ssl);
480 cipherlist_new = (STACK_OF(SSL_CIPHER) *) sk_SSL_CIPHER_new_null();
482 for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist, i)) != NULL; i++) {
483 if (SSL_CIPHER_get_bits(cipher, NULL) >= 128) {
484 sk_SSL_CIPHER_push(cipherlist_new, cipher);
487 Log_debug("List of ciphers:");
488 if (cipherlist_new) {
489 for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
490 Log_debug("%s", SSL_CIPHER_get_name(cipher));
491 offset += snprintf(cipherstring + offset, 1024 - offset, "%s:", SSL_CIPHER_get_name(cipher));
493 cipherstring[offset - 1] = '\0';
497 sk_SSL_CIPHER_free(cipherlist_new);
499 if (strlen(cipherstring) == 0)
500 Log_fatal("No suitable ciphers found!");
502 if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
503 Log_fatal("Failed to set cipher list!");
507 Log_info("OpenSSL library initialized");
511 void SSLi_deinit(void)
513 SSL_CTX_free(context);
517 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
520 rc = SSL_accept(ssl);
522 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
523 SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
524 Log_debug("SSL not ready");
527 Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
535 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
540 ssl = SSL_new(context);
541 SSL_set_fd(ssl, *fd);
542 if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
549 void SSLi_closeconnection(SSL_handle_t *ssl)
554 void SSLi_shutdown(SSL_handle_t *ssl)
559 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
561 return SSL_read(ssl, buf, len);
564 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
566 return SSL_write(ssl, buf, len);
569 int SSLi_get_error(SSL_handle_t *ssl, int code)
571 return SSL_get_error(ssl, code);
574 bool_t SSLi_data_pending(SSL_handle_t *ssl)
576 return SSL_pending(ssl);
579 void SSLi_free(SSL_handle_t *ssl)