LCOV - code coverage report
Current view: top level - src - ssl.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 156 0.0 %
Date: 2015-10-31 Functions: 0 12 0.0 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "conf.h"
       4             : #include "log.h"
       5             : #include "server/ca.h"
       6             : 
       7             : static const char *pass=NULL;
       8             : 
       9           0 : int ssl_load_dh_params(SSL_CTX *ctx, struct conf **confs)
      10             : {
      11           0 :         DH *ret=0;
      12           0 :         BIO *bio=NULL;
      13           0 :         const char *ssl_dhfile=get_string(confs[OPT_SSL_DHFILE]);
      14             : 
      15           0 :         if(!(bio=BIO_new_file(ssl_dhfile, "r")))
      16             :         {
      17           0 :                 logp_ssl_err("Couldn't open ssl_dhfile: %s\n", ssl_dhfile);
      18           0 :                 return -1;
      19             :         }
      20             : 
      21           0 :         ret=PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
      22           0 :         BIO_free(bio);
      23           0 :         if(SSL_CTX_set_tmp_dh(ctx, ret)<0)
      24             :         {
      25           0 :                 logp_ssl_err("Couldn't set DH parameters");
      26           0 :                 return -1;
      27             :         }
      28           0 :         return 0;
      29             : }
      30             : 
      31           0 : static int password_cb(char *buf, int num, int rwflag, void *userdata)
      32             : {
      33           0 :         if(num<(int)strlen(pass)+1) return 0;
      34           0 :         strcpy(buf, pass);
      35           0 :         return strlen(pass);
      36             : }
      37             : 
      38           0 : void ssl_load_globals(void)
      39             : {
      40             :         // Global system initialization.
      41           0 :         SSL_library_init();
      42           0 :         SSL_load_error_strings();
      43           0 : }
      44             : 
      45           0 : static int check_path(const char *path, const char *what)
      46             : {
      47             :         struct stat statp;
      48           0 :         if(!path) return -1;
      49           0 :         if(stat(path, &statp))
      50             :         {
      51             :                 logp("Could not find %s %s: %s\n",
      52           0 :                         what, path, strerror(errno));
      53           0 :                 return -1;
      54             :         }
      55           0 :         return 0;
      56             : }
      57             : 
      58           0 : static int ssl_load_keys_and_certs(SSL_CTX *ctx, struct conf **confs)
      59             : {
      60           0 :         char *ssl_key=NULL;
      61           0 :         const char *ssl_cert=get_string(confs[OPT_SSL_CERT]);
      62           0 :         const char *ssl_cert_ca=get_string(confs[OPT_SSL_CERT_CA]);
      63             : 
      64             :         // Load our keys and certificates if the path exists.
      65           0 :         if(!check_path(ssl_cert, "ssl_cert")
      66           0 :           && !SSL_CTX_use_certificate_chain_file(ctx, ssl_cert))
      67             :         {
      68           0 :                 logp_ssl_err("Can't read ssl_cert: %s\n", ssl_cert);
      69           0 :                 return -1;
      70             :         }
      71             : 
      72           0 :         pass=get_string(confs[OPT_SSL_KEY_PASSWORD]);
      73           0 :         SSL_CTX_set_default_passwd_cb(ctx, password_cb);
      74             : 
      75           0 :         ssl_key=get_string(confs[OPT_SSL_KEY]);
      76           0 :         if(!ssl_key) ssl_key=get_string(confs[OPT_SSL_CERT]);
      77             : 
      78             :         // Load the key file, if the path exists.
      79           0 :         if(!check_path(ssl_key, "ssl_key")
      80           0 :           && !SSL_CTX_use_PrivateKey_file(ctx, ssl_key, SSL_FILETYPE_PEM))
      81             :         {
      82           0 :                 logp_ssl_err("Can't read ssl_key file: %s\n", ssl_key);
      83           0 :                 return -1;
      84             :         }
      85             : 
      86             :         // Load the CAs we trust, if the path exists.
      87           0 :         if(!check_path(ssl_cert_ca, "ssl_cert_ca")
      88           0 :           && !SSL_CTX_load_verify_locations(ctx, ssl_cert_ca, 0))
      89             :         {
      90           0 :                 logp_ssl_err("Can't read ssl_cert_ca file: %s\n", ssl_cert_ca);
      91           0 :                 return -1;
      92             :         }
      93             : 
      94           0 :         return 0;
      95             : }
      96             : 
      97           0 : SSL_CTX *ssl_initialise_ctx(struct conf **confs)
      98             : {
      99           0 :         SSL_CTX *ctx=NULL;
     100           0 :         SSL_METHOD *meth=NULL;
     101           0 :         const char *ssl_ciphers=get_string(confs[OPT_SSL_CIPHERS]);
     102             : 
     103             :         // Create our context.
     104           0 :         meth=(SSL_METHOD *)SSLv23_method();
     105           0 :         ctx=(SSL_CTX *)SSL_CTX_new(meth);
     106             : 
     107           0 :         if(ssl_load_keys_and_certs(ctx, confs)) return NULL;
     108             : 
     109           0 :         if(ssl_ciphers)
     110           0 :                 SSL_CTX_set_cipher_list(ctx, ssl_ciphers);
     111             : 
     112             :         // Unclear what is negotiated, so keep quiet until I figure that out.
     113           0 :         if(!get_int(confs[OPT_SSL_COMPRESSION]))
     114             :         {
     115             : #ifdef SSL_OP_NO_COMPRESSION
     116           0 :                 SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
     117             : #else
     118             :                 logp("This version of openssl has no SSL_OP_NO_COMPRESSION option, so turning off config option '%s' will not work. You should probably upgrade openssl.\n", confs[OPT_SSL_COMPRESSION]->field);
     119             : #endif
     120             :         }
     121             :         // Default is zlib5, which needs no option set.
     122             : 
     123           0 :         SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
     124             : 
     125           0 :         return ctx;
     126             : }
     127             : 
     128           0 : void ssl_destroy_ctx(SSL_CTX *ctx)
     129             : {
     130           0 :         SSL_CTX_free(ctx);
     131           0 : }
     132             : 
     133             : #ifndef HAVE_WIN32
     134           0 : static void sanitise(char *buf)
     135             : {
     136           0 :         char *cp=NULL;
     137           0 :         for(cp=buf; *cp; cp++)
     138             :         {
     139           0 :                 if(!isalnum(*cp)
     140           0 :                   && !isblank(*cp)
     141           0 :                   && *cp!='_'
     142           0 :                   && *cp!='-'
     143           0 :                   && *cp!='.'
     144           0 :                   && *cp!=':'
     145           0 :                   && *cp!='@')
     146           0 :                         *cp='_';
     147             :         }
     148           0 : }
     149             : 
     150             : // This function taken from openvpn-2.2.1 and tidied up a bit.
     151           0 : static int setenv_x509(X509_NAME *x509, const char *type)
     152             : {
     153             :         int i, n;
     154             :         int fn_nid;
     155             :         ASN1_OBJECT *fn;
     156             :         ASN1_STRING *val;
     157             :         X509_NAME_ENTRY *ent;
     158             :         const char *objbuf;
     159             :         uint8_t *buf;
     160             :         char *name_expand;
     161             :         size_t name_expand_size;
     162             : 
     163           0 :         n=X509_NAME_entry_count (x509);
     164           0 :         for(i=0; i<n; ++i)
     165             :         {
     166           0 :                 if(!(ent=X509_NAME_get_entry (x509, i))
     167           0 :                   || !(fn=X509_NAME_ENTRY_get_object(ent))
     168           0 :                   || !(val=X509_NAME_ENTRY_get_data(ent))
     169           0 :                   || (fn_nid=OBJ_obj2nid(fn))==NID_undef
     170           0 :                   || !(objbuf=OBJ_nid2sn(fn_nid)))
     171           0 :                         continue;
     172           0 :                 buf=(uint8_t *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
     173           0 :                 if(ASN1_STRING_to_UTF8(&buf, val)<=0) continue;
     174           0 :                 name_expand_size=64+strlen(objbuf);
     175           0 :                 if(!(name_expand=(char *)malloc_w(name_expand_size, __func__)))
     176           0 :                         return -1;
     177             :                 snprintf(name_expand, name_expand_size,
     178           0 :                         "X509_%s_%s", type, objbuf);
     179           0 :                 sanitise(name_expand);
     180           0 :                 sanitise((char*)buf);
     181           0 :                 setenv(name_expand, (char*)buf, 1);
     182           0 :                 free (name_expand);
     183           0 :                 OPENSSL_free (buf);
     184             :         }
     185           0 :         return 0;
     186             : }
     187             : 
     188           0 : static int setenv_x509_date(ASN1_TIME *tm, const char *env)
     189             : {
     190           0 :         BIO *bio_out=NULL;
     191           0 :         BUF_MEM *bptr=NULL;
     192           0 :         char tmpbuf[256]="";
     193           0 :         if(!(bio_out=BIO_new(BIO_s_mem())))
     194             :         {
     195           0 :                 log_out_of_memory(__func__);
     196           0 :                 return -1;
     197             :         }
     198           0 :         ASN1_TIME_print(bio_out, tm);
     199           0 :         BIO_get_mem_ptr(bio_out, &bptr);
     200           0 :         BIO_gets(bio_out, tmpbuf, sizeof(tmpbuf)-1);
     201           0 :         BIO_free_all(bio_out);
     202           0 :         sanitise(tmpbuf);
     203           0 :         setenv(env, (char*)tmpbuf, 1);
     204           0 :         return 0;
     205             : }
     206             : 
     207           0 : static int setenv_x509_serialnumber(ASN1_INTEGER *i, const char *env)
     208             : {
     209           0 :         BIO *bio_out=NULL;
     210           0 :         BUF_MEM *bptr=NULL;
     211           0 :         char tmpbuf[256]="";
     212           0 :         if(!(bio_out=BIO_new(BIO_s_mem())))
     213             :         {
     214           0 :                 log_out_of_memory(__func__);
     215           0 :                 return -1;
     216             :         }
     217           0 :         i2a_ASN1_INTEGER(bio_out, i);
     218           0 :         BIO_get_mem_ptr(bio_out, &bptr);
     219           0 :         BIO_gets(bio_out, tmpbuf, sizeof(tmpbuf)-1);
     220           0 :         BIO_free_all(bio_out);
     221           0 :         sanitise(tmpbuf);
     222           0 :         setenv(env, (char*)tmpbuf, 1);
     223           0 :         return 0;
     224             : }
     225             : #endif
     226             : 
     227           0 : int ssl_check_cert(SSL *ssl, struct conf **confs, struct conf **cconfs)
     228             : {
     229             :         X509 *peer;
     230           0 :         char tmpbuf[256]="";
     231           0 :         const char *ssl_peer_cn=get_string(cconfs[OPT_SSL_PEER_CN]);
     232             : 
     233           0 :         if(!ssl_peer_cn)
     234             :         {
     235           0 :                 logp("ssl_peer_cn not set.\n");
     236           0 :                 return -1;
     237             :         }
     238             : 
     239             :         SSL_CIPHER_description(SSL_get_current_cipher(ssl),
     240           0 :                 tmpbuf, sizeof(tmpbuf));
     241           0 :         logp("SSL is using cipher: %s\n", tmpbuf);
     242           0 :         if(!(peer=SSL_get_peer_certificate(ssl)))
     243             :         {
     244           0 :                 logp("Could not get peer certificate.\n");
     245           0 :                 return -1;
     246             :         }
     247           0 :         if(SSL_get_verify_result(ssl)!=X509_V_OK)
     248             :         {
     249           0 :                 logp_ssl_err("Certificate doesn't verify.\n");
     250           0 :                 return -1;
     251             :         }
     252             : 
     253             :         X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
     254           0 :                 NID_commonName, tmpbuf, sizeof(tmpbuf));
     255           0 :         if(strcasecmp(tmpbuf, ssl_peer_cn))
     256             :         {
     257           0 :                 logp("cert common name doesn't match configured ssl_peer_cn\n");
     258           0 :                 logp("'%s'!='%s'\n", tmpbuf, ssl_peer_cn);
     259           0 :                 return -1;
     260             :         }
     261             : 
     262             : #ifndef HAVE_WIN32
     263             :         // Check the peer certificate against the CRL list only if set
     264             :         // in the configuration file. Thus if not set it is not
     265             :         // breaking the 'ssl_extra_checks_script' configuration.
     266           0 :         if(confs && ca_x509_verify_crl(confs, peer, ssl_peer_cn))
     267           0 :                 return -1;
     268             : 
     269           0 :         if(setenv_x509(X509_get_subject_name(peer), "PEER")
     270           0 :           || setenv_x509(X509_get_issuer_name(peer), "ISSUER"))
     271           0 :                 return -1;
     272             : 
     273           0 :         if(setenv_x509_date(X509_get_notBefore(peer), "X509_PEER_NOT_BEFORE")
     274           0 :           || setenv_x509_date(X509_get_notAfter(peer), "X509_PEER_NOT_AFTER"))
     275           0 :                 return -1;
     276             : 
     277           0 :         if(setenv_x509_serialnumber(X509_get_serialNumber(peer),
     278           0 :                 "X509_PEER_SERIALNUMBER"))
     279           0 :                         return -1;
     280             : #endif
     281             :         //if((comp=SSL_get_current_compression(ssl)))
     282             :         //      logp("SSL is using compression: %s\n", comp->name);
     283             : 
     284           0 :         return 0;
     285             : }

Generated by: LCOV version 1.10