"Fossies" - the Fresh Open Source Software Archive

Member "sendmail-8.15.2/sendmail/tls.c" (20 Jun 2015, 49707 Bytes) of package /linux/misc/sendmail.8.15.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tls.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 8.15.1_vs_8.15.2.

    1 /*
    2  * Copyright (c) 2000-2006, 2008, 2009, 2011, 2013 Proofpoint, Inc. and its suppliers.
    3  *  All rights reserved.
    4  *
    5  * By using this file, you agree to the terms and conditions set
    6  * forth in the LICENSE file which can be found at the top level of
    7  * the sendmail distribution.
    8  *
    9  */
   10 
   11 #include <sendmail.h>
   12 
   13 SM_RCSID("@(#)$Id: tls.c,v 8.127 2013-11-27 02:51:11 gshapiro Exp $")
   14 
   15 #if STARTTLS
   16 # include <openssl/err.h>
   17 # include <openssl/bio.h>
   18 # include <openssl/pem.h>
   19 # ifndef HASURANDOMDEV
   20 #  include <openssl/rand.h>
   21 # endif /* ! HASURANDOMDEV */
   22 # if !TLS_NO_RSA
   23 static RSA *rsa_tmp = NULL; /* temporary RSA key */
   24 static RSA *tmp_rsa_key __P((SSL *, int, int));
   25 # endif /* !TLS_NO_RSA */
   26 # if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
   27 static int  tls_verify_cb __P((X509_STORE_CTX *));
   28 # else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
   29 static int  tls_verify_cb __P((X509_STORE_CTX *, void *));
   30 # endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
   31 
   32 # if OPENSSL_VERSION_NUMBER > 0x00907000L
   33 static int x509_verify_cb __P((int, X509_STORE_CTX *));
   34 # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
   35 
   36 # if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
   37 #  define CONST097
   38 # else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
   39 #  define CONST097 const
   40 # endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
   41 static void apps_ssl_info_cb __P((CONST097 SSL *, int , int));
   42 static bool tls_ok_f __P((char *, char *, int));
   43 static bool tls_safe_f __P((char *, long, bool));
   44 static int  tls_verify_log __P((int, X509_STORE_CTX *, const char *));
   45 
   46 # if !NO_DH
   47 static DH *get_dh512 __P((void));
   48 
   49 static unsigned char dh512_p[] =
   50 {
   51     0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
   52     0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
   53     0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
   54     0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
   55     0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
   56     0x47,0x74,0xE8,0x33
   57 };
   58 static unsigned char dh512_g[] =
   59 {
   60     0x02
   61 };
   62 
   63 static DH *
   64 get_dh512()
   65 {
   66     DH *dh = NULL;
   67 
   68     if ((dh = DH_new()) == NULL)
   69         return NULL;
   70     dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
   71     dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
   72     if ((dh->p == NULL) || (dh->g == NULL))
   73         return NULL;
   74     return dh;
   75 }
   76 
   77 #  if 0
   78 
   79 This is the data from which the C code has been generated:
   80 
   81 -----BEGIN DH PARAMETERS-----
   82 MIIBCAKCAQEArDcgcLpxEksQHPlolRKCUJ2szKRziseWV9cUSQNZGxoGw7KkROz4
   83 HF9QSbg5axyNIG+QbZYtx0jp3l6/GWq1dLOj27yZkgYgaYgFrvKPiZ2jJ5xETQVH
   84 UpZwbjRcyjyWkWYJVsx1aF4F/iY4kT0n/+iGEoimI3C9V3KXTJ2S6jIkyJ6M/CrN
   85 EtrDynMlUMGlc7S1ouXVOTrtKeqy3S2L9eBLxVI+sChEijGIfELupdVeXihK006p
   86 MgnABPDbkTx6OOtYmSZaGQX+OLW2FPmwvcrzgCz9t9cAsuUcBZv1LeHEqZZttyLU
   87 oK0jjSXgFyeU4/NfyA+zuNeWzUL6bHmigwIBAg==
   88 -----END DH PARAMETERS-----
   89 #  endif /* 0 */
   90 
   91 static DH *
   92 get_dh2048()
   93 {
   94     static unsigned char dh2048_p[]={
   95         0xAC,0x37,0x20,0x70,0xBA,0x71,0x12,0x4B,0x10,0x1C,0xF9,0x68,
   96         0x95,0x12,0x82,0x50,0x9D,0xAC,0xCC,0xA4,0x73,0x8A,0xC7,0x96,
   97         0x57,0xD7,0x14,0x49,0x03,0x59,0x1B,0x1A,0x06,0xC3,0xB2,0xA4,
   98         0x44,0xEC,0xF8,0x1C,0x5F,0x50,0x49,0xB8,0x39,0x6B,0x1C,0x8D,
   99         0x20,0x6F,0x90,0x6D,0x96,0x2D,0xC7,0x48,0xE9,0xDE,0x5E,0xBF,
  100         0x19,0x6A,0xB5,0x74,0xB3,0xA3,0xDB,0xBC,0x99,0x92,0x06,0x20,
  101         0x69,0x88,0x05,0xAE,0xF2,0x8F,0x89,0x9D,0xA3,0x27,0x9C,0x44,
  102         0x4D,0x05,0x47,0x52,0x96,0x70,0x6E,0x34,0x5C,0xCA,0x3C,0x96,
  103         0x91,0x66,0x09,0x56,0xCC,0x75,0x68,0x5E,0x05,0xFE,0x26,0x38,
  104         0x91,0x3D,0x27,0xFF,0xE8,0x86,0x12,0x88,0xA6,0x23,0x70,0xBD,
  105         0x57,0x72,0x97,0x4C,0x9D,0x92,0xEA,0x32,0x24,0xC8,0x9E,0x8C,
  106         0xFC,0x2A,0xCD,0x12,0xDA,0xC3,0xCA,0x73,0x25,0x50,0xC1,0xA5,
  107         0x73,0xB4,0xB5,0xA2,0xE5,0xD5,0x39,0x3A,0xED,0x29,0xEA,0xB2,
  108         0xDD,0x2D,0x8B,0xF5,0xE0,0x4B,0xC5,0x52,0x3E,0xB0,0x28,0x44,
  109         0x8A,0x31,0x88,0x7C,0x42,0xEE,0xA5,0xD5,0x5E,0x5E,0x28,0x4A,
  110         0xD3,0x4E,0xA9,0x32,0x09,0xC0,0x04,0xF0,0xDB,0x91,0x3C,0x7A,
  111         0x38,0xEB,0x58,0x99,0x26,0x5A,0x19,0x05,0xFE,0x38,0xB5,0xB6,
  112         0x14,0xF9,0xB0,0xBD,0xCA,0xF3,0x80,0x2C,0xFD,0xB7,0xD7,0x00,
  113         0xB2,0xE5,0x1C,0x05,0x9B,0xF5,0x2D,0xE1,0xC4,0xA9,0x96,0x6D,
  114         0xB7,0x22,0xD4,0xA0,0xAD,0x23,0x8D,0x25,0xE0,0x17,0x27,0x94,
  115         0xE3,0xF3,0x5F,0xC8,0x0F,0xB3,0xB8,0xD7,0x96,0xCD,0x42,0xFA,
  116         0x6C,0x79,0xA2,0x83,
  117         };
  118     static unsigned char dh2048_g[]={ 0x02, };
  119     DH *dh;
  120 
  121     if ((dh=DH_new()) == NULL)
  122         return(NULL);
  123     dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
  124     dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
  125     if ((dh->p == NULL) || (dh->g == NULL))
  126     {
  127         DH_free(dh);
  128         return(NULL);
  129     }
  130     return(dh);
  131 }
  132 # endif /* !NO_DH */
  133 
  134 
  135 /*
  136 **  TLS_RAND_INIT -- initialize STARTTLS random generator
  137 **
  138 **  Parameters:
  139 **      randfile -- name of file with random data
  140 **      logl -- loglevel
  141 **
  142 **  Returns:
  143 **      success/failure
  144 **
  145 **  Side Effects:
  146 **      initializes PRNG for tls library.
  147 */
  148 
  149 # define MIN_RAND_BYTES 128 /* 1024 bits */
  150 
  151 # define RF_OK      0   /* randfile OK */
  152 # define RF_MISS    1   /* randfile == NULL || *randfile == '\0' */
  153 # define RF_UNKNOWN 2   /* unknown prefix for randfile */
  154 
  155 # define RI_NONE    0   /* no init yet */
  156 # define RI_SUCCESS 1   /* init was successful */
  157 # define RI_FAIL    2   /* init failed */
  158 
  159 static bool tls_rand_init __P((char *, int));
  160 
  161 static bool
  162 tls_rand_init(randfile, logl)
  163     char *randfile;
  164     int logl;
  165 {
  166 # ifndef HASURANDOMDEV
  167     /* not required if /dev/urandom exists, OpenSSL does it internally */
  168 
  169     bool ok;
  170     int randdef;
  171     static int done = RI_NONE;
  172 
  173     /*
  174     **  initialize PRNG
  175     */
  176 
  177     /* did we try this before? if yes: return old value */
  178     if (done != RI_NONE)
  179         return done == RI_SUCCESS;
  180 
  181     /* set default values */
  182     ok = false;
  183     done = RI_FAIL;
  184     randdef = (randfile == NULL || *randfile == '\0') ? RF_MISS : RF_OK;
  185 #   if EGD
  186     if (randdef == RF_OK && sm_strncasecmp(randfile, "egd:", 4) == 0)
  187     {
  188         randfile += 4;
  189         if (RAND_egd(randfile) < 0)
  190         {
  191             sm_syslog(LOG_WARNING, NOQID,
  192                   "STARTTLS: RAND_egd(%s) failed: random number generator not seeded",
  193                    randfile);
  194         }
  195         else
  196             ok = true;
  197     }
  198     else
  199 #   endif /* EGD */
  200     if (randdef == RF_OK && sm_strncasecmp(randfile, "file:", 5) == 0)
  201     {
  202         int fd;
  203         long sff;
  204         struct stat st;
  205 
  206         randfile += 5;
  207         sff = SFF_SAFEDIRPATH | SFF_NOWLINK
  208               | SFF_NOGWFILES | SFF_NOWWFILES
  209               | SFF_NOGRFILES | SFF_NOWRFILES
  210               | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
  211         if (DontLockReadFiles)
  212             sff |= SFF_NOLOCK;
  213         if ((fd = safeopen(randfile, O_RDONLY, 0, sff)) >= 0)
  214         {
  215             if (fstat(fd, &st) < 0)
  216             {
  217                 if (LogLevel > logl)
  218                     sm_syslog(LOG_ERR, NOQID,
  219                           "STARTTLS: can't fstat(%s)",
  220                           randfile);
  221             }
  222             else
  223             {
  224                 bool use, problem;
  225 
  226                 use = true;
  227                 problem = false;
  228 
  229                 /* max. age of file: 10 minutes */
  230                 if (st.st_mtime + 600 < curtime())
  231                 {
  232                     use = bitnset(DBS_INSUFFICIENTENTROPY,
  233                               DontBlameSendmail);
  234                     problem = true;
  235                     if (LogLevel > logl)
  236                         sm_syslog(LOG_ERR, NOQID,
  237                               "STARTTLS: RandFile %s too old: %s",
  238                               randfile,
  239                               use ? "unsafe" :
  240                                 "unusable");
  241                 }
  242                 if (use && st.st_size < MIN_RAND_BYTES)
  243                 {
  244                     use = bitnset(DBS_INSUFFICIENTENTROPY,
  245                               DontBlameSendmail);
  246                     problem = true;
  247                     if (LogLevel > logl)
  248                         sm_syslog(LOG_ERR, NOQID,
  249                               "STARTTLS: size(%s) < %d: %s",
  250                               randfile,
  251                               MIN_RAND_BYTES,
  252                               use ? "unsafe" :
  253                                 "unusable");
  254                 }
  255                 if (use)
  256                     ok = RAND_load_file(randfile, -1) >=
  257                          MIN_RAND_BYTES;
  258                 if (use && !ok)
  259                 {
  260                     if (LogLevel > logl)
  261                         sm_syslog(LOG_WARNING, NOQID,
  262                               "STARTTLS: RAND_load_file(%s) failed: random number generator not seeded",
  263                               randfile);
  264                 }
  265                 if (problem)
  266                     ok = false;
  267             }
  268             if (ok || bitnset(DBS_INSUFFICIENTENTROPY,
  269                       DontBlameSendmail))
  270             {
  271                 /* add this even if fstat() failed */
  272                 RAND_seed((void *) &st, sizeof(st));
  273             }
  274             (void) close(fd);
  275         }
  276         else
  277         {
  278             if (LogLevel > logl)
  279                 sm_syslog(LOG_WARNING, NOQID,
  280                       "STARTTLS: Warning: safeopen(%s) failed",
  281                       randfile);
  282         }
  283     }
  284     else if (randdef == RF_OK)
  285     {
  286         if (LogLevel > logl)
  287             sm_syslog(LOG_WARNING, NOQID,
  288                   "STARTTLS: Error: no proper random file definition %s",
  289                   randfile);
  290         randdef = RF_UNKNOWN;
  291     }
  292     if (randdef == RF_MISS)
  293     {
  294         if (LogLevel > logl)
  295             sm_syslog(LOG_WARNING, NOQID,
  296                   "STARTTLS: Error: missing random file definition");
  297     }
  298     if (!ok && bitnset(DBS_INSUFFICIENTENTROPY, DontBlameSendmail))
  299     {
  300         int i;
  301         long r;
  302         unsigned char buf[MIN_RAND_BYTES];
  303 
  304         /* assert((MIN_RAND_BYTES % sizeof(long)) == 0); */
  305         for (i = 0; i <= sizeof(buf) - sizeof(long); i += sizeof(long))
  306         {
  307             r = get_random();
  308             (void) memcpy(buf + i, (void *) &r, sizeof(long));
  309         }
  310         RAND_seed(buf, sizeof(buf));
  311         if (LogLevel > logl)
  312             sm_syslog(LOG_WARNING, NOQID,
  313                   "STARTTLS: Warning: random number generator not properly seeded");
  314         ok = true;
  315     }
  316     done = ok ? RI_SUCCESS : RI_FAIL;
  317     return ok;
  318 # else /* ! HASURANDOMDEV */
  319     return true;
  320 # endif /* ! HASURANDOMDEV */
  321 }
  322 /*
  323 **  INIT_TLS_LIBRARY -- Calls functions which setup TLS library for global use.
  324 **
  325 **  Parameters:
  326 **      fipsmode -- use FIPS?
  327 **
  328 **  Returns:
  329 **      succeeded?
  330 */
  331 
  332 bool
  333 init_tls_library(fipsmode)
  334     bool fipsmode;
  335 {
  336     bool bv;
  337 
  338     /* basic TLS initialization, ignore result for now */
  339     SSL_library_init();
  340     SSL_load_error_strings();
  341     OpenSSL_add_all_algorithms();
  342 # if 0
  343     /* this is currently a macro for SSL_library_init */
  344     SSLeay_add_ssl_algorithms();
  345 # endif /* 0 */
  346 
  347     bv = tls_rand_init(RandFile, 7);
  348 # if _FFR_FIPSMODE
  349     if (bv && fipsmode)
  350     {
  351         if (!FIPS_mode_set(1))
  352         {
  353             unsigned long err;
  354 
  355             err = ERR_get_error();
  356             if (LogLevel > 0)
  357                 sm_syslog(LOG_ERR, NOQID,
  358                     "STARTTLS=init, FIPSMode=%s",
  359                     ERR_error_string(err, NULL));
  360             return false;
  361         }
  362         else
  363         {
  364             if (LogLevel > 9)
  365                 sm_syslog(LOG_INFO, NOQID,
  366                     "STARTTLS=init, FIPSMode=ok");
  367         }
  368     }
  369 #endif /* _FFR_FIPSMODE  */
  370     if (bv && CertFingerprintAlgorithm != NULL)
  371     {
  372         const EVP_MD *md;
  373 
  374         md = EVP_get_digestbyname(CertFingerprintAlgorithm);
  375         if (NULL == md)
  376         {
  377             bv = false;
  378             if (LogLevel > 0)
  379                 sm_syslog(LOG_ERR, NOQID,
  380                     "STARTTLS=init, CertFingerprintAlgorithm=%s, status=invalid"
  381                     , CertFingerprintAlgorithm);
  382         }
  383         else
  384             EVP_digest = md;
  385     }
  386     return bv;
  387 }
  388 
  389 /*
  390 **  TLS_SET_VERIFY -- request client certificate?
  391 **
  392 **  Parameters:
  393 **      ctx -- TLS context
  394 **      ssl -- TLS structure
  395 **      vrfy -- request certificate?
  396 **
  397 **  Returns:
  398 **      none.
  399 **
  400 **  Side Effects:
  401 **      Sets verification state for TLS
  402 **
  403 # if TLS_VRFY_PER_CTX
  404 **  Notice:
  405 **      This is per TLS context, not per TLS structure;
  406 **      the former is global, the latter per connection.
  407 **      It would be nice to do this per connection, but this
  408 **      doesn't work in the current TLS libraries :-(
  409 # endif * TLS_VRFY_PER_CTX *
  410 */
  411 
  412 void
  413 tls_set_verify(ctx, ssl, vrfy)
  414     SSL_CTX *ctx;
  415     SSL *ssl;
  416     bool vrfy;
  417 {
  418 # if !TLS_VRFY_PER_CTX
  419     SSL_set_verify(ssl, vrfy ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
  420 # else /* !TLS_VRFY_PER_CTX */
  421     SSL_CTX_set_verify(ctx, vrfy ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,
  422             NULL);
  423 # endif /* !TLS_VRFY_PER_CTX */
  424 }
  425 
  426 /*
  427 **  status in initialization
  428 **  these flags keep track of the status of the initialization
  429 **  i.e., whether a file exists (_EX) and whether it can be used (_OK)
  430 **  [due to permissions]
  431 */
  432 
  433 # define TLS_S_NONE 0x00000000  /* none yet */
  434 # define TLS_S_CERT_EX  0x00000001  /* cert file exists */
  435 # define TLS_S_CERT_OK  0x00000002  /* cert file is ok */
  436 # define TLS_S_KEY_EX   0x00000004  /* key file exists */
  437 # define TLS_S_KEY_OK   0x00000008  /* key file is ok */
  438 # define TLS_S_CERTP_EX 0x00000010  /* CA cert path exists */
  439 # define TLS_S_CERTP_OK 0x00000020  /* CA cert path is ok */
  440 # define TLS_S_CERTF_EX 0x00000040  /* CA cert file exists */
  441 # define TLS_S_CERTF_OK 0x00000080  /* CA cert file is ok */
  442 # define TLS_S_CRLF_EX  0x00000100  /* CRL file exists */
  443 # define TLS_S_CRLF_OK  0x00000200  /* CRL file is ok */
  444 
  445 # define TLS_S_CERT2_EX 0x00001000  /* 2nd cert file exists */
  446 # define TLS_S_CERT2_OK 0x00002000  /* 2nd cert file is ok */
  447 # define TLS_S_KEY2_EX  0x00004000  /* 2nd key file exists */
  448 # define TLS_S_KEY2_OK  0x00008000  /* 2nd key file is ok */
  449 
  450 # define TLS_S_DH_OK    0x00200000  /* DH cert is ok */
  451 # define TLS_S_DHPAR_EX 0x00400000  /* DH param file exists */
  452 # define TLS_S_DHPAR_OK 0x00800000  /* DH param file is ok to use */
  453 
  454 /* Type of variable */
  455 # define TLS_T_OTHER    0
  456 # define TLS_T_SRV  1
  457 # define TLS_T_CLT  2
  458 
  459 /*
  460 **  TLS_OK_F -- can var be an absolute filename?
  461 **
  462 **  Parameters:
  463 **      var -- filename
  464 **      fn -- what is the filename used for?
  465 **      type -- type of variable
  466 **
  467 **  Returns:
  468 **      ok?
  469 */
  470 
  471 static bool
  472 tls_ok_f(var, fn, type)
  473     char *var;
  474     char *fn;
  475     int type;
  476 {
  477     /* must be absolute pathname */
  478     if (var != NULL && *var == '/')
  479         return true;
  480     if (LogLevel > 12)
  481         sm_syslog(LOG_WARNING, NOQID, "STARTTLS: %s%s missing",
  482               type == TLS_T_SRV ? "Server" :
  483               (type == TLS_T_CLT ? "Client" : ""), fn);
  484     return false;
  485 }
  486 /*
  487 **  TLS_SAFE_F -- is a file safe to use?
  488 **
  489 **  Parameters:
  490 **      var -- filename
  491 **      sff -- flags for safefile()
  492 **      srv -- server side?
  493 **
  494 **  Returns:
  495 **      ok?
  496 */
  497 
  498 static bool
  499 tls_safe_f(var, sff, srv)
  500     char *var;
  501     long sff;
  502     bool srv;
  503 {
  504     int ret;
  505 
  506     if ((ret = safefile(var, RunAsUid, RunAsGid, RunAsUserName, sff,
  507                 S_IRUSR, NULL)) == 0)
  508         return true;
  509     if (LogLevel > 7)
  510         sm_syslog(LOG_WARNING, NOQID, "STARTTLS=%s: file %s unsafe: %s",
  511               srv ? "server" : "client", var, sm_errstring(ret));
  512     return false;
  513 }
  514 
  515 /*
  516 **  TLS_OK_F -- macro to simplify calls to tls_ok_f
  517 **
  518 **  Parameters:
  519 **      var -- filename
  520 **      fn -- what is the filename used for?
  521 **      req -- is the file required?
  522 **      st -- status bit to set if ok
  523 **      type -- type of variable
  524 **
  525 **  Side Effects:
  526 **      uses r, ok; may change ok and status.
  527 **
  528 */
  529 
  530 # define TLS_OK_F(var, fn, req, st, type) if (ok) \
  531     { \
  532         r = tls_ok_f(var, fn, type); \
  533         if (r) \
  534             status |= st; \
  535         else if (req) \
  536             ok = false; \
  537     }
  538 
  539 /*
  540 **  TLS_UNR -- macro to return whether a file should be unreadable
  541 **
  542 **  Parameters:
  543 **      bit -- flag to test
  544 **      req -- flags
  545 **
  546 **  Returns:
  547 **      0/SFF_NORFILES
  548 */
  549 # define TLS_UNR(bit, req)  (bitset(bit, req) ? SFF_NORFILES : 0)
  550 # define TLS_OUNR(bit, req) (bitset(bit, req) ? SFF_NOWRFILES : 0)
  551 # define TLS_KEYSFF(req)    \
  552     (bitnset(DBS_GROUPREADABLEKEYFILE, DontBlameSendmail) ? \
  553         TLS_OUNR(TLS_I_KEY_OUNR, req) :         \
  554         TLS_UNR(TLS_I_KEY_UNR, req))
  555 
  556 /*
  557 **  TLS_SAFE_F -- macro to simplify calls to tls_safe_f
  558 **
  559 **  Parameters:
  560 **      var -- filename
  561 **      sff -- flags for safefile()
  562 **      req -- is the file required?
  563 **      ex -- does the file exist?
  564 **      st -- status bit to set if ok
  565 **      srv -- server side?
  566 **
  567 **  Side Effects:
  568 **      uses r, ok, ex; may change ok and status.
  569 **
  570 */
  571 
  572 # define TLS_SAFE_F(var, sff, req, ex, st, srv) if (ex && ok) \
  573     { \
  574         r = tls_safe_f(var, sff, srv); \
  575         if (r) \
  576             status |= st;   \
  577         else if (req) \
  578             ok = false; \
  579     }
  580 
  581 # if _FFR_TLS_SE_OPTS
  582 /*
  583 **  LOAD_CERTKEY -- load cert/key for TLS session
  584 **
  585 **  Parameters:
  586 **      ssl -- TLS session context
  587 **      certfile -- filename of certificate
  588 **      keyfile -- filename of private key
  589 **
  590 **  Returns:
  591 **      succeeded?
  592 */
  593 
  594 bool
  595 load_certkey(ssl, srv, certfile, keyfile)
  596     SSL *ssl;
  597     bool srv;
  598     char *certfile;
  599     char *keyfile;
  600 {
  601     bool ok;
  602     int r;
  603     long sff, status;
  604     unsigned long req;
  605     char *who;
  606 
  607     ok = true;
  608     who = srv ? "server" : "client";
  609     status = TLS_S_NONE;
  610     req = TLS_I_CERT_EX|TLS_I_KEY_EX;
  611     TLS_OK_F(certfile, "CertFile", bitset(TLS_I_CERT_EX, req),
  612          TLS_S_CERT_EX, srv ? TLS_T_SRV : TLS_T_CLT);
  613     TLS_OK_F(keyfile, "KeyFile", bitset(TLS_I_KEY_EX, req),
  614          TLS_S_KEY_EX, srv ? TLS_T_SRV : TLS_T_CLT);
  615 
  616     /* certfile etc. must be "safe". */
  617     sff = SFF_REGONLY | SFF_SAFEDIRPATH | SFF_NOWLINK
  618          | SFF_NOGWFILES | SFF_NOWWFILES
  619          | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
  620     if (DontLockReadFiles)
  621         sff |= SFF_NOLOCK;
  622 
  623     TLS_SAFE_F(certfile, sff | TLS_UNR(TLS_I_CERT_UNR, req),
  624            bitset(TLS_I_CERT_EX, req),
  625            bitset(TLS_S_CERT_EX, status), TLS_S_CERT_OK, srv);
  626     TLS_SAFE_F(keyfile, sff | TLS_KEYSFF(req),
  627            bitset(TLS_I_KEY_EX, req),
  628            bitset(TLS_S_KEY_EX, status), TLS_S_KEY_OK, srv);
  629 
  630 # define SSL_use_cert(ssl, certfile) \
  631     SSL_use_certificate_file(ssl, certfile, SSL_FILETYPE_PEM)
  632 # define SSL_USE_CERT "SSL_use_certificate_file"
  633 
  634     if (bitset(TLS_S_CERT_OK, status) &&
  635         SSL_use_cert(ssl, certfile) <= 0)
  636     {
  637         if (LogLevel > 7)
  638         {
  639             sm_syslog(LOG_WARNING, NOQID,
  640                   "STARTTLS=%s, error: %s(%s) failed",
  641                   who, SSL_USE_CERT, certfile);
  642             if (LogLevel > 9)
  643                 tlslogerr(LOG_WARNING, who);
  644         }
  645         if (bitset(TLS_I_USE_CERT, req))
  646             return false;
  647     }
  648     if (bitset(TLS_S_KEY_OK, status) &&
  649         SSL_use_PrivateKey_file(ssl, keyfile, SSL_FILETYPE_PEM) <= 0)
  650     {
  651         if (LogLevel > 7)
  652         {
  653             sm_syslog(LOG_WARNING, NOQID,
  654                   "STARTTLS=%s, error: SSL_use_PrivateKey_file(%s) failed",
  655                   who, keyfile);
  656             if (LogLevel > 9)
  657                 tlslogerr(LOG_WARNING, who);
  658         }
  659         if (bitset(TLS_I_USE_KEY, req))
  660             return false;
  661     }
  662 
  663     /* check the private key */
  664     if (bitset(TLS_S_KEY_OK, status) &&
  665         (r = SSL_check_private_key(ssl)) <= 0)
  666     {
  667         /* Private key does not match the certificate public key */
  668         if (LogLevel > 5)
  669         {
  670             sm_syslog(LOG_WARNING, NOQID,
  671                   "STARTTLS=%s, error: SSL_check_private_key failed(%s): %d",
  672                   who, keyfile, r);
  673             if (LogLevel > 9)
  674                 tlslogerr(LOG_WARNING, who);
  675         }
  676         if (bitset(TLS_I_USE_KEY, req))
  677             return false;
  678     }
  679 
  680     return true;
  681 }
  682 # endif /* _FFR_TLS_SE_OPTS */
  683 
  684 /*
  685 **  INITTLS -- initialize TLS
  686 **
  687 **  Parameters:
  688 **      ctx -- pointer to context
  689 **      req -- requirements for initialization (see sendmail.h)
  690 **      options -- options
  691 **      srv -- server side?
  692 **      certfile -- filename of certificate
  693 **      keyfile -- filename of private key
  694 **      cacertpath -- path to CAs
  695 **      cacertfile -- file with CA(s)
  696 **      dhparam -- parameters for DH
  697 **
  698 **  Returns:
  699 **      succeeded?
  700 */
  701 
  702 /*
  703 **  The session_id_context identifies the service that created a session.
  704 **  This information is used to distinguish between multiple TLS-based
  705 **  servers running on the same server. We use the name of the mail system.
  706 **  Note: the session cache is not persistent.
  707 */
  708 
  709 static char server_session_id_context[] = "sendmail8";
  710 
  711 /* 0.9.8a and b have a problem with SSL_OP_TLS_BLOCK_PADDING_BUG */
  712 #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
  713 # define SM_SSL_OP_TLS_BLOCK_PADDING_BUG    1
  714 #else
  715 # define SM_SSL_OP_TLS_BLOCK_PADDING_BUG    0
  716 #endif
  717 
  718 bool
  719 inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
  720     SSL_CTX **ctx;
  721     unsigned long req;
  722     unsigned long options;
  723     bool srv;
  724     char *certfile, *keyfile, *cacertpath, *cacertfile, *dhparam;
  725 {
  726 # if !NO_DH
  727     static DH *dh = NULL;
  728 # endif /* !NO_DH */
  729     int r;
  730     bool ok;
  731     long sff, status;
  732     char *who;
  733     char *cf2, *kf2;
  734 # if SM_CONF_SHM
  735     extern int ShmId;
  736 # endif /* SM_CONF_SHM */
  737 # if OPENSSL_VERSION_NUMBER > 0x00907000L
  738     BIO *crl_file;
  739     X509_CRL *crl;
  740     X509_STORE *store;
  741 # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
  742 #if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
  743     long rt_version;
  744     STACK_OF(SSL_COMP) *comp_methods;
  745 #endif
  746 
  747     status = TLS_S_NONE;
  748     who = srv ? "server" : "client";
  749     if (ctx == NULL)
  750     {
  751         syserr("STARTTLS=%s, inittls: ctx == NULL", who);
  752         /* NOTREACHED */
  753         SM_ASSERT(ctx != NULL);
  754     }
  755 
  756     /* already initialized? (we could re-init...) */
  757     if (*ctx != NULL)
  758         return true;
  759     ok = true;
  760 
  761     /*
  762     **  look for a second filename: it must be separated by a ','
  763     **  no blanks allowed (they won't be skipped).
  764     **  we change a global variable here! this change will be undone
  765     **  before return from the function but only if it returns true.
  766     **  this isn't a problem since in a failure case this function
  767     **  won't be called again with the same (overwritten) values.
  768     **  otherwise each return must be replaced with a goto endinittls.
  769     */
  770 
  771     cf2 = NULL;
  772     kf2 = NULL;
  773     if (certfile != NULL && (cf2 = strchr(certfile, ',')) != NULL)
  774     {
  775         *cf2++ = '\0';
  776         if (keyfile != NULL && (kf2 = strchr(keyfile, ',')) != NULL)
  777             *kf2++ = '\0';
  778     }
  779 
  780     /*
  781     **  Check whether files/paths are defined
  782     */
  783 
  784     TLS_OK_F(certfile, "CertFile", bitset(TLS_I_CERT_EX, req),
  785          TLS_S_CERT_EX, srv ? TLS_T_SRV : TLS_T_CLT);
  786     TLS_OK_F(keyfile, "KeyFile", bitset(TLS_I_KEY_EX, req),
  787          TLS_S_KEY_EX, srv ? TLS_T_SRV : TLS_T_CLT);
  788     TLS_OK_F(cacertpath, "CACertPath", bitset(TLS_I_CERTP_EX, req),
  789          TLS_S_CERTP_EX, TLS_T_OTHER);
  790     TLS_OK_F(cacertfile, "CACertFile", bitset(TLS_I_CERTF_EX, req),
  791          TLS_S_CERTF_EX, TLS_T_OTHER);
  792 
  793 # if OPENSSL_VERSION_NUMBER > 0x00907000L
  794     TLS_OK_F(CRLFile, "CRLFile", bitset(TLS_I_CRLF_EX, req),
  795          TLS_S_CRLF_EX, TLS_T_OTHER);
  796 # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
  797 
  798     /*
  799     **  if the second file is specified it must exist
  800     **  XXX: it is possible here to define only one of those files
  801     */
  802 
  803     if (cf2 != NULL)
  804     {
  805         TLS_OK_F(cf2, "CertFile", bitset(TLS_I_CERT_EX, req),
  806              TLS_S_CERT2_EX, srv ? TLS_T_SRV : TLS_T_CLT);
  807     }
  808     if (kf2 != NULL)
  809     {
  810         TLS_OK_F(kf2, "KeyFile", bitset(TLS_I_KEY_EX, req),
  811              TLS_S_KEY2_EX, srv ? TLS_T_SRV : TLS_T_CLT);
  812     }
  813 
  814     /*
  815     **  valid values for dhparam are (only the first char is checked)
  816     **  none    no parameters: don't use DH
  817     **  i       use precomputed 2048 bit parameters
  818     **  512     use precomputed 512 bit parameters
  819     **  1024    generate 1024 bit parameters
  820     **  2048    generate 2048 bit parameters
  821     **  /file/name  read parameters from /file/name
  822     */
  823 
  824 #define SET_DH_DFL  \
  825     do {    \
  826         dhparam = "I";  \
  827         req |= TLS_I_DHFIXED;   \
  828     } while (0)
  829 
  830     if (bitset(TLS_I_TRY_DH, req))
  831     {
  832         if (dhparam != NULL)
  833         {
  834             char c = *dhparam;
  835 
  836             if (c == '1')
  837                 req |= TLS_I_DH1024;
  838             else if (c == 'I' || c == 'i')
  839                 req |= TLS_I_DHFIXED;
  840             else if (c == '2')
  841                 req |= TLS_I_DH2048;
  842             else if (c == '5')
  843                 req |= TLS_I_DH512;
  844             else if (c == 'n' || c == 'N')
  845                 req &= ~TLS_I_TRY_DH;
  846             else if (c != '/')
  847             {
  848                 if (LogLevel > 12)
  849                     sm_syslog(LOG_WARNING, NOQID,
  850                           "STARTTLS=%s, error: illegal value '%s' for DHParameters",
  851                           who, dhparam);
  852                 dhparam = NULL;
  853             }
  854         }
  855         if (dhparam == NULL)
  856             SET_DH_DFL;
  857         else if (*dhparam == '/')
  858         {
  859             TLS_OK_F(dhparam, "DHParameters",
  860                  bitset(TLS_I_DHPAR_EX, req),
  861                  TLS_S_DHPAR_EX, TLS_T_OTHER);
  862         }
  863     }
  864     if (!ok)
  865         return ok;
  866 
  867     /* certfile etc. must be "safe". */
  868     sff = SFF_REGONLY | SFF_SAFEDIRPATH | SFF_NOWLINK
  869          | SFF_NOGWFILES | SFF_NOWWFILES
  870          | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
  871     if (DontLockReadFiles)
  872         sff |= SFF_NOLOCK;
  873 
  874     TLS_SAFE_F(certfile, sff | TLS_UNR(TLS_I_CERT_UNR, req),
  875            bitset(TLS_I_CERT_EX, req),
  876            bitset(TLS_S_CERT_EX, status), TLS_S_CERT_OK, srv);
  877     TLS_SAFE_F(keyfile, sff | TLS_KEYSFF(req),
  878            bitset(TLS_I_KEY_EX, req),
  879            bitset(TLS_S_KEY_EX, status), TLS_S_KEY_OK, srv);
  880     TLS_SAFE_F(cacertfile, sff | TLS_UNR(TLS_I_CERTF_UNR, req),
  881            bitset(TLS_I_CERTF_EX, req),
  882            bitset(TLS_S_CERTF_EX, status), TLS_S_CERTF_OK, srv);
  883     if (dhparam != NULL && *dhparam == '/')
  884     {
  885         TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req),
  886                bitset(TLS_I_DHPAR_EX, req),
  887                bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK, srv);
  888         if (!bitset(TLS_S_DHPAR_OK, status))
  889             SET_DH_DFL;
  890     }
  891 # if OPENSSL_VERSION_NUMBER > 0x00907000L
  892     TLS_SAFE_F(CRLFile, sff | TLS_UNR(TLS_I_CRLF_UNR, req),
  893            bitset(TLS_I_CRLF_EX, req),
  894            bitset(TLS_S_CRLF_EX, status), TLS_S_CRLF_OK, srv);
  895 # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
  896     if (!ok)
  897         return ok;
  898     if (cf2 != NULL)
  899     {
  900         TLS_SAFE_F(cf2, sff | TLS_UNR(TLS_I_CERT_UNR, req),
  901                bitset(TLS_I_CERT_EX, req),
  902                bitset(TLS_S_CERT2_EX, status), TLS_S_CERT2_OK, srv);
  903     }
  904     if (kf2 != NULL)
  905     {
  906         TLS_SAFE_F(kf2, sff | TLS_KEYSFF(req),
  907                bitset(TLS_I_KEY_EX, req),
  908                bitset(TLS_S_KEY2_EX, status), TLS_S_KEY2_OK, srv);
  909     }
  910 
  911     /* create a method and a new context */
  912     if ((*ctx = SSL_CTX_new(srv ? SSLv23_server_method() :
  913                       SSLv23_client_method())) == NULL)
  914     {
  915         if (LogLevel > 7)
  916             sm_syslog(LOG_WARNING, NOQID,
  917                   "STARTTLS=%s, error: SSL_CTX_new(SSLv23_%s_method()) failed",
  918                   who, who);
  919         if (LogLevel > 9)
  920             tlslogerr(LOG_WARNING, who);
  921         return false;
  922     }
  923 
  924 # if OPENSSL_VERSION_NUMBER > 0x00907000L
  925     if (CRLFile != NULL)
  926     {
  927         /* get a pointer to the current certificate validation store */
  928         store = SSL_CTX_get_cert_store(*ctx);   /* does not fail */
  929         crl_file = BIO_new(BIO_s_file_internal());
  930         if (crl_file != NULL)
  931         {
  932             if (BIO_read_filename(crl_file, CRLFile) >= 0)
  933             {
  934                 crl = PEM_read_bio_X509_CRL(crl_file, NULL,
  935                             NULL, NULL);
  936                 BIO_free(crl_file);
  937                 X509_STORE_add_crl(store, crl);
  938                 X509_CRL_free(crl);
  939                 X509_STORE_set_flags(store,
  940                     X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
  941                 X509_STORE_set_verify_cb_func(store,
  942                         x509_verify_cb);
  943             }
  944             else
  945             {
  946                 if (LogLevel > 9)
  947                 {
  948                     sm_syslog(LOG_WARNING, NOQID,
  949                           "STARTTLS=%s, error: PEM_read_bio_X509_CRL(%s)=failed",
  950                           who, CRLFile);
  951                 }
  952 
  953                 /* avoid memory leaks */
  954                 BIO_free(crl_file);
  955                 return false;
  956             }
  957 
  958         }
  959         else if (LogLevel > 9)
  960             sm_syslog(LOG_WARNING, NOQID,
  961                   "STARTTLS=%s, error: BIO_new=failed", who);
  962     }
  963     else
  964         store = NULL;
  965 #  if _FFR_CRLPATH
  966     if (CRLPath != NULL && store != NULL)
  967     {
  968         X509_LOOKUP *lookup;
  969 
  970         lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
  971         if (lookup == NULL)
  972         {
  973             if (LogLevel > 9)
  974             {
  975                 sm_syslog(LOG_WARNING, NOQID,
  976                       "STARTTLS=%s, error: X509_STORE_add_lookup(hash)=failed",
  977                       who, CRLFile);
  978             }
  979             return false;
  980         }
  981         X509_LOOKUP_add_dir(lookup, CRLPath, X509_FILETYPE_PEM);
  982         X509_STORE_set_flags(store,
  983             X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
  984     }
  985 #  endif /* _FFR_CRLPATH */
  986 # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
  987 
  988 # if TLS_NO_RSA
  989     /* turn off backward compatibility, required for no-rsa */
  990     SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2);
  991 # endif /* TLS_NO_RSA */
  992 
  993 
  994 # if !TLS_NO_RSA
  995     /*
  996     **  Create a temporary RSA key
  997     **  XXX  Maybe we shouldn't create this always (even though it
  998     **  is only at startup).
  999     **  It is a time-consuming operation and it is not always necessary.
 1000     **  maybe we should do it only on demand...
 1001     */
 1002 
 1003     if (bitset(TLS_I_RSA_TMP, req)
 1004 #  if SM_CONF_SHM
 1005         && ShmId != SM_SHM_NO_ID &&
 1006         (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
 1007                     NULL)) == NULL
 1008 #  else /* SM_CONF_SHM */
 1009         && 0    /* no shared memory: no need to generate key now */
 1010 #  endif /* SM_CONF_SHM */
 1011        )
 1012     {
 1013         if (LogLevel > 7)
 1014         {
 1015             sm_syslog(LOG_WARNING, NOQID,
 1016                   "STARTTLS=%s, error: RSA_generate_key failed",
 1017                   who);
 1018             if (LogLevel > 9)
 1019                 tlslogerr(LOG_WARNING, who);
 1020         }
 1021         return false;
 1022     }
 1023 # endif /* !TLS_NO_RSA */
 1024 
 1025     /*
 1026     **  load private key
 1027     **  XXX change this for DSA-only version
 1028     */
 1029 
 1030     if (bitset(TLS_S_KEY_OK, status) &&
 1031         SSL_CTX_use_PrivateKey_file(*ctx, keyfile,
 1032                      SSL_FILETYPE_PEM) <= 0)
 1033     {
 1034         if (LogLevel > 7)
 1035         {
 1036             sm_syslog(LOG_WARNING, NOQID,
 1037                   "STARTTLS=%s, error: SSL_CTX_use_PrivateKey_file(%s) failed",
 1038                   who, keyfile);
 1039             if (LogLevel > 9)
 1040                 tlslogerr(LOG_WARNING, who);
 1041         }
 1042         if (bitset(TLS_I_USE_KEY, req))
 1043             return false;
 1044     }
 1045 
 1046 #if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
 1047 # define SSL_CTX_use_cert(ssl_ctx, certfile) \
 1048     SSL_CTX_use_certificate_chain_file(ssl_ctx, certfile)
 1049 # define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_chain_file"
 1050 #else
 1051 # define SSL_CTX_use_cert(ssl_ctx, certfile) \
 1052     SSL_CTX_use_certificate_file(ssl_ctx, certfile, SSL_FILETYPE_PEM)
 1053 # define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_file"
 1054 #endif
 1055 
 1056     /* get the certificate file */
 1057     if (bitset(TLS_S_CERT_OK, status) &&
 1058         SSL_CTX_use_cert(*ctx, certfile) <= 0)
 1059     {
 1060         if (LogLevel > 7)
 1061         {
 1062             sm_syslog(LOG_WARNING, NOQID,
 1063                   "STARTTLS=%s, error: %s(%s) failed",
 1064                   who, SSL_CTX_USE_CERT, certfile);
 1065             if (LogLevel > 9)
 1066                 tlslogerr(LOG_WARNING, who);
 1067         }
 1068         if (bitset(TLS_I_USE_CERT, req))
 1069             return false;
 1070     }
 1071 
 1072     /* check the private key */
 1073     if (bitset(TLS_S_KEY_OK, status) &&
 1074         (r = SSL_CTX_check_private_key(*ctx)) <= 0)
 1075     {
 1076         /* Private key does not match the certificate public key */
 1077         if (LogLevel > 5)
 1078         {
 1079             sm_syslog(LOG_WARNING, NOQID,
 1080                   "STARTTLS=%s, error: SSL_CTX_check_private_key failed(%s): %d",
 1081                   who, keyfile, r);
 1082             if (LogLevel > 9)
 1083                 tlslogerr(LOG_WARNING, who);
 1084         }
 1085         if (bitset(TLS_I_USE_KEY, req))
 1086             return false;
 1087     }
 1088 
 1089     /* XXX this code is pretty much duplicated from above! */
 1090 
 1091     /* load private key */
 1092     if (bitset(TLS_S_KEY2_OK, status) &&
 1093         SSL_CTX_use_PrivateKey_file(*ctx, kf2, SSL_FILETYPE_PEM) <= 0)
 1094     {
 1095         if (LogLevel > 7)
 1096         {
 1097             sm_syslog(LOG_WARNING, NOQID,
 1098                   "STARTTLS=%s, error: SSL_CTX_use_PrivateKey_file(%s) failed",
 1099                   who, kf2);
 1100             if (LogLevel > 9)
 1101                 tlslogerr(LOG_WARNING, who);
 1102         }
 1103     }
 1104 
 1105     /* get the certificate file */
 1106     if (bitset(TLS_S_CERT2_OK, status) &&
 1107         SSL_CTX_use_cert(*ctx, cf2) <= 0)
 1108     {
 1109         if (LogLevel > 7)
 1110         {
 1111             sm_syslog(LOG_WARNING, NOQID,
 1112                   "STARTTLS=%s, error: %s(%s) failed",
 1113                   who, SSL_CTX_USE_CERT, cf2);
 1114             if (LogLevel > 9)
 1115                 tlslogerr(LOG_WARNING, who);
 1116         }
 1117     }
 1118 
 1119     /* also check the private key */
 1120     if (bitset(TLS_S_KEY2_OK, status) &&
 1121         (r = SSL_CTX_check_private_key(*ctx)) <= 0)
 1122     {
 1123         /* Private key does not match the certificate public key */
 1124         if (LogLevel > 5)
 1125         {
 1126             sm_syslog(LOG_WARNING, NOQID,
 1127                   "STARTTLS=%s, error: SSL_CTX_check_private_key 2 failed: %d",
 1128                   who, r);
 1129             if (LogLevel > 9)
 1130                 tlslogerr(LOG_WARNING, who);
 1131         }
 1132     }
 1133 
 1134     /* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */
 1135 
 1136 #if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
 1137 
 1138     /*
 1139     **  In OpenSSL 0.9.8[ab], enabling zlib compression breaks the
 1140     **  padding bug work-around, leading to false positives and
 1141     **  failed connections. We may not interoperate with systems
 1142     **  with the bug, but this is better than breaking on all 0.9.8[ab]
 1143     **  systems that have zlib support enabled.
 1144     **  Note: this checks the runtime version of the library, not
 1145     **  just the compile time version.
 1146     */
 1147 
 1148     rt_version = SSLeay();
 1149     if (rt_version >= 0x00908000L && rt_version <= 0x0090802fL)
 1150     {
 1151         comp_methods = SSL_COMP_get_compression_methods();
 1152         if (comp_methods != NULL && sk_SSL_COMP_num(comp_methods) > 0)
 1153             options &= ~SSL_OP_TLS_BLOCK_PADDING_BUG;
 1154     }
 1155 #endif
 1156     SSL_CTX_set_options(*ctx, (long) options);
 1157 
 1158 # if !NO_DH
 1159     /* Diffie-Hellman initialization */
 1160     if (bitset(TLS_I_TRY_DH, req))
 1161     {
 1162 #if _FFR_TLS_EC
 1163         EC_KEY *ecdh;
 1164 #endif /* _FFR_TLS_EC */
 1165 
 1166         if (tTd(96, 8))
 1167             sm_dprintf("inittls: req=%#lx, status=%#lx\n",
 1168                 req, status);
 1169         if (bitset(TLS_S_DHPAR_OK, status))
 1170         {
 1171             BIO *bio;
 1172 
 1173             if ((bio = BIO_new_file(dhparam, "r")) != NULL)
 1174             {
 1175                 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
 1176                 BIO_free(bio);
 1177                 if (dh == NULL && LogLevel > 7)
 1178                 {
 1179                     unsigned long err;
 1180 
 1181                     err = ERR_get_error();
 1182                     sm_syslog(LOG_WARNING, NOQID,
 1183                           "STARTTLS=%s, error: cannot read DH parameters(%s): %s",
 1184                           who, dhparam,
 1185                           ERR_error_string(err, NULL));
 1186                     if (LogLevel > 9)
 1187                         tlslogerr(LOG_WARNING, who);
 1188                     SET_DH_DFL;
 1189                 }
 1190             }
 1191             else
 1192             {
 1193                 if (LogLevel > 5)
 1194                 {
 1195                     sm_syslog(LOG_WARNING, NOQID,
 1196                           "STARTTLS=%s, error: BIO_new_file(%s) failed",
 1197                           who, dhparam);
 1198                     if (LogLevel > 9)
 1199                         tlslogerr(LOG_WARNING, who);
 1200                 }
 1201             }
 1202         }
 1203         if (dh == NULL && bitset(TLS_I_DH1024|TLS_I_DH2048, req))
 1204         {
 1205             int bits;
 1206             DSA *dsa;
 1207 
 1208             bits = bitset(TLS_I_DH2048, req) ? 2048 : 1024;
 1209             if (tTd(96, 2))
 1210                 sm_dprintf("inittls: Generating %d bit DH parameters\n", bits);
 1211 
 1212             /* this takes a while! */
 1213             dsa = DSA_generate_parameters(bits, NULL, 0, NULL,
 1214                               NULL, 0, NULL);
 1215             dh = DSA_dup_DH(dsa);
 1216             DSA_free(dsa);
 1217         }
 1218         else if (dh == NULL && bitset(TLS_I_DHFIXED, req))
 1219         {
 1220             if (tTd(96, 2))
 1221                 sm_dprintf("inittls: Using precomputed 2048 bit DH parameters\n");
 1222             dh = get_dh2048();
 1223         }
 1224         else if (dh == NULL && bitset(TLS_I_DH512, req))
 1225         {
 1226             if (tTd(96, 2))
 1227                 sm_dprintf("inittls: Using precomputed 512 bit DH parameters\n");
 1228             dh = get_dh512();
 1229         }
 1230 
 1231         if (dh == NULL)
 1232         {
 1233             if (LogLevel > 9)
 1234             {
 1235                 unsigned long err;
 1236 
 1237                 err = ERR_get_error();
 1238                 sm_syslog(LOG_WARNING, NOQID,
 1239                       "STARTTLS=%s, error: cannot read or set DH parameters(%s): %s",
 1240                       who, dhparam,
 1241                       ERR_error_string(err, NULL));
 1242             }
 1243             if (bitset(TLS_I_REQ_DH, req))
 1244                 return false;
 1245         }
 1246         else
 1247         {
 1248             /* important to avoid small subgroup attacks */
 1249             SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_DH_USE);
 1250 
 1251             SSL_CTX_set_tmp_dh(*ctx, dh);
 1252             if (LogLevel > 13)
 1253                 sm_syslog(LOG_INFO, NOQID,
 1254                       "STARTTLS=%s, Diffie-Hellman init, key=%d bit (%c)",
 1255                       who, 8 * DH_size(dh), *dhparam);
 1256             DH_free(dh);
 1257         }
 1258 
 1259 #if _FFR_TLS_EC
 1260         ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
 1261         if (ecdh != NULL)
 1262         {
 1263             SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_ECDH_USE);
 1264             SSL_CTX_set_tmp_ecdh(*ctx, ecdh);
 1265             EC_KEY_free(ecdh);
 1266         }
 1267 #endif /* _FFR_TLS_EC */
 1268 
 1269     }
 1270 # endif /* !NO_DH */
 1271 
 1272 
 1273     /* XXX do we need this cache here? */
 1274     if (bitset(TLS_I_CACHE, req))
 1275     {
 1276         SSL_CTX_sess_set_cache_size(*ctx, 1);
 1277         SSL_CTX_set_timeout(*ctx, 1);
 1278         SSL_CTX_set_session_id_context(*ctx,
 1279             (void *) &server_session_id_context,
 1280             sizeof(server_session_id_context));
 1281         (void) SSL_CTX_set_session_cache_mode(*ctx,
 1282                 SSL_SESS_CACHE_SERVER);
 1283     }
 1284     else
 1285     {
 1286         (void) SSL_CTX_set_session_cache_mode(*ctx,
 1287                 SSL_SESS_CACHE_OFF);
 1288     }
 1289 
 1290     /* load certificate locations and default CA paths */
 1291     if (bitset(TLS_S_CERTP_EX, status) && bitset(TLS_S_CERTF_EX, status))
 1292     {
 1293         if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile,
 1294                                cacertpath)) == 1)
 1295         {
 1296 # if !TLS_NO_RSA
 1297             if (bitset(TLS_I_RSA_TMP, req))
 1298                 SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key);
 1299 # endif /* !TLS_NO_RSA */
 1300 
 1301             /*
 1302             **  We have to install our own verify callback:
 1303             **  SSL_VERIFY_PEER requests a client cert but even
 1304             **  though *FAIL_IF* isn't set, the connection
 1305             **  will be aborted if the client presents a cert
 1306             **  that is not "liked" (can't be verified?) by
 1307             **  the TLS library :-(
 1308             */
 1309 
 1310             /*
 1311             **  XXX currently we could call tls_set_verify()
 1312             **  but we hope that that function will later on
 1313             **  only set the mode per connection.
 1314             */
 1315             SSL_CTX_set_verify(*ctx,
 1316                 bitset(TLS_I_NO_VRFY, req) ? SSL_VERIFY_NONE
 1317                                : SSL_VERIFY_PEER,
 1318                 NULL);
 1319 
 1320             /* install verify callback */
 1321             SSL_CTX_set_cert_verify_callback(*ctx, tls_verify_cb,
 1322                              NULL);
 1323             SSL_CTX_set_client_CA_list(*ctx,
 1324                 SSL_load_client_CA_file(cacertfile));
 1325         }
 1326         else
 1327         {
 1328             /*
 1329             **  can't load CA data; do we care?
 1330             **  the data is necessary to authenticate the client,
 1331             **  which in turn would be necessary
 1332             **  if we want to allow relaying based on it.
 1333             */
 1334             if (LogLevel > 5)
 1335             {
 1336                 sm_syslog(LOG_WARNING, NOQID,
 1337                       "STARTTLS=%s, error: load verify locs %s, %s failed: %d",
 1338                       who, cacertpath, cacertfile, r);
 1339                 if (LogLevel > 9)
 1340                     tlslogerr(LOG_WARNING, who);
 1341             }
 1342             if (bitset(TLS_I_VRFY_LOC, req))
 1343                 return false;
 1344         }
 1345     }
 1346 
 1347     /* XXX: make this dependent on an option? */
 1348     if (tTd(96, 9))
 1349         SSL_CTX_set_info_callback(*ctx, apps_ssl_info_cb);
 1350 
 1351     /* install our own cipher list */
 1352     if (CipherList != NULL && *CipherList != '\0')
 1353     {
 1354         if (SSL_CTX_set_cipher_list(*ctx, CipherList) <= 0)
 1355         {
 1356             if (LogLevel > 7)
 1357             {
 1358                 sm_syslog(LOG_WARNING, NOQID,
 1359                       "STARTTLS=%s, error: SSL_CTX_set_cipher_list(%s) failed, list ignored",
 1360                       who, CipherList);
 1361 
 1362                 if (LogLevel > 9)
 1363                     tlslogerr(LOG_WARNING, who);
 1364             }
 1365             /* failure if setting to this list is required? */
 1366         }
 1367     }
 1368 
 1369     if (LogLevel > 12)
 1370         sm_syslog(LOG_INFO, NOQID, "STARTTLS=%s, init=%d", who, ok);
 1371 
 1372 # if 0
 1373     /*
 1374     **  this label is required if we want to have a "clean" exit
 1375     **  see the comments above at the initialization of cf2
 1376     */
 1377 
 1378     endinittls:
 1379 # endif /* 0 */
 1380 
 1381     /* undo damage to global variables */
 1382     if (cf2 != NULL)
 1383         *--cf2 = ',';
 1384     if (kf2 != NULL)
 1385         *--kf2 = ',';
 1386 
 1387     return ok;
 1388 }
 1389 
 1390 /*
 1391 **  CERT_FP -- get cert fingerprint
 1392 **
 1393 **  Parameters:
 1394 **      cert -- TLS cert
 1395 **      mac -- macro storage
 1396 **      macro -- where to store cert fp
 1397 **
 1398 **  Returns:
 1399 **      <=0: cert fp calculation failed
 1400 **      >0: cert fp calculation ok
 1401 */
 1402 
 1403 static int
 1404 cert_fp(cert, evp_digest, mac, macro)
 1405     X509 *cert;
 1406     const EVP_MD *evp_digest;
 1407     MACROS_T *mac;
 1408     char *macro;
 1409 {
 1410     unsigned int n;
 1411     int r;
 1412     unsigned char md[EVP_MAX_MD_SIZE];
 1413     char md5h[EVP_MAX_MD_SIZE * 3];
 1414     static const char hexcodes[] = "0123456789ABCDEF";
 1415 
 1416     n = 0;
 1417     if (X509_digest(cert, EVP_digest, md, &n) == 0 || n <= 0)
 1418     {
 1419         macdefine(mac, A_TEMP, macid(macro), "");
 1420         return 0;
 1421     }
 1422 
 1423     SM_ASSERT((n * 3) + 2 < sizeof(md5h));
 1424     for (r = 0; r < (int) n; r++)
 1425     {
 1426         md5h[r * 3] = hexcodes[(md[r] & 0xf0) >> 4];
 1427         md5h[(r * 3) + 1] = hexcodes[(md[r] & 0x0f)];
 1428         md5h[(r * 3) + 2] = ':';
 1429     }
 1430     md5h[(n * 3) - 1] = '\0';
 1431     macdefine(mac, A_TEMP, macid(macro), md5h);
 1432     return 1;
 1433 }
 1434 
 1435 /*
 1436 **  TLS_GET_INFO -- get information about TLS connection
 1437 **
 1438 **  Parameters:
 1439 **      ssl -- TLS connection structure
 1440 **      srv -- server or client
 1441 **      host -- hostname of other side
 1442 **      mac -- macro storage
 1443 **      certreq -- did we ask for a cert?
 1444 **
 1445 **  Returns:
 1446 **      result of authentication.
 1447 **
 1448 **  Side Effects:
 1449 **      sets various TLS related macros.
 1450 */
 1451 
 1452 int
 1453 tls_get_info(ssl, srv, host, mac, certreq)
 1454     SSL *ssl;
 1455     bool srv;
 1456     char *host;
 1457     MACROS_T *mac;
 1458     bool certreq;
 1459 {
 1460     const SSL_CIPHER *c;
 1461     int b, r;
 1462     long verifyok;
 1463     char *s, *who;
 1464     char bitstr[16];
 1465     X509 *cert;
 1466 
 1467     c = SSL_get_current_cipher(ssl);
 1468 
 1469     /* cast is just workaround for compiler warning */
 1470     macdefine(mac, A_TEMP, macid("{cipher}"),
 1471           (char *) SSL_CIPHER_get_name(c));
 1472     b = SSL_CIPHER_get_bits(c, &r);
 1473     (void) sm_snprintf(bitstr, sizeof(bitstr), "%d", b);
 1474     macdefine(mac, A_TEMP, macid("{cipher_bits}"), bitstr);
 1475     (void) sm_snprintf(bitstr, sizeof(bitstr), "%d", r);
 1476     macdefine(mac, A_TEMP, macid("{alg_bits}"), bitstr);
 1477     s = (char *) SSL_get_version(ssl);
 1478     if (s == NULL)
 1479         s = "UNKNOWN";
 1480     macdefine(mac, A_TEMP, macid("{tls_version}"), s);
 1481 
 1482     who = srv ? "server" : "client";
 1483     cert = SSL_get_peer_certificate(ssl);
 1484     verifyok = SSL_get_verify_result(ssl);
 1485     if (LogLevel > 14)
 1486         sm_syslog(LOG_INFO, NOQID,
 1487               "STARTTLS=%s, get_verify: %ld get_peer: 0x%lx",
 1488               who, verifyok, (unsigned long) cert);
 1489     if (cert != NULL)
 1490     {
 1491         X509_NAME *subj, *issuer;
 1492         char buf[MAXNAME];
 1493 
 1494         subj = X509_get_subject_name(cert);
 1495         issuer = X509_get_issuer_name(cert);
 1496         X509_NAME_oneline(subj, buf, sizeof(buf));
 1497         macdefine(mac, A_TEMP, macid("{cert_subject}"),
 1498              xtextify(buf, "<>\")"));
 1499         X509_NAME_oneline(issuer, buf, sizeof(buf));
 1500         macdefine(mac, A_TEMP, macid("{cert_issuer}"),
 1501              xtextify(buf, "<>\")"));
 1502 
 1503 # define LL_BADCERT 8
 1504 
 1505 #define CERTFPMACRO (CertFingerprintAlgorithm != NULL ? "{cert_fp}" : "{cert_md5}")
 1506 
 1507 #define CHECK_X509_NAME(which)  \
 1508     do {    \
 1509         if (r == -1)    \
 1510         {       \
 1511             sm_strlcpy(buf, "BadCertificateUnknown", sizeof(buf)); \
 1512             if (LogLevel > LL_BADCERT)  \
 1513                 sm_syslog(LOG_INFO, NOQID,  \
 1514                     "STARTTLS=%s, relay=%.100s, field=%s, status=failed to extract CN", \
 1515                     who,    \
 1516                     host == NULL ? "local" : host,  \
 1517                     which); \
 1518         }       \
 1519         else if ((size_t)r >= sizeof(buf) - 1)  \
 1520         {       \
 1521             sm_strlcpy(buf, "BadCertificateTooLong", sizeof(buf)); \
 1522             if (LogLevel > 7)   \
 1523                 sm_syslog(LOG_INFO, NOQID,  \
 1524                     "STARTTLS=%s, relay=%.100s, field=%s, status=CN too long",  \
 1525                     who,    \
 1526                     host == NULL ? "local" : host,  \
 1527                     which); \
 1528         }       \
 1529         else if ((size_t)r > strlen(buf))   \
 1530         {       \
 1531             sm_strlcpy(buf, "BadCertificateContainsNUL",    \
 1532                 sizeof(buf));   \
 1533             if (LogLevel > 7)   \
 1534                 sm_syslog(LOG_INFO, NOQID,  \
 1535                     "STARTTLS=%s, relay=%.100s, field=%s, status=CN contains NUL",  \
 1536                     who,    \
 1537                     host == NULL ? "local" : host,  \
 1538                     which); \
 1539         }       \
 1540     } while (0)
 1541 
 1542         r = X509_NAME_get_text_by_NID(subj, NID_commonName, buf,
 1543             sizeof buf);
 1544         CHECK_X509_NAME("cn_subject");
 1545         macdefine(mac, A_TEMP, macid("{cn_subject}"),
 1546              xtextify(buf, "<>\")"));
 1547         r = X509_NAME_get_text_by_NID(issuer, NID_commonName, buf,
 1548             sizeof buf);
 1549         CHECK_X509_NAME("cn_issuer");
 1550         macdefine(mac, A_TEMP, macid("{cn_issuer}"),
 1551              xtextify(buf, "<>\")"));
 1552         (void) cert_fp(cert, EVP_digest, mac, CERTFPMACRO);
 1553     }
 1554     else
 1555     {
 1556         macdefine(mac, A_PERM, macid("{cert_subject}"), "");
 1557         macdefine(mac, A_PERM, macid("{cert_issuer}"), "");
 1558         macdefine(mac, A_PERM, macid("{cn_subject}"), "");
 1559         macdefine(mac, A_PERM, macid("{cn_issuer}"), "");
 1560         macdefine(mac, A_TEMP, macid(CERTFPMACRO), "");
 1561     }
 1562     switch (verifyok)
 1563     {
 1564       case X509_V_OK:
 1565         if (cert != NULL)
 1566         {
 1567             s = "OK";
 1568             r = TLS_AUTH_OK;
 1569         }
 1570         else
 1571         {
 1572             s = certreq ? "NO" : "NOT",
 1573             r = TLS_AUTH_NO;
 1574         }
 1575         break;
 1576       default:
 1577         s = "FAIL";
 1578         r = TLS_AUTH_FAIL;
 1579         break;
 1580     }
 1581     macdefine(mac, A_PERM, macid("{verify}"), s);
 1582     if (cert != NULL)
 1583         X509_free(cert);
 1584 
 1585     /* do some logging */
 1586     if (LogLevel > 8)
 1587     {
 1588         char *vers, *s1, *s2, *cbits, *algbits;
 1589 
 1590         vers = macget(mac, macid("{tls_version}"));
 1591         cbits = macget(mac, macid("{cipher_bits}"));
 1592         algbits = macget(mac, macid("{alg_bits}"));
 1593         s1 = macget(mac, macid("{verify}"));
 1594         s2 = macget(mac, macid("{cipher}"));
 1595 
 1596         /* XXX: maybe cut off ident info? */
 1597         sm_syslog(LOG_INFO, NOQID,
 1598               "STARTTLS=%s, relay=%.100s, version=%.16s, verify=%.16s, cipher=%.64s, bits=%.6s/%.6s",
 1599               who,
 1600               host == NULL ? "local" : host,
 1601               vers, s1, s2, /* sm_snprintf() can deal with NULL */
 1602               algbits == NULL ? "0" : algbits,
 1603               cbits == NULL ? "0" : cbits);
 1604         if (LogLevel > 11)
 1605         {
 1606             /*
 1607             **  Maybe run xuntextify on the strings?
 1608             **  That is easier to read but makes it maybe a bit
 1609             **  more complicated to figure out the right values
 1610             **  for the access map...
 1611             */
 1612 
 1613             s1 = macget(mac, macid("{cert_subject}"));
 1614             s2 = macget(mac, macid("{cert_issuer}"));
 1615             sm_syslog(LOG_INFO, NOQID,
 1616                   "STARTTLS=%s, cert-subject=%.256s, cert-issuer=%.256s, verifymsg=%s",
 1617                   who, s1, s2,
 1618                   X509_verify_cert_error_string(verifyok));
 1619         }
 1620     }
 1621     return r;
 1622 }
 1623 /*
 1624 **  ENDTLS -- shutdown secure connection
 1625 **
 1626 **  Parameters:
 1627 **      ssl -- SSL connection information.
 1628 **      side -- server/client (for logging).
 1629 **
 1630 **  Returns:
 1631 **      success? (EX_* code)
 1632 */
 1633 
 1634 int
 1635 endtls(ssl, side)
 1636     SSL *ssl;
 1637     char *side;
 1638 {
 1639     int ret = EX_OK;
 1640 
 1641     if (ssl != NULL)
 1642     {
 1643         int r;
 1644 
 1645         if ((r = SSL_shutdown(ssl)) < 0)
 1646         {
 1647             if (LogLevel > 11)
 1648             {
 1649                 sm_syslog(LOG_WARNING, NOQID,
 1650                       "STARTTLS=%s, SSL_shutdown failed: %d",
 1651                       side, r);
 1652                 tlslogerr(LOG_WARNING, side);
 1653             }
 1654             ret = EX_SOFTWARE;
 1655         }
 1656 # if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL
 1657 
 1658         /*
 1659         **  Bug in OpenSSL (at least up to 0.9.6b):
 1660         **  From: Lutz.Jaenicke@aet.TU-Cottbus.DE
 1661         **  Message-ID: <20010723152244.A13122@serv01.aet.tu-cottbus.de>
 1662         **  To: openssl-users@openssl.org
 1663         **  Subject: Re: SSL_shutdown() woes (fwd)
 1664         **
 1665         **  The side sending the shutdown alert first will
 1666         **  not care about the answer of the peer but will
 1667         **  immediately return with a return value of "0"
 1668         **  (ssl/s3_lib.c:ssl3_shutdown()). SSL_get_error will evaluate
 1669         **  the value of "0" and as the shutdown alert of the peer was
 1670         **  not received (actually, the program did not even wait for
 1671         **  the answer), an SSL_ERROR_SYSCALL is flagged, because this
 1672         **  is the default rule in case everything else does not apply.
 1673         **
 1674         **  For your server the problem is different, because it
 1675         **  receives the shutdown first (setting SSL_RECEIVED_SHUTDOWN),
 1676         **  then sends its response (SSL_SENT_SHUTDOWN), so for the
 1677         **  server the shutdown was successfull.
 1678         **
 1679         **  As is by know, you would have to call SSL_shutdown() once
 1680         **  and ignore an SSL_ERROR_SYSCALL returned. Then call
 1681         **  SSL_shutdown() again to actually get the server's response.
 1682         **
 1683         **  In the last discussion, Bodo Moeller concluded that a
 1684         **  rewrite of the shutdown code would be necessary, but
 1685         **  probably with another API, as the change would not be
 1686         **  compatible to the way it is now.  Things do not become
 1687         **  easier as other programs do not follow the shutdown
 1688         **  guidelines anyway, so that a lot error conditions and
 1689         **  compitibility issues would have to be caught.
 1690         **
 1691         **  For now the recommondation is to ignore the error message.
 1692         */
 1693 
 1694         else if (r == 0)
 1695         {
 1696             if (LogLevel > 15)
 1697             {
 1698                 sm_syslog(LOG_WARNING, NOQID,
 1699                       "STARTTLS=%s, SSL_shutdown not done",
 1700                       side);
 1701                 tlslogerr(LOG_WARNING, side);
 1702             }
 1703             ret = EX_SOFTWARE;
 1704         }
 1705 # endif /* !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL */
 1706         SSL_free(ssl);
 1707         ssl = NULL;
 1708     }
 1709     return ret;
 1710 }
 1711 
 1712 # if !TLS_NO_RSA
 1713 /*
 1714 **  TMP_RSA_KEY -- return temporary RSA key
 1715 **
 1716 **  Parameters:
 1717 **      s -- TLS connection structure
 1718 **      export --
 1719 **      keylength --
 1720 **
 1721 **  Returns:
 1722 **      temporary RSA key.
 1723 */
 1724 
 1725 #   ifndef MAX_RSA_TMP_CNT
 1726 #    define MAX_RSA_TMP_CNT 1000    /* XXX better value? */
 1727 #   endif /* ! MAX_RSA_TMP_CNT */
 1728 
 1729 /* ARGUSED0 */
 1730 static RSA *
 1731 tmp_rsa_key(s, export, keylength)
 1732     SSL *s;
 1733     int export;
 1734     int keylength;
 1735 {
 1736 #   if SM_CONF_SHM
 1737     extern int ShmId;
 1738     extern int *PRSATmpCnt;
 1739 
 1740     if (ShmId != SM_SHM_NO_ID && rsa_tmp != NULL &&
 1741         ++(*PRSATmpCnt) < MAX_RSA_TMP_CNT)
 1742         return rsa_tmp;
 1743 #   endif /* SM_CONF_SHM */
 1744 
 1745     if (rsa_tmp != NULL)
 1746         RSA_free(rsa_tmp);
 1747     rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL, NULL);
 1748     if (rsa_tmp == NULL)
 1749     {
 1750         if (LogLevel > 0)
 1751             sm_syslog(LOG_ERR, NOQID,
 1752                   "STARTTLS=server, tmp_rsa_key: RSA_generate_key failed!");
 1753     }
 1754     else
 1755     {
 1756 #   if SM_CONF_SHM
 1757 #    if 0
 1758         /*
 1759         **  XXX we can't (yet) share the new key...
 1760         **  The RSA structure contains pointers hence it can't be
 1761         **  easily kept in shared memory.  It must be transformed
 1762         **  into a continous memory region first, then stored,
 1763         **  and later read out again (each time re-transformed).
 1764         */
 1765 
 1766         if (ShmId != SM_SHM_NO_ID)
 1767             *PRSATmpCnt = 0;
 1768 #    endif /* 0 */
 1769 #   endif /* SM_CONF_SHM */
 1770         if (LogLevel > 9)
 1771             sm_syslog(LOG_ERR, NOQID,
 1772                   "STARTTLS=server, tmp_rsa_key: new temp RSA key");
 1773     }
 1774     return rsa_tmp;
 1775 }
 1776 # endif /* !TLS_NO_RSA */
 1777 /*
 1778 **  APPS_SSL_INFO_CB -- info callback for TLS connections
 1779 **
 1780 **  Parameters:
 1781 **      s -- TLS connection structure
 1782 **      where -- state in handshake
 1783 **      ret -- return code of last operation
 1784 **
 1785 **  Returns:
 1786 **      none.
 1787 */
 1788 
 1789 static void
 1790 apps_ssl_info_cb(s, where, ret)
 1791     CONST097 SSL *s;
 1792     int where;
 1793     int ret;
 1794 {
 1795     int w;
 1796     char *str;
 1797     BIO *bio_err = NULL;
 1798 
 1799     if (LogLevel > 14)
 1800         sm_syslog(LOG_INFO, NOQID,
 1801               "STARTTLS: info_callback where=0x%x, ret=%d",
 1802               where, ret);
 1803 
 1804     w = where & ~SSL_ST_MASK;
 1805     if (bio_err == NULL)
 1806         bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
 1807 
 1808     if (bitset(SSL_ST_CONNECT, w))
 1809         str = "SSL_connect";
 1810     else if (bitset(SSL_ST_ACCEPT, w))
 1811         str = "SSL_accept";
 1812     else
 1813         str = "undefined";
 1814 
 1815     if (bitset(SSL_CB_LOOP, where))
 1816     {
 1817         if (LogLevel > 12)
 1818             sm_syslog(LOG_NOTICE, NOQID,
 1819                 "STARTTLS: %s:%s",
 1820                 str, SSL_state_string_long(s));
 1821     }
 1822     else if (bitset(SSL_CB_ALERT, where))
 1823     {
 1824         str = bitset(SSL_CB_READ, where) ? "read" : "write";
 1825         if (LogLevel > 12)
 1826             sm_syslog(LOG_NOTICE, NOQID,
 1827                 "STARTTLS: SSL3 alert %s:%s:%s",
 1828                 str, SSL_alert_type_string_long(ret),
 1829                 SSL_alert_desc_string_long(ret));
 1830     }
 1831     else if (bitset(SSL_CB_EXIT, where))
 1832     {
 1833         if (ret == 0)
 1834         {
 1835             if (LogLevel > 7)
 1836                 sm_syslog(LOG_WARNING, NOQID,
 1837                     "STARTTLS: %s:failed in %s",
 1838                     str, SSL_state_string_long(s));
 1839         }
 1840         else if (ret < 0)
 1841         {
 1842             if (LogLevel > 7)
 1843                 sm_syslog(LOG_WARNING, NOQID,
 1844                     "STARTTLS: %s:error in %s",
 1845                     str, SSL_state_string_long(s));
 1846         }
 1847     }
 1848 }
 1849 /*
 1850 **  TLS_VERIFY_LOG -- log verify error for TLS certificates
 1851 **
 1852 **  Parameters:
 1853 **      ok -- verify ok?
 1854 **      ctx -- x509 context
 1855 **      name -- from where is this called?
 1856 **
 1857 **  Returns:
 1858 **      1 -- ok
 1859 */
 1860 
 1861 static int
 1862 tls_verify_log(ok, ctx, name)
 1863     int ok;
 1864     X509_STORE_CTX *ctx;
 1865     const char *name;
 1866 {
 1867     X509 *cert;
 1868     int reason, depth;
 1869     char buf[512];
 1870 
 1871     cert = X509_STORE_CTX_get_current_cert(ctx);
 1872     reason = X509_STORE_CTX_get_error(ctx);
 1873     depth = X509_STORE_CTX_get_error_depth(ctx);
 1874     X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
 1875     sm_syslog(LOG_INFO, NOQID,
 1876           "STARTTLS: %s cert verify: depth=%d %s, state=%d, reason=%s",
 1877           name, depth, buf, ok, X509_verify_cert_error_string(reason));
 1878     return 1;
 1879 }
 1880 
 1881 /*
 1882 **  TLS_VERIFY_CB -- verify callback for TLS certificates
 1883 **
 1884 **  Parameters:
 1885 **      ctx -- x509 context
 1886 **
 1887 **  Returns:
 1888 **      accept connection?
 1889 **      currently: always yes.
 1890 */
 1891 
 1892 static int
 1893 #  if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
 1894 tls_verify_cb(ctx)
 1895     X509_STORE_CTX *ctx;
 1896 #  else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
 1897 tls_verify_cb(ctx, unused)
 1898     X509_STORE_CTX *ctx;
 1899     void *unused;
 1900 #  endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
 1901 {
 1902     int ok;
 1903 
 1904     /*
 1905     **  man SSL_CTX_set_cert_verify_callback():
 1906     **  callback should return 1 to indicate verification success
 1907     **  and 0 to indicate verification failure.
 1908     */
 1909 
 1910     ok = X509_verify_cert(ctx);
 1911     if (ok <= 0)
 1912     {
 1913         if (LogLevel > 13)
 1914             return tls_verify_log(ok, ctx, "TLS");
 1915     }
 1916     return 1;
 1917 }
 1918 /*
 1919 **  TLSLOGERR -- log the errors from the TLS error stack
 1920 **
 1921 **  Parameters:
 1922 **      level -- syslog level
 1923 **      who -- server/client (for logging).
 1924 **
 1925 **  Returns:
 1926 **      none.
 1927 */
 1928 
 1929 void
 1930 tlslogerr(level, who)
 1931     int level;
 1932     const char *who;
 1933 {
 1934     unsigned long l;
 1935     int line, flags;
 1936     unsigned long es;
 1937     char *file, *data;
 1938     char buf[256];
 1939 
 1940     es = CRYPTO_thread_id();
 1941     while ((l = ERR_get_error_line_data((const char **) &file, &line,
 1942                         (const char **) &data, &flags))
 1943         != 0)
 1944     {
 1945         sm_syslog(level, NOQID,
 1946               "STARTTLS=%s: %lu:%s:%s:%d:%s", who, es,
 1947               ERR_error_string(l, buf),
 1948               file, line,
 1949               bitset(ERR_TXT_STRING, flags) ? data : "");
 1950     }
 1951 }
 1952 
 1953 # if OPENSSL_VERSION_NUMBER > 0x00907000L
 1954 /*
 1955 **  X509_VERIFY_CB -- verify callback
 1956 **
 1957 **  Parameters:
 1958 **      ctx -- x509 context
 1959 **
 1960 **  Returns:
 1961 **      accept connection?
 1962 **      currently: always yes.
 1963 */
 1964 
 1965 static int
 1966 x509_verify_cb(ok, ctx)
 1967     int ok;
 1968     X509_STORE_CTX *ctx;
 1969 {
 1970     if (ok == 0)
 1971     {
 1972         if (LogLevel > 13)
 1973             tls_verify_log(ok, ctx, "x509");
 1974         if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
 1975         {
 1976             ctx->error = 0;
 1977             return 1;   /* override it */
 1978         }
 1979     }
 1980     return ok;
 1981 }
 1982 # endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
 1983 #endif /* STARTTLS */