X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fssl.c;h=9c5236ec6815dff9d70f16890e1d5c973b436b7f;hb=b95d77db3f58c300c5e0a9c11862a4ba529ce82b;hp=964d7eece5d1af2b982a8cd29e0bd2395f1324b3;hpb=4f5079fe2b925b52a21162267614f4f5ed8f5a6b;p=umurmur.git diff --git a/src/ssl.c b/src/ssl.c index 964d7ee..9c5236e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1,5 +1,5 @@ -/* Copyright (C) 2009-2011, Martin Johansson - Copyright (C) 2005-2011, Thorvald Natvig +/* Copyright (C) 2009-2012, Martin Johansson + Copyright (C) 2005-2012, Thorvald Natvig All rights reserved. @@ -30,6 +30,7 @@ */ #include #include +#include #include "conf.h" #include "log.h" @@ -46,25 +47,32 @@ #include #include +#ifdef POLARSSL_API_V1_2 +int ciphers[] = +{ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + 0 +}; +#else int ciphers[] = { SSL_EDH_RSA_AES_256_SHA, - SSL_EDH_RSA_CAMELLIA_256_SHA, - SSL_EDH_RSA_DES_168_SHA, SSL_RSA_AES_256_SHA, - SSL_RSA_CAMELLIA_256_SHA, SSL_RSA_AES_128_SHA, - SSL_RSA_CAMELLIA_128_SHA, - SSL_RSA_DES_168_SHA, - SSL_RSA_RC4_128_SHA, - SSL_RSA_RC4_128_MD5, 0 }; +#endif static x509_cert certificate; static rsa_context key; bool_t builtInTestCertificate; -havege_state hs; /* exported to crypt.c */ +#ifdef USE_POLARSSL_HAVEGE +havege_state hs; +#else +int urandom_fd; +#endif /* DH prime */ char *my_dhm_P = @@ -77,6 +85,7 @@ char *my_dhm_P = "DEF409C08E8AC24D1732A6128D2220DC53"; char *my_dhm_G = "4"; +#ifdef USE_POLARSSL_TESTCERT static void initTestCert() { int rc; @@ -96,6 +105,7 @@ static void initTestKey() if (rc != 0) Log_fatal("Could not parse built-in test RSA key"); } +#endif /* * How to generate a self-signed cert with openssl: @@ -108,14 +118,22 @@ static void initCert() char *crtfile = (char *)getStrConf(CERTIFICATE); if (crtfile == NULL) { - Log_warn("No certificate file specified"); +#ifdef USE_POLARSSL_TESTCERT + Log_warn("No certificate file specified. Falling back to test certificate."); initTestCert(); +#else + Log_fatal("No certificate file specified"); +#endif return; } rc = x509parse_crtfile(&certificate, crtfile); if (rc != 0) { - Log_warn("Could not read certificate file %s", crtfile); +#ifdef USE_POLARSSL_TESTCERT + Log_warn("Could not read certificate file '%s'. Falling back to test certificate.", crtfile); initTestCert(); +#else + Log_fatal("Could not read certificate file '%s'", crtfile); +#endif return; } } @@ -132,6 +150,20 @@ static void initKey() Log_fatal("Could not read RSA key file %s", keyfile); } +#ifndef USE_POLARSSL_HAVEGE +int urandom_bytes(void *ctx, unsigned char *dest, size_t len) +{ + int cur; + + while (len) { + cur = read(urandom_fd, dest, len); + if (cur < 0) + continue; + len -= cur; + } +} +#endif + #define DEBUG_LEVEL 0 static void pssl_debug(void *ctx, int level, const char *str) { @@ -144,14 +176,27 @@ void SSLi_init(void) char verstring[12]; initCert(); +#ifdef USE_POLARSSL_TESTCERT if (builtInTestCertificate) { Log_warn("*** Using built-in test certificate and RSA key ***"); - Log_warn("*** This is not secure! Please use a CA-signed certificate or create a self-signed certificate ***"); + Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***"); initTestKey(); } else initKey(); +#else + initKey(); +#endif + + /* Initialize random number generator */ +#ifdef USE_POLARSSL_HAVEGE havege_init(&hs); +#else + urandom_fd = open("/dev/urandom", O_RDONLY); + if (urandom_fd < 0) + Log_fatal("Cannot open /dev/urandom"); + Log_info("Using random number generator /dev/urandom"); +#endif #ifdef POLARSSL_VERSION_MAJOR version_get_string(verstring); @@ -170,9 +215,13 @@ void SSLi_deinit(void) /* Create SHA1 of last certificate in the peer's chain. */ bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash) { - x509_cert *cert = ssl->peer_cert; - if (!ssl->peer_cert) { - /* XXX what to do? */ + x509_cert const *cert; +#ifdef POLARSSL_API_V1_2 + cert = ssl_get_peer_cert(ssl); +#else + cert = ssl->peer_cert; +#endif + if (!cert) { return false; } sha1(cert->raw.p, cert->raw.len, hash); @@ -194,12 +243,17 @@ SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready) rc = ssl_init(ssl); if (rc != 0 ) - Log_fatal("Failed to initalize: %d", rc); + Log_fatal("Failed to initialize: %d", rc); ssl_set_endpoint(ssl, SSL_IS_SERVER); ssl_set_authmode(ssl, SSL_VERIFY_OPTIONAL); - + +#ifdef USE_POLARSSL_HAVEGE ssl_set_rng(ssl, HAVEGE_RAND, &hs); +#else + ssl_set_rng(ssl, urandom_bytes, NULL); +#endif + ssl_set_dbg(ssl, pssl_debug, NULL); ssl_set_bio(ssl, net_recv, fd, net_send, fd); @@ -208,7 +262,12 @@ SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready) #else ssl_set_ciphers(ssl, ciphers); #endif + +#ifdef POLARSSL_API_V1_2 + ssl_set_session(ssl, ssn); +#else ssl_set_session(ssl, 0, 0, ssn); +#endif ssl_set_ca_chain(ssl, &certificate, NULL, NULL); ssl_set_own_cert(ssl, &certificate, &key); @@ -509,10 +568,10 @@ void SSLi_init(void) { const SSL_METHOD *method; SSL *ssl; - int i, offset = 0; + int i, offset = 0, cipherstringlen = 0; STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL; SSL_CIPHER *cipher; - char cipherstring[1024]; + char *cipherstring, tempstring[128]; SSL_library_init(); OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */ @@ -545,11 +604,16 @@ void SSLi_init(void) } Log_debug("List of ciphers:"); if (cipherlist_new) { - for ( i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) { + for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) { Log_debug("%s", SSL_CIPHER_get_name(cipher)); - offset += snprintf(cipherstring + offset, 1024 - offset, "%s:", SSL_CIPHER_get_name(cipher)); + cipherstringlen += strlen(SSL_CIPHER_get_name(cipher)) + 1; + } + cipherstring = malloc(cipherstringlen + 1); + if (cipherstring == NULL) + Log_fatal("Out of memory"); + for (i = 0; (cipher = sk_SSL_CIPHER_value(cipherlist_new, i)) != NULL; i++) { + offset += sprintf(cipherstring + offset, "%s:", SSL_CIPHER_get_name(cipher)); } - cipherstring[offset - 1] = '\0'; } if (cipherlist_new) @@ -560,6 +624,8 @@ void SSLi_init(void) if (SSL_CTX_set_cipher_list(context, cipherstring) == 0) Log_fatal("Failed to set cipher list!"); + + free(cipherstring); SSL_CTX_set_verify(context, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verify_callback); @@ -615,7 +681,7 @@ bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash) int len; x509 = SSL_get_peer_certificate(ssl); - if (x509) { + if (!x509) { return false; } @@ -624,10 +690,11 @@ bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash) if (buf == NULL) { Log_fatal("malloc"); } + + p = buf; + i2d_X509(x509, &p); - i2d_X509(x509, &p); - - SHA1(p, len, hash); + SHA1(buf, len, hash); free(buf); return true; } @@ -687,17 +754,16 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) X509_STORE_CTX_set_error(ctx, err); } if (!preverify_ok) { - Log_warn("verify error:num=%d:%s:depth=%d:%s\n", err, + Log_warn("SSL: verify error:num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf); } /* * At this point, err contains the last verification error. We can use * it for something special */ - if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) - { + if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) { X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); - Log_warn("issuer= %s", buf); + Log_warn("issuer= %s", buf); } return 1; }