LCOV - code coverage report
Current view: top level - src - ssl.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 7 152 4.6 %
Date: 2016-07-02 Functions: 2 13 15.4 %

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

Generated by: LCOV version 1.10