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

Generated by: LCOV version 1.13