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 bool_t builtInTestCertificate;
69 havege_state hs; /* exported to crypt.c */
73 "9CE85640903BF123906947FEDE767261" \
74 "D9B4A973EB8F7D984A8C656E2BCC161C" \
75 "183D4CA471BA78225F940F16D1D99CA3" \
76 "E66152CC68EDCE1311A390F307741835" \
77 "44FF6AB553EC7073AD0CB608F2A3B480" \
78 "19E6C02BCED40BD30E91BB2469089670" \
79 "DEF409C08E8AC24D1732A6128D2220DC53";
82 static void initTestCert()
85 builtInTestCertificate = true;
86 rc = x509parse_crt(&certificate, (unsigned char *)test_srv_crt,
87 strlen(test_srv_crt));
89 Log_fatal("Could not parse built-in test certificate");
90 rc = x509parse_crt(&certificate, (unsigned char *)test_ca_crt,
93 Log_fatal("Could not parse built-in test CA certificate");
96 static void initTestKey()
100 rc = x509parse_key(&key, (unsigned char *)test_srv_key,
101 strlen(test_srv_key), NULL, 0);
103 Log_fatal("Could not parse built-in test RSA key");
107 * openssl genrsa 1024 > host.key
108 * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
110 static void initCert()
113 char *crtfile = (char *)getStrConf(CERTIFICATE);
116 if (crtfile == NULL) {
117 Log_warn("No certificate file specified");
121 rc = x509parse_crtfile(&certificate, crtfile);
123 Log_warn("Could not read certificate file %s", crtfile);
128 /* Look for CA certificate file in same dir */
129 ca_file = malloc(strlen(crtfile) + strlen(CA_CRT_FILENAME) + 1);
130 strcpy(ca_file, crtfile);
131 p = strrchr(ca_file, '/');
133 strcpy(p + 1, CA_CRT_FILENAME);
135 strcpy(ca_file, CA_CRT_FILENAME);
137 rc = x509parse_crtfile(&certificate, ca_file);
138 if (rc != 0) { /* No CA certifiacte found. Assume self-signed. */
139 Log_info("CA certificate file %s not found. Assuming self-signed certificate.", ca_file);
141 * Apparently PolarSSL needs to read something more into certificate chain.
142 * Doesn't seem to matter what. Read own certificate again.
144 rc = x509parse_crtfile(&certificate, crtfile);
146 Log_fatal("Could not read certificate file %s", crtfile);
151 static void initKey()
154 char *keyfile = (char *)getStrConf(KEY);
157 Log_fatal("No key file specified");
158 rc = x509parse_keyfile(&key, keyfile, NULL);
160 Log_fatal("Could not read RSA key file %s", keyfile);
163 #define DEBUG_LEVEL 0
164 static void pssl_debug(void *ctx, int level, char *str)
166 if (level <= DEBUG_LEVEL)
167 Log_debug("PolarSSL [level %d]: %s", level, str);
173 if (builtInTestCertificate) {
174 Log_warn("*** Using built-in test certificate and RSA key ***");
175 Log_warn("*** This is not secure! Please use a CA-signed certificate or create a self-signed certificate ***");
181 Log_info("PolarSSL library initialized");
184 void SSLi_deinit(void)
186 x509_free(&certificate);
190 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
196 ssl = malloc(sizeof(ssl_context));
197 ssn = malloc(sizeof(ssl_session));
199 Log_fatal("Out of memory");
200 memset(ssl, 0, sizeof(ssl_context));
201 memset(ssn, 0, sizeof(ssl_session));
205 Log_fatal("Failed to initalize: %d", rc);
207 ssl_set_endpoint(ssl, SSL_IS_SERVER);
208 ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL);
210 ssl_set_rng(ssl, havege_rand, &hs);
211 ssl_set_dbg(ssl, pssl_debug, NULL);
212 ssl_set_bio(ssl, net_recv, fd, net_send, fd);
214 ssl_set_ciphers(ssl, ciphers);
215 ssl_set_session(ssl, 0, 0, ssn);
217 ssl_set_ca_chain(ssl, certificate.next, NULL, NULL);
218 ssl_set_own_cert(ssl, &certificate, &key);
219 ssl_set_dh_param(ssl, my_dhm_P, my_dhm_G);
224 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
228 rc = ssl_handshake(ssl);
230 if (rc == POLARSSL_ERR_NET_TRY_AGAIN) {
233 Log_warn("SSL handshake failed: %d", rc);
241 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
244 rc = ssl_read(ssl, buf, len);
245 if (rc == POLARSSL_ERR_NET_TRY_AGAIN)
246 return SSLI_ERROR_WANT_READ;
250 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
253 rc = ssl_write(ssl, buf, len);
254 if (rc == POLARSSL_ERR_NET_TRY_AGAIN)
255 return SSLI_ERROR_WANT_WRITE;
259 int SSLi_get_error(SSL_handle_t *ssl, int code)
264 bool_t SSLi_data_pending(SSL_handle_t *ssl)
266 return ssl_get_bytes_avail(ssl) > 0;
269 void SSLi_shutdown(SSL_handle_t *ssl)
271 ssl_close_notify(ssl);
274 void SSLi_free(SSL_handle_t *ssl)
276 Log_debug("SSLi_free");
277 free(ssl->session); /* XXX - Hmmm. */
287 #include <openssl/x509v3.h>
288 #include <openssl/ssl.h>
289 #include <openssl/err.h>
290 #include <openssl/safestack.h>
293 static SSL_CTX *context;
294 static EVP_PKEY *pkey;
296 static int SSL_add_ext(X509 * crt, int nid, char *value) {
299 X509V3_set_ctx_nodb(&ctx);
300 X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
301 ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
305 X509_add_ext(crt, ex, -1);
306 X509_EXTENSION_free(ex);
310 static X509 *SSL_readcert(char *certfile)
315 /* open the private key file */
316 fp = fopen(certfile, "r");
318 Log_warn("Unable to open the X509 file %s for reading.", certfile);
322 /* allocate memory for the cert structure */
325 if (PEM_read_X509(fp, &x509, NULL, NULL) == 0) {
326 /* error reading the x509 information - check the error stack */
327 Log_warn("Error trying to read X509 info.");
336 static RSA *SSL_readprivatekey(char *keyfile)
341 /* open the private key file for reading */
342 fp = fopen(keyfile, "r");
344 Log_warn("Unable to open the private key file %s for reading.", keyfile);
348 /* allocate memory for the RSA structure */
351 /* assign a callback function for the password */
353 /* read a private key from file */
354 if (PEM_read_RSAPrivateKey(fp, &rsa, NULL, NULL) <= 0) {
355 /* error reading the key - check the error stack */
356 Log_warn("Error trying to read private key.");
365 static void SSL_writecert(char *certfile, X509 *x509)
370 /* prepare a BIO for outputting error messages */
372 err_output = BIO_new_fp(stderr,BIO_NOCLOSE);
374 /* open the private key file */
375 fp = fopen(certfile, "w");
377 BIO_printf(err_output, "Unable to open the X509 file for writing.\n");
378 BIO_free(err_output);
382 if (PEM_write_X509(fp, x509) == 0) {
383 BIO_printf(err_output, "Error trying to write X509 info.\n");
384 ERR_print_errors(err_output);
389 static void SSL_writekey(char *keyfile, RSA *rsa)
393 /* prepare a BIO for outputing error messages */
394 err_output = BIO_new_fp(stderr, BIO_NOCLOSE);
396 /* open the private key file for reading */
397 fp = fopen(keyfile, "w");
399 BIO_printf(err_output, "Unable to open the private key file %s for writing.\n", keyfile);
400 BIO_free(err_output);
404 if (PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL) == 0) {
405 /* error reading the key - check the error stack */
406 BIO_printf(err_output, "Error trying to write private key\n");
407 ERR_print_errors(err_output);
412 static void SSL_initializeCert() {
413 char *crt, *key, *pass;
415 crt = (char *)getStrConf(CERTIFICATE);
416 key = (char *)getStrConf(KEY);
417 pass = (char *)getStrConf(PASSPHRASE);
419 x509 = SSL_readcert(crt);
420 rsa = SSL_readprivatekey(key);
422 pkey = EVP_PKEY_new();
423 EVP_PKEY_assign_RSA(pkey, rsa);
429 qscCert = QSslCertificate(key);
430 if (! qscCert.isNull()) {
431 logthis("Using certificate from key.");
435 if (! qscCert.isNull()) {
436 QSsl::KeyAlgorithm alg = qscCert.publicKey().algorithm();
437 /* Fetch algorith from cert */
438 if (! key.isEmpty()) {
440 qskKey = QSslKey(key, alg, QSsl::Pem, QSsl::PrivateKey, pass);
441 if (qskKey.isNull()) {
442 logthis("Failed to parse key.");
446 if (! crt.isEmpty() && qskKey.isNull()) {
447 /* get key from certificate */
448 qskKey = QSslKey(crt, alg, QSsl::Pem, QSsl::PrivateKey, pass);
449 if (! qskKey.isNull()) {
450 logthis("Using key from certificate.");
458 logthis("Generating new server certificate.");
462 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
464 bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
467 pkey = EVP_PKEY_new();
468 rsa = RSA_generate_key(1024,RSA_F4,NULL,NULL);
469 EVP_PKEY_assign_RSA(pkey, rsa);
471 X509_set_version(x509, 2);
472 ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
473 X509_gmtime_adj(X509_get_notBefore(x509),0);
474 X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
475 X509_set_pubkey(x509, pkey);
477 X509_NAME *name=X509_get_subject_name(x509);
479 X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
480 X509_set_issuer_name(x509, name);
481 SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
482 SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
483 SSL_add_ext(x509, NID_subject_key_identifier, "hash");
484 SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
486 X509_sign(x509, pkey, EVP_md5());
488 SSL_writecert(crt, x509);
489 SSL_writekey(key, rsa);
496 const SSL_METHOD *method;
499 STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
501 char cipherstring[1024];
504 OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
505 SSL_load_error_strings(); /* load all error messages */
506 ERR_load_crypto_strings(); /* load all error messages */
507 method = SSLv23_server_method(); /* create new server-method instance */
508 context = SSL_CTX_new(method); /* create new context from method */
511 ERR_print_errors_fp(stderr);
514 SSL_initializeCert();
515 if (SSL_CTX_use_certificate(context, x509) <= 0)
516 Log_fatal("Failed to initialize cert");
517 if (SSL_CTX_use_PrivateKey(context, pkey) <= 0) {
518 ERR_print_errors_fp(stderr);
519 Log_fatal("Failed to initialize private key");
522 /* Set cipher list */
523 ssl = SSL_new(context);
524 cipherlist = (STACK_OF(SSL_CIPHER) *) SSL_get_ciphers(ssl);
525 cipherlist_new = (STACK_OF(SSL_CIPHER) *) sk_SSL_CIPHER_new_null();
527 for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist, i)) != NULL; i++) {
528 if (SSL_CIPHER_get_bits(cipher, NULL) >= 128) {
529 sk_SSL_CIPHER_push(cipherlist_new, cipher);
532 Log_debug("List of ciphers:");
533 if (cipherlist_new) {
534 for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) {
535 Log_debug("%s", SSL_CIPHER_get_name(cipher));
536 offset += snprintf(cipherstring + offset, 1024 - offset, "%s:", SSL_CIPHER_get_name(cipher));
538 cipherstring[offset - 1] = '\0';
542 sk_SSL_CIPHER_free(cipherlist_new);
544 if (strlen(cipherstring) == 0)
545 Log_fatal("No suitable ciphers found!");
547 if (SSL_CTX_set_cipher_list(context, cipherstring) == 0)
548 Log_fatal("Failed to set cipher list!");
552 Log_info("OpenSSL library initialized");
556 void SSLi_deinit(void)
558 SSL_CTX_free(context);
562 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
565 rc = SSL_accept(ssl);
567 if (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ ||
568 SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) {
569 Log_debug("SSL not ready");
572 Log_warn("SSL error: %s", ERR_error_string(SSL_get_error(ssl, rc), NULL));
580 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
585 ssl = SSL_new(context);
586 SSL_set_fd(ssl, *fd);
587 if (SSLi_nonblockaccept(ssl, SSLready) < 0) {
594 void SSLi_closeconnection(SSL_handle_t *ssl)
599 void SSLi_shutdown(SSL_handle_t *ssl)
604 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
606 return SSL_read(ssl, buf, len);
609 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
611 return SSL_write(ssl, buf, len);
614 int SSLi_get_error(SSL_handle_t *ssl, int code)
616 return SSL_get_error(ssl, code);
619 bool_t SSLi_data_pending(SSL_handle_t *ssl)
621 return SSL_pending(ssl);
624 void SSLi_free(SSL_handle_t *ssl)