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

Generated by: LCOV version 1.13