home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ck_ssl.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  148KB  |  4,359 lines

  1. char *cksslv = "SSL/TLS support, 9.0.227, 04 Aug 2010";
  2. /*
  3.   C K _ S S L . C --  OpenSSL Interface for C-Kermit
  4.  
  5.   Copyright (C) 1985, 2010,
  6.     Trustees of Columbia University in the City of New York.
  7.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  8.     copyright text in the ckcmai.c module for disclaimer and permissions.
  9.  
  10.     Author:  Jeffrey E Altman (jaltman@secure-endpoints.com)
  11.                Secure Endpoints Inc., New York City
  12.  
  13.   Provides:
  14.  
  15.   . Telnet Auth SSL option compatible with Tim Hudson's hack.
  16.   . Telnet START_TLS option
  17.   . Configuration of certificate and key files
  18.   . Certificate verification and revocation list checks
  19.   . Client certificate to user id routine
  20.  
  21.   Note: This code is written to be compatible with OpenSSL 0.9.6[abcdefgh]
  22.   and 0.9.7 beta 5 (and, presumably, later).
  23.   It will also compile with version 0.9.5 although that is discouraged
  24.   due to security weaknesses in that release.
  25. */
  26.  
  27. #include "ckcsym.h"
  28. #include "ckcdeb.h"
  29.  
  30. #ifdef CK_SSL
  31. #include "ckcnet.h"
  32. #include "ckuath.h"
  33.  
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #ifdef UNIX
  37. #include <netinet/in.h>
  38. #ifndef FREEBSD4
  39. #include <arpa/inet.h>
  40. #endif /* FREEBSD4 */
  41. #endif /* UNIX */
  42.  
  43. #ifdef DEC_TCPIP
  44. #include <time.h>
  45. #include <inet.h>
  46. #endif /* DEC_TCPIP */
  47.  
  48. #ifdef OS2
  49. extern char exedir[];
  50. #ifdef NT
  51. char * GetAppData(int);
  52. #endif
  53. #endif /* OS2 */
  54.  
  55. extern int quiet;            /* fdc - Mon Nov 28 11:44:15 2005 */
  56.  
  57. static int ssl_installed = 1;
  58. #endif /* CK_SSL */
  59. int
  60. ck_ssh_is_installed()
  61. {
  62. #ifdef SSHBUILTIN
  63. #ifdef SSLDLL
  64. #ifdef NT
  65.     extern HINSTANCE hCRYPTO;
  66. #else /* NT */
  67.     extern HMODULE hCRYPTO;
  68. #endif /* NT */
  69.     debug(F111,"ck_ssh_is_installed","hCRYPTO",hCRYPTO);
  70.     return(ssl_installed && (hCRYPTO != NULL));
  71. #else /* SSLDLL */
  72.     return(ssl_installed);
  73. #endif /* SSLDLL */
  74. #else
  75.     return 0;
  76. #endif
  77. }
  78.  
  79. int
  80. #ifdef CK_ANSIC
  81. ck_ssleay_is_installed(void)
  82. #else
  83. ck_ssleay_is_installed()
  84. #endif
  85. {
  86. #ifdef CK_SSL
  87. #ifdef SSLDLL
  88. #ifdef NT
  89.     extern HINSTANCE hSSL, hCRYPTO;
  90. #else /* NT */
  91.     extern HMODULE hSSL, hCRYPTO;
  92. #endif /* NT */
  93.     debug(F111,"ck_ssleay_is_installed","hSSL",hSSL);
  94.     debug(F111,"ck_ssleay_is_installed","hCRYPTO",hCRYPTO);
  95.     return(ssl_installed && (hSSL != NULL) && (hCRYPTO != NULL));
  96. #else /* SSLDLL */
  97.     return(ssl_installed);
  98. #endif /* SSLDLL */
  99. #else /* CK_SSL */
  100.     return(0);
  101. #endif /* CK_SSL */
  102. }
  103.  
  104. #ifdef CK_SSL
  105. #include "ckcker.h"
  106. #include "ckucmd.h"                             /* For struct keytab */
  107. #include "ckctel.h"
  108. #include "ck_ssl.h"
  109. #ifdef UNIX
  110. #include <pwd.h>                    /* Password file for home directory */
  111. #endif /* UNIX */
  112. #ifdef OS2
  113. #include <process.h>
  114. #endif /* OS2 */
  115. #ifdef OS2ONLY
  116. #include "ckotcp.h"
  117. #endif /* OS2ONLY */
  118.  
  119. #ifdef SSLDLL
  120. int ssl_finished_messages = 0;
  121. #else /* SSLDLL */
  122. #ifdef OPENSSL_VERSION_NUMBER
  123. int ssl_finished_messages = (OPENSSL_VERSION_NUMBER >= 0x0090581fL);
  124. #else
  125. !ERROR This module requires OpenSSL 0.9.5a or higher
  126. #endif /* OPENSSL_VERSION_NUMBER */
  127. #endif /* SSLDLL */
  128.  
  129. static int auth_ssl_valid = 0;
  130. static char *auth_ssl_name = 0;    /* this holds the oneline name */
  131. char ssl_err[SSL_ERR_BFSZ]="";
  132.  
  133. BIO *bio_err=NULL;
  134. X509_STORE *crl_store = NULL;
  135.  
  136. #ifndef NOFTP
  137. #ifndef SYSFTP
  138. SSL *ssl_ftp_con             = NULL;
  139. SSL_CTX *ssl_ftp_ctx         = NULL;
  140. SSL *ssl_ftp_data_con        = NULL;
  141. int ssl_ftp_active_flag      = 0;
  142. int ssl_ftp_data_active_flag = 0;
  143. #endif /* SYSFTP */
  144. #endif /* NOFTP */
  145.  
  146. #ifndef NOHTTP
  147. SSL *tls_http_con            = NULL;
  148. SSL_CTX *tls_http_ctx        = NULL;
  149. int tls_http_active_flag     = 0;
  150. int ssl_http_initialized = 0;
  151. #endif /* NOHTTP */
  152.  
  153. SSL_CTX *ssl_ctx = NULL;
  154. SSL *ssl_con = NULL;
  155. int ssl_debug_flag = 0;
  156. int ssl_verbose_flag = 0;
  157. int ssl_only_flag = 0;
  158. int ssl_raw_flag = 0;
  159. int ssl_active_flag = 0;
  160. int ssl_verify_flag = SSL_VERIFY_PEER;
  161. int ssl_certsok_flag = 0;
  162. char *ssl_rsa_cert_file = NULL;
  163. char *ssl_rsa_cert_chain_file = NULL;
  164. char *ssl_rsa_key_file = NULL;
  165. char *ssl_dsa_cert_file = NULL;
  166. char *ssl_dsa_cert_chain_file = NULL;
  167. char *ssl_dh_key_file = NULL;
  168. char *ssl_crl_file = NULL;
  169. char *ssl_crl_dir = NULL;
  170. char *ssl_verify_file = NULL;
  171. char *ssl_verify_dir = NULL;
  172. char *ssl_dh_param_file = NULL;
  173. char *ssl_cipher_list = NULL;
  174. char *ssl_rnd_file = NULL;
  175.  
  176. SSL_CTX *tls_ctx = NULL;
  177. SSL *tls_con = NULL;
  178. int tls_only_flag = 0;
  179. int tls_raw_flag = 0;
  180. int tls_active_flag = 0;
  181.  
  182. int ssl_initialized = 0;
  183. int ssl_verify_depth = -1; /* used to track depth in verify routines */
  184.  
  185. /* compile this set to 1 to negotiate SSL/TLS but not actually start it */
  186. int ssl_dummy_flag=0;
  187.  
  188. extern int inserver;
  189. extern int debses;
  190. extern int accept_complete;
  191. extern char szHostName[], szUserNameRequested[], szUserNameAuthenticated[];
  192.  
  193. _PROTOTYP(int X509_to_user,(X509 *, char *, int));
  194.  
  195. static int verbosity = 0;        /* Message control */
  196. static VOID
  197. setverbosity() {
  198.     verbosity = ssl_verbose_flag;
  199.     if (quiet) verbosity = 0;
  200. }
  201.  
  202. int
  203. #ifdef CK_ANSIC
  204. ssl_server_verify_callback(int ok, X509_STORE_CTX * ctx)
  205. #else /* CK_ANSIC */
  206. ssl_server_verify_callback(ok, ctx)
  207. int ok;
  208. X509_STORE_CTX *ctx;
  209. #endif /* CK_ANSIC */
  210. {
  211.     static char *saved_subject=NULL;
  212.     char *subject=NULL, *issuer=NULL;
  213.     int depth,error;
  214.     X509 *xs = NULL;
  215.  
  216.     if ( ssl_certsok_flag )
  217.         return(1);
  218.  
  219.     setverbosity();
  220.  
  221.     error=X509_STORE_CTX_get_error(ctx);
  222.     depth=X509_STORE_CTX_get_error_depth(ctx);
  223.     xs=X509_STORE_CTX_get_current_cert(ctx);
  224.  
  225.     if (depth==0) {
  226.         /* clear things */
  227.         if (saved_subject!=NULL) {
  228.             free(saved_subject);
  229.             saved_subject=NULL;
  230.         }
  231.         if (auth_ssl_name!=NULL) {
  232.             free(auth_ssl_name);
  233.             auth_ssl_name=NULL;
  234.         }
  235.     }
  236.  
  237.  
  238.     if (ssl_debug_flag && !inserver) {
  239.         printf("ssl:server_verify_callback:depth=%d ok=%d err=%d-%s\r\n",
  240.             depth,ok,error,X509_verify_cert_error_string(error));
  241.     }
  242.  
  243.     /* first thing is to have a meaningful name for the current
  244.      * certificate that is being verified ... and if we cannot
  245.      * determine that then something is seriously wrong!
  246.      */
  247.     makestr(&subject,
  248.             (char *)X509_NAME_oneline(X509_get_subject_name(xs),NULL,0));
  249.     makestr(&issuer,
  250.             (char *)X509_NAME_oneline(X509_get_issuer_name(xs),NULL,0));
  251.     if (!subject || !subject[0] || !issuer || !issuer[0]) {
  252.         ok = 0;
  253.         goto return_time;
  254.     }
  255.  
  256.     if (verbosity && !inserver && depth != ssl_verify_depth) {
  257.         printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
  258.         printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
  259.         ssl_verify_depth = depth;
  260.     }
  261.  
  262.     /* make sure that the certificate that has been presented */
  263.     /* has not been revoked (if we have been given a CRL.     */
  264.     ok =  ssl_verify_crl(ok, ctx);
  265.  
  266.     /* if we have any form of error in secure mode we reject the connection */
  267.     if (error!=X509_V_OK) {
  268.         if (inserver) {
  269. #ifdef CKSYSLOG
  270.             if (ckxsyslog >= SYSLG_LI && ckxlogging) {
  271.                 cksyslog(SYSLG_LI, 0,
  272.                           "X.509 Certificate verify failure",
  273.                           (char *) subject,
  274.                           (char *)X509_verify_cert_error_string(error)
  275.                           );
  276.             }
  277. #endif /* CKSYSLOG */
  278.  
  279.         } else {
  280.             if ( ssl_verify_flag &
  281.                  (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
  282.                 printf("Error: ");
  283.             else
  284.                 printf("Warning: ");
  285.             switch (error) {
  286.             case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
  287.                 printf("Certificate is self signed.\r\n");
  288.                 break;
  289.             case X509_V_ERR_CERT_HAS_EXPIRED:
  290.                 printf("Certificate has expired.\r\n");
  291.                 break;
  292.             case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
  293.                 printf(
  294.   "Certificate issuer's certificate isn't available locally.\r\n");
  295.                 break;
  296.             case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
  297.                 printf("Unable to verify leaf signature.\r\n");
  298.                 break;
  299.             case X509_V_ERR_CERT_REVOKED:
  300.                 printf("Certificate revoked.\r\n");
  301.                 break;
  302.             default:
  303.                 printf("Error %d while verifying certificate.\r\n",
  304.                        ctx->error);
  305.                 break;
  306.             }
  307.         }
  308.         ok = !(ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
  309.     } else {
  310.         /* if we got all the way to the top of the tree then
  311.          * we *can* use this certificate for a username to
  312.          * match ... in all other cases we must not!
  313.          */
  314.         auth_ssl_name = saved_subject;
  315.         saved_subject = NULL;
  316.     }
  317.  
  318.   return_time:
  319.  
  320.     /* save the name if at least the first level is okay */
  321.     if (depth == 0 && ok)
  322.         makestr(&saved_subject,subject);
  323.  
  324.     /* clean up things */
  325.     if (subject!=NULL)
  326.         free(subject);
  327.     if (issuer!=NULL)
  328.         free(issuer);
  329.  
  330.     return ok;
  331. }
  332.  
  333. int
  334. #ifdef CK_ANSIC
  335. ssl_client_verify_callback(int ok, X509_STORE_CTX * ctx)
  336. #else
  337. ssl_client_verify_callback(ok, ctx)
  338. int ok;
  339. X509_STORE_CTX *ctx;
  340. #endif
  341. {
  342.     char subject[256]="", issuer[256]="";
  343.     int depth, error, len;
  344.     X509 *xs;
  345.  
  346.     setverbosity();
  347.  
  348.     xs=X509_STORE_CTX_get_current_cert(ctx);
  349.     error=X509_STORE_CTX_get_error(ctx);
  350.     depth=X509_STORE_CTX_get_error_depth(ctx);
  351.  
  352.     if ( ssl_debug_flag )
  353.         printf("ssl:client_verify_callback:depth=%d ok=%d err=%d-%s\r\n",
  354.                 depth,ok,error,X509_verify_cert_error_string(error));
  355.  
  356.     if ( ssl_certsok_flag ) {
  357.         ok = 1;
  358.     }
  359.  
  360.     /* first thing is to have a meaningful name for the current
  361.      * certificate that is being verified ... and if we cannot
  362.      * determine that then something is seriously wrong!
  363.      */
  364. #ifdef XN_FLAG_SEP_MULTILINE
  365.     X509_NAME_print_ex(bio_err,X509_get_subject_name(xs),4,
  366.                         XN_FLAG_SEP_MULTILINE);
  367.     len = BIO_read(bio_err,subject,256);
  368.     subject[len < 256 ? len : 255] = '\0';
  369.     if (!subject[0]) {
  370.         ERR_print_errors(bio_err);
  371.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  372.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  373.         uq_ok("X.509 Subject Name unavailable", ssl_err, 1, NULL, 0);
  374.         ok=0;
  375.         goto return_time;
  376.     }
  377.  
  378.     X509_NAME_print_ex(bio_err,X509_get_issuer_name(xs),4,
  379.                         XN_FLAG_SEP_MULTILINE);
  380.     len = BIO_read(bio_err,issuer,256);
  381.     issuer[len < 256 ? len : 255] = '\0';
  382.     if (!issuer[0]) {
  383.         ERR_print_errors(bio_err);
  384.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  385.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  386.         uq_ok("X.509 Issuer Name unavailable", ssl_err, 1, NULL, 0);
  387.         ok=0;
  388.         goto return_time;
  389.     }
  390. #else /* XN_FLAG_SEP_MULTILINE */
  391.     X509_NAME_oneline(X509_get_subject_name(xs),subject,256);
  392.     if (!subject[0]) {
  393.         int len;
  394.         ERR_print_errors(bio_err);
  395.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  396.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  397.         uq_ok("X.509 Subject Name unavailable", ssl_err, 1, NULL, 0);
  398.         ok=0;
  399.         goto return_time;
  400.     }
  401.  
  402.     X509_NAME_oneline(X509_get_issuer_name(xs),issuer,256);
  403.     if (!issuer[0]) {
  404.         int len;
  405.         ERR_print_errors(bio_err);
  406.         len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  407.         ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  408.         uq_ok("X.509 Issuer Name unavailable", ssl_err, 1, NULL, 0);
  409.         ok=0;
  410.         goto return_time;
  411.     }
  412. #endif /* XN_FLAG_SEP_MULTILINE */
  413.  
  414.     if (verbosity && depth != ssl_verify_depth) {
  415.         printf("[%d] Certificate Subject:\r\n%s\r\n",depth,subject);
  416.         printf("[%d] Certificate Issuer:\r\n%s\r\n",depth,issuer);
  417.         ssl_verify_depth = depth;
  418.     }
  419.  
  420.     ok = ssl_verify_crl(ok, ctx);
  421.  
  422.     if ( !ok ) {
  423.         char prefix[1024];
  424.         /* if the server is using a self signed certificate then
  425.          * we need to decide if that is good enough for us to
  426.          * accept ...
  427.          */
  428.  
  429.         switch ( error ) {
  430.         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: {
  431.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  432.                 /* make 100% sure that in secure more we drop the
  433.                  * connection if the server does not have a
  434.                  * real certificate!
  435.                  */
  436.                 ckmakxmsg(prefix,1024,
  437.                            "Error: Server has a self-signed certificate\n",
  438.                            "[",ckitoa(depth),"] Certificate Subject=\n",subject,
  439.                            "\n[",ckitoa(depth),"] Certificate Issuer=\n",issuer,
  440.                            NULL,NULL,NULL);
  441.  
  442.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  443.  
  444.                 /* sometimes it is really handy to be able to debug things
  445.                 * and still get a connection!
  446.                 */
  447.                 if (ssl_debug_flag) {
  448.                     printf("SSL: debug -> ignoring cert required!\r\n");
  449.                     ok=1;
  450.                 } else {
  451.                     ok=0;
  452.                 }
  453.                 goto return_time;
  454.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  455.                 ckmakxmsg(prefix,1024,
  456.                            "Warning: Server has a self-signed certificate\n",
  457.                            "[",ckitoa(depth),"] Certificate Subject=\n",subject,
  458.                            "\n[",ckitoa(depth),"] Certificate Issuer=\n",issuer,
  459.                            NULL,NULL,NULL);
  460.  
  461.                 ok = uq_ok(prefix,
  462.                            "Continue? (Y/N) ",
  463.                            3, NULL, 0);
  464.                 if ( ok < 0 )
  465.                     ok = 0;
  466.                 goto return_time;
  467.             }
  468.         }
  469.         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
  470.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  471.                 /* make 100% sure that in secure more we drop the
  472.                  * connection if the server does not have a
  473.                  * real certificate!
  474.                  */
  475.                 ckmakxmsg(prefix,1024,
  476.                            "Error: ",
  477.                            (char *)X509_verify_cert_error_string(error),
  478.                            "\nCertificate Issuer=\n",issuer,
  479.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  480.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  481.  
  482.                 /* sometimes it is really handy to be able to debug things
  483.                 * and still get a connection!
  484.                 */
  485.                 if (ssl_debug_flag) {
  486.                     printf("SSL: debug -> ignoring cert required!\r\n");
  487.                     ok=1;
  488.                 } else {
  489.                     ok=0;
  490.                 }
  491.                 goto return_time;
  492.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  493.                 ckmakxmsg(prefix,1024,
  494.                            "Warning: ",
  495.                            (char *)X509_verify_cert_error_string(error),
  496.                            "\nCertificate Issuer=\n",issuer,
  497.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  498.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  499.                 goto return_time;
  500.             }
  501.             break;
  502.         case X509_V_ERR_CERT_NOT_YET_VALID:
  503.         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
  504.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  505.                 int len;
  506.                 /* make 100% sure that in secure more we drop the
  507.                  * connection if the server does not have a
  508.                  * real certificate!
  509.                  */
  510.                 ASN1_TIME_print(bio_err,X509_get_notBefore(xs));
  511.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  512.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  513.                 ckmakxmsg(prefix,1024,
  514.                            "Error: ",
  515.                            (char *)X509_verify_cert_error_string(error),
  516.                            "\nCertificate Subject=\n",subject,
  517.                            "\nnotBefore=",ssl_err,
  518.                            NULL,NULL,NULL,NULL,NULL,NULL);
  519.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  520.                 /* sometimes it is really handy to be able to debug things
  521.                 * and still get a connection!
  522.                 */
  523.                 if (ssl_debug_flag) {
  524.                     printf("SSL: debug -> ignoring cert required!\r\n");
  525.                     ok=1;
  526.                 } else {
  527.                     ok=0;
  528.                 }
  529.                 goto return_time;
  530.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  531.                 int len;
  532.                 ASN1_TIME_print(bio_err,X509_get_notBefore(xs));
  533.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  534.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  535.                 ckmakxmsg(prefix,1024,
  536.                            "Warning: ",
  537.                            (char *)X509_verify_cert_error_string(error),
  538.                            "\nCertificate Subject=\n",subject,
  539.                            "\n    notBefore=",ssl_err,
  540.                            NULL,NULL,NULL,NULL,NULL,NULL);
  541.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  542.             }
  543.             break;
  544.         case X509_V_ERR_CERT_HAS_EXPIRED:
  545.         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
  546.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  547.                 int len;
  548.                 /* make 100% sure that in secure more we drop the
  549.                  * connection if the server does not have a
  550.                  * real certificate!
  551.                  */
  552.                 ASN1_TIME_print(bio_err,X509_get_notAfter(xs));
  553.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  554.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  555.  
  556.                 ckmakxmsg(prefix,1024,
  557.                            "Error: ",
  558.                            (char *)X509_verify_cert_error_string(error),
  559.                            "\nCertificate Subject=\n",subject,
  560.                            "\n    notAfter=",ssl_err,
  561.                            NULL,NULL,NULL,NULL,NULL,NULL);
  562.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  563.    
  564.                 /* sometimes it is really handy to be able to debug things
  565.                 * and still get a connection!
  566.                 */
  567.                 if (ssl_debug_flag) {
  568.                     printf("SSL: debug -> ignoring cert required!\r\n");
  569.                     ok=1;
  570.                 } else {
  571.                     ok=0;
  572.                 }
  573.                 goto return_time;
  574.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  575.                 int len;
  576.                 ASN1_TIME_print(bio_err,X509_get_notAfter(xs));
  577.                 len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  578.                 ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  579.                 ckmakxmsg(prefix,1024,
  580.                            "Warning: ",
  581.                            (char *)X509_verify_cert_error_string(error),
  582.                            "\nCertificate Subject=\n",subject,
  583.                            "\n    notAfter=",ssl_err,
  584.                            NULL,NULL,NULL,NULL,NULL,NULL);
  585.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  586.             }
  587.             break;
  588.         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
  589.         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
  590.             /*
  591.              * When an SSL server sends its certificates to the client there
  592.              * are two" conventions": one is to send the complete certificate
  593.              * chain and the other is to send the whole chain apart from the
  594.              * root.
  595.              *
  596.              * You don't usually need the root because the root is normally
  597.              * stored and trusted locally.
  598.              *
  599.              * So if you get the whole chain it will complain about the self
  600.              * signed certificate whereas if the root is missing it says it
  601.              * can't find the issuer certificate.
  602.              */
  603.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  604.                 /* make 100% sure that in secure more we drop the
  605.                  * connection if the server does not have a
  606.                  * real certificate!
  607.                  */
  608.                 ckmakxmsg(prefix,1024,
  609.                            "Error: ",
  610.                            (char *)X509_verify_cert_error_string(error),
  611.                            "\nCertificate Issuer=\n",issuer,
  612.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  613.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  614.                 /* sometimes it is really handy to be able to debug things
  615.                 * and still get a connection!
  616.                 */
  617.                 if (ssl_debug_flag) {
  618.                     printf("SSL: debug -> ignoring cert required!\r\n");
  619.                     ok=1;
  620.                 } else {
  621.                     ok=0;
  622.                 }
  623.                 goto return_time;
  624.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  625.                 ckmakxmsg(prefix,1024,
  626.                            "Warning: ",
  627.                            (char *)X509_verify_cert_error_string(error),
  628.                            "\nCertificate Issuer=\n",issuer,
  629.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  630.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  631. #ifdef NT
  632.                 if (ok) {
  633.                     /* if the user decides to accept the certificate
  634.                      * offer to store it for future connections in 
  635.                      * the user's private store
  636.                      */
  637.                     ok = uq_ok(
  638.   "Do you wish to store the certificate to verify future connections?",
  639.                                "Continue (Y/N)", 3, NULL, 0);
  640.                     if (ok)
  641.                         ck_X509_save_cert_to_user_store(xs);
  642.                 }
  643. #endif /* NT */
  644.             }
  645.             break;
  646.         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
  647.         case X509_V_ERR_UNABLE_TO_GET_CRL:
  648.         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
  649.         case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
  650.         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
  651.         case X509_V_ERR_CERT_SIGNATURE_FAILURE:
  652.         case X509_V_ERR_CRL_SIGNATURE_FAILURE:
  653.         case X509_V_ERR_CRL_NOT_YET_VALID:
  654.         case X509_V_ERR_CRL_HAS_EXPIRED:
  655.         case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
  656.         case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
  657.         case X509_V_ERR_OUT_OF_MEM:
  658.         case X509_V_ERR_CERT_CHAIN_TOO_LONG:
  659.         case X509_V_ERR_CERT_REVOKED:
  660.         case X509_V_ERR_APPLICATION_VERIFICATION:
  661.         default:
  662.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  663.                 /* make 100% sure that in secure mode we drop the
  664.                  * connection if the server does not have a
  665.                  * real certificate!
  666.                  */
  667.                 ckmakxmsg(prefix,1024,
  668.                            "Error: ",
  669.                            (char *)X509_verify_cert_error_string(error),
  670.                            "\nCertificate Subject=\n",subject,
  671.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  672.                 uq_ok(prefix, "Rejecting Connection", 1, NULL, 0);
  673.  
  674.                 /* sometimes it is really handy to be able to debug things
  675.                 * and still get a connection!
  676.                 */
  677.                 if (ssl_debug_flag) {
  678.                     printf("SSL: debug -> ignoring cert required!\r\n");
  679.                     ok=1;
  680.                 } else {
  681.                     ok=0;
  682.                 }
  683.                 goto return_time;
  684.             } else if (ssl_verify_flag != SSL_VERIFY_NONE) {
  685.                 ckmakxmsg(prefix,1024,
  686.                            "Warning: ",
  687.                            (char *)X509_verify_cert_error_string(error),
  688.                            "\nCertificate Subject=\n",subject,
  689.                            NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  690.                 ok = uq_ok(prefix, "Continue (Y/N)", 3, NULL, 0);
  691.             }
  692.             break;
  693.         }
  694.     }
  695.  
  696.   return_time:
  697.     if ( ssl_debug_flag )
  698.         printf("ssl:client_verify_callback => ok: %d\r\n",ok);
  699.     return ok;
  700. }
  701.  
  702. VOID
  703. #ifdef CK_ANSIC
  704. ssl_client_info_callback(const SSL *s, int where, int ret)
  705. #else
  706. ssl_client_info_callback(s,where,ret)
  707. const SSL *s;
  708. int where;
  709. int ret;
  710. #endif /* CK_ANSIC */
  711. {
  712.     if (inserver || !ssl_debug_flag)
  713.         return;
  714.  
  715.     setverbosity();
  716.  
  717.     switch ( where ) {
  718.     case SSL_CB_CONNECT_LOOP:
  719.         printf("SSL_connect:%s %s\r\n",
  720.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  721.         break;
  722.     case SSL_CB_CONNECT_EXIT:
  723.         if (ret == 0) {
  724.             printf("SSL_connect:failed in %s %s\r\n",
  725.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  726.         } else if (ret < 0) {
  727.             printf("SSL_connect:error in %s %s\r\n",
  728.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  729.         }
  730.         break;
  731.     case SSL_CB_ACCEPT_LOOP:
  732.         printf("SSL_accept:%s %s\r\n",
  733.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  734.         break;
  735.     case SSL_CB_ACCEPT_EXIT:
  736.         if (ret == 0) {
  737.             printf("SSL_accept:failed in %s %s\r\n",
  738.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  739.         } else if (ret < 0) {
  740.             printf("SSL_accept:error in %s %s\r\n",
  741.                     SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  742.         }
  743.         break;
  744.     case SSL_CB_READ_ALERT:
  745.         printf("SSL_read_alert\r\n");
  746.         break;
  747.     case SSL_CB_WRITE_ALERT:
  748.         printf("SSL_write_alert\r\n");
  749.         break;
  750.     case SSL_CB_HANDSHAKE_START:
  751.         printf("SSL_handshake:%s %s\r\n",
  752.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  753.         break;
  754.     case SSL_CB_HANDSHAKE_DONE:
  755.         printf("SSL_handshake:%s %s\r\n",
  756.                 SSL_state_string((SSL *)s),SSL_state_string_long((SSL *)s));
  757.         break;
  758.     }
  759. }
  760.  
  761. #ifdef USE_CERT_CB
  762. /* Return 1, client cert is available */
  763. /* Return 0, no client cert is available */
  764. /* Return -1, callback must be called again. SSL_want_x509_lookup() == 1 */
  765. int
  766. #ifdef CK_ANSIC
  767. ssl_client_cert_callback(SSL * s, X509 ** x509, EVP_PKEY ** pkey)
  768. #else /* CK_ANSIC */
  769. ssl_client_cert_callback(s, x509, pkey)
  770.     SSL * s;
  771.     X509 ** x509;
  772.     EVP_PKEY ** pkey;
  773. #endif /* CK_ANSIC */
  774. {
  775.     setverbosity();
  776.  
  777.     if ( ssl_debug_flag ) {
  778.         const char * cipher_list=SSL_get_cipher(s);
  779.         printf("ssl_client_cert_callback called (%s)\r\n",
  780.                 cipher_list?cipher_list:"UNKNOWN");
  781.     }
  782. #ifdef COMMENT
  783.     if ( s == tls_con ) {
  784.         if (tls_load_certs(tls_cts,tls_con,0)) {
  785.             *x509 = SSL_get_certificate(s);
  786.             *pkey = SSL_get_privatekey(s);
  787.             return(1);
  788.         }
  789.     } else if ( s == ssl_con ) {
  790.         if (tls_load_certs(ssl_ctx,ssl_con,0)) {
  791.             *x509 = SSL_get_certificate(s);
  792.             *pkey = SSL_get_privatekey(s);
  793.             return(1);
  794.         }
  795.     }
  796.     return(0);
  797. #else /* COMMENT */
  798.     return(0);
  799. #endif /* COMMENT */
  800. }
  801. #endif /* USE_CERT_CB */
  802.  
  803. #ifndef MS_CALLBACK
  804. #define MS_CALLBACK
  805. #endif /* MS_CALLBACK */
  806.  
  807. static RSA MS_CALLBACK *
  808. #ifdef CK_ANSIC
  809. tmp_rsa_cb(SSL * s, int export, int keylength)
  810. #else /* CK_ANSIC */
  811. tmp_rsa_cb(s,export,keylength)
  812. SSL *s;
  813. int export;
  814. int keylength;
  815. #endif /* CK_ANSIC */
  816. {
  817.     static RSA *rsa_tmp=NULL;
  818.  
  819. #ifndef NO_RSA
  820.     if (rsa_tmp == NULL)
  821.     {
  822.         if (ssl_debug_flag)
  823.             printf("Generating temporary (%d bit) RSA key...\r\n",keylength);
  824.  
  825.         rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL);
  826.  
  827.         if (ssl_debug_flag)
  828.             printf("\r\n");
  829.     }
  830. #else /* NO_RSA */
  831.     if (ssl_debug_flag)
  832.         printf("Unable to generate temporary RSA key...\r\n");
  833. #endif
  834.     return(rsa_tmp);
  835. }
  836.  
  837.  
  838. #ifndef NO_DH
  839. static unsigned char dh512_p[]={
  840.     0xE9,0x4E,0x3A,0x64,0xFA,0x65,0x5F,0xA6,0x44,0xC7,0xFC,0xF1,
  841.     0x16,0x8B,0x11,0x11,0x7A,0xF0,0xB2,0x49,0x80,0x56,0xA3,0xF8,
  842.     0x0F,0x7D,0x01,0x68,0x5D,0xF6,0x8A,0xEA,0x8C,0xDD,0x01,0xDC,
  843.     0x43,0x18,0xE0,0xC4,0x89,0x80,0xE6,0x2D,0x44,0x77,0x45,0xFD,
  844.     0xBA,0xFC,0x43,0x35,0x12,0xC0,0xED,0x32,0xD3,0x16,0xEF,0x51,
  845.     0x09,0x44,0xA2,0xDB,
  846. };
  847. static unsigned char dh512_g[]={
  848.     0x05,
  849. };
  850.  
  851. static unsigned char dh768_p[]={
  852.     0x8B,0x2A,0x8C,0x6C,0x0F,0x87,0xC7,0x34,0xEE,0x2E,0xFB,0x60,
  853.     0x94,0xB3,0xBF,0x95,0xBA,0x84,0x74,0x86,0xEA,0xE0,0xA4,0x33,
  854.     0xE0,0x8F,0x7C,0x79,0x5C,0x62,0xE2,0x91,0xC5,0x6D,0x68,0xB9,
  855.     0x6C,0x5E,0x4E,0x94,0x0C,0x8E,0x56,0x8E,0xEB,0x98,0x7C,0x6E,
  856.     0x0E,0xF2,0xD5,0xAA,0x22,0x27,0x3F,0x0F,0xAF,0x10,0xB5,0x0B,
  857.     0x16,0xCC,0x05,0x27,0xBB,0x58,0x6D,0x61,0x4B,0x2B,0xAB,0xDC,
  858.     0x6A,0x15,0xBC,0x36,0x75,0x4D,0xEC,0xAB,0xFA,0xB6,0xE1,0xB1,
  859.     0x13,0x70,0xD8,0x77,0xCD,0x5E,0x51,0x77,0x81,0x0D,0x77,0x43,
  860. };
  861. static unsigned char dh768_g[]={
  862.     0x05,
  863. };
  864.  
  865. static unsigned char dh1024_p[]={
  866.     0xA4,0x75,0xCF,0x35,0x00,0xAF,0x3C,0x17,0xCE,0xB0,0xD0,0x52,
  867.     0x43,0xA0,0x0E,0xFA,0xA2,0xC9,0xBE,0x0B,0x76,0x7A,0xD9,0x2E,
  868.     0xF4,0x97,0xAC,0x02,0x24,0x69,0xF6,0x36,0x4F,0xAB,0xCC,0x43,
  869.     0xC1,0x74,0xFF,0xA3,0xD4,0x04,0x0F,0x11,0x2B,0x6D,0x8C,0x47,
  870.     0xC9,0xCF,0x40,0x93,0x9B,0x7D,0x1E,0x52,0x85,0xB2,0x17,0x55,
  871.     0x9C,0xF2,0x41,0x02,0x2A,0x9D,0x5F,0x24,0x22,0xC6,0x04,0xC4,
  872.     0xAB,0x92,0x6D,0xC7,0xC8,0xF3,0x41,0x58,0x6C,0x86,0xFD,0xB8,
  873.     0x0F,0x2D,0xDD,0xBF,0xA8,0x40,0x0C,0x58,0xC8,0xF2,0x3F,0x18,
  874.     0xEF,0xF1,0x93,0x3E,0xBA,0x16,0x41,0xBE,0x32,0x6C,0xC5,0x63,
  875.     0xFF,0x8A,0x02,0x3D,0xAC,0xD5,0x5A,0x49,0x64,0x34,0x14,0x2E,
  876.     0xFB,0x2E,0xE7,0x39,0x1A,0x0F,0x3C,0x33,
  877. };
  878. static unsigned char dh1024_g[]={
  879.     0x05,
  880. };
  881.  
  882. static unsigned char dh1536_p[]={
  883.     0xA3,0x2B,0x75,0x0E,0x7B,0x31,0x82,0xCA,0xF2,0xFC,0xF3,0x3D,
  884.     0xCE,0x5F,0xCD,0x5B,0x95,0xF6,0x2F,0xA4,0x5D,0x08,0x26,0xD2,
  885.     0x5F,0xC0,0x3F,0xC5,0xD8,0xA2,0xFE,0x83,0x26,0xBC,0xEB,0x7D,
  886.     0xF0,0x4E,0xD2,0xA6,0xBB,0x3C,0x88,0x63,0xCE,0x98,0xDE,0x08,
  887.     0xE2,0xE1,0xAF,0xE2,0x38,0xA8,0xFA,0x68,0x76,0x8D,0xBF,0xDF,
  888.     0xBB,0x30,0x15,0xFE,0xBD,0x22,0xCC,0x03,0x4E,0x5E,0x33,0xA3,
  889.     0x6D,0xD6,0x68,0x12,0x97,0x17,0x4B,0xB5,0x84,0x5F,0x5F,0xA3,
  890.     0x5C,0x2F,0xA4,0x10,0xC1,0xAD,0xBF,0xAC,0x30,0xCA,0x47,0x64,
  891.     0x63,0xFE,0xEE,0xEE,0xA1,0x64,0x73,0x70,0xAA,0xF9,0xFE,0xC6,
  892.     0xAD,0x5E,0xF6,0xF3,0x9C,0xDF,0x34,0x53,0x34,0x72,0xA6,0xA4,
  893.     0xBB,0x81,0x5A,0x43,0x41,0xFD,0x41,0x05,0x5B,0x77,0x7B,0x84,
  894.     0x03,0xFA,0x8A,0xFA,0xF7,0x8E,0x0F,0xCB,0x51,0xA2,0xB8,0x45,
  895.     0xFF,0x59,0x42,0xEF,0xCF,0xF6,0x25,0x37,0xE2,0x6D,0xFF,0x69,
  896.     0x11,0xF5,0x77,0x59,0x79,0x1C,0x5F,0x05,0xFC,0x7A,0x65,0x81,
  897.     0x03,0x4A,0x78,0xC6,0xE9,0x48,0x73,0xF6,0x10,0xBC,0x99,0x1C,
  898.     0xEE,0x44,0x2F,0x8B,0x70,0xCA,0xA8,0xB6,0x02,0x83,0x3E,0x0B,
  899. };
  900. static unsigned char dh1536_g[]={
  901.     0x05,
  902. };
  903.  
  904. static unsigned char dh2048_p[]={
  905.     0xFA,0x4E,0xE4,0x3B,0xFA,0xC1,0x87,0xDD,0xE7,0xC6,0x8B,0xE6,
  906.     0x13,0x85,0xBC,0x9B,0x2B,0x8B,0x5B,0x46,0xBB,0x8B,0x86,0x6D,
  907.     0xD7,0xB6,0xD5,0x49,0xC5,0x54,0xF2,0x3E,0xD2,0x39,0x64,0x9B,
  908.     0x0E,0x33,0x39,0x8F,0xFA,0xFA,0xD9,0x78,0xED,0x34,0x82,0x29,
  909.     0x37,0x58,0x4D,0x5D,0x40,0xCB,0x69,0xE3,0x8A,0x9F,0x17,0x0C,
  910.     0x01,0x23,0x6B,0x05,0x01,0xAF,0x33,0xDE,0xDF,0x1A,0xBB,0x7B,
  911.     0x6A,0x9F,0xD8,0xED,0x8D,0x5E,0x44,0x19,0x5B,0xE0,0xB6,0x23,
  912.     0xF9,0x7A,0x96,0x6E,0x94,0x33,0x31,0x49,0xBA,0x84,0xD5,0x12,
  913.     0xD7,0x6D,0xDC,0x35,0x54,0x64,0xA3,0xD8,0x04,0x26,0xC5,0xAF,
  914.     0x7F,0xE3,0xFE,0x6F,0xBE,0xD5,0x17,0x72,0x4B,0xA6,0xD0,0xA7,
  915.     0x5F,0x18,0xF5,0xF0,0x2D,0x11,0x9A,0xF6,0xD5,0x3B,0x6C,0x61,
  916.     0x3C,0x6F,0x8E,0x09,0x4F,0x2C,0xE1,0x26,0x06,0x51,0xB3,0x19,
  917.     0x85,0x85,0x13,0xF9,0xC2,0x6E,0x80,0x28,0x9E,0x8A,0xA0,0x01,
  918.     0x46,0xD1,0x85,0x44,0x8C,0xE6,0xEE,0x7E,0x1E,0x17,0x3D,0xBA,
  919.     0x54,0xFF,0xE8,0x0E,0xDD,0x51,0xF3,0x74,0x7F,0x0D,0x0B,0xAB,
  920.     0xCA,0x84,0x8D,0x24,0x5D,0x56,0xD4,0x47,0x02,0xFC,0x93,0x9F,
  921.     0xAE,0x9B,0x5C,0xDB,0x63,0xEB,0x65,0x01,0x38,0xC2,0x7B,0x30,
  922.     0x1E,0x17,0x1C,0x75,0xF5,0x16,0x3B,0x4F,0x5F,0x41,0x32,0xB5,
  923.     0xFF,0x9E,0x61,0xFD,0xD2,0x62,0x6E,0xFD,0x8A,0x28,0x93,0x59,
  924.     0x2D,0x70,0x14,0x4D,0xE1,0x86,0xD5,0x90,0xB4,0xDF,0x72,0x71,
  925.     0xE0,0xB4,0xD0,0xD6,0x82,0x3A,0x4A,0x04,0x58,0x32,0x0B,0xD3,
  926.     0x51,0x13,0x32,0x63,
  927. };
  928. static unsigned char dh2048_g[]={
  929.     0x02,
  930. };
  931.  
  932. static DH *
  933. get_dh512()
  934. {
  935.     DH *dh=NULL;
  936.  
  937.     if ((dh=DH_new()) == NULL)
  938.         return(NULL);
  939.     dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
  940.     dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
  941.     if ((dh->p == NULL) || (dh->g == NULL))
  942.         return(NULL);
  943.     return(dh);
  944. }
  945.  
  946. static DH *
  947. get_dh768()
  948. {
  949.     DH *dh=NULL;
  950.  
  951.     if ((dh=DH_new()) == NULL)
  952.         return(NULL);
  953.     dh->p=BN_bin2bn(dh768_p,sizeof(dh768_p),NULL);
  954.     dh->g=BN_bin2bn(dh768_g,sizeof(dh768_g),NULL);
  955.     if ((dh->p == NULL) || (dh->g == NULL))
  956.         return(NULL);
  957.     return(dh);
  958. }
  959.  
  960. static DH *
  961. get_dh1024()
  962. {
  963.     DH *dh=NULL;
  964.  
  965.     if ((dh=DH_new()) == NULL)
  966.         return(NULL);
  967.     dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL);
  968.     dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL);
  969.     if ((dh->p == NULL) || (dh->g == NULL))
  970.         return(NULL);
  971.     return(dh);
  972. }
  973.  
  974. static DH *
  975. get_dh1536()
  976. {
  977.     DH *dh=NULL;
  978.  
  979.     if ((dh=DH_new()) == NULL)
  980.         return(NULL);
  981.     dh->p=BN_bin2bn(dh1536_p,sizeof(dh1536_p),NULL);
  982.     dh->g=BN_bin2bn(dh1536_g,sizeof(dh1536_g),NULL);
  983.     if ((dh->p == NULL) || (dh->g == NULL))
  984.         return(NULL);
  985.     return(dh);
  986. }
  987.  
  988. static DH *
  989. get_dh2048()
  990. {
  991.     DH *dh=NULL;
  992.  
  993.     if ((dh=DH_new()) == NULL)
  994.         return(NULL);
  995.     dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
  996.     dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
  997.     if ((dh->p == NULL) || (dh->g == NULL))
  998.         return(NULL);
  999.     return(dh);
  1000. }
  1001. #endif /* NO_DH */
  1002.  
  1003. static DH MS_CALLBACK *
  1004. #ifdef CK_ANSIC
  1005. tmp_dh_cb(SSL * s, int export, int keylength)
  1006. #else /* CK_ANSIC */
  1007. tmp_dh_cb(s,export,keylength)
  1008. SSL *s;
  1009. int export;
  1010. int keylength;
  1011. #endif /* CK_ANSIC */
  1012. {
  1013.     static DH *dh_tmp=NULL;
  1014.     BIO *bio=NULL;
  1015.  
  1016. #ifndef NO_DH
  1017.     if (dh_tmp == NULL)
  1018.     {
  1019.         if (ssl_dh_param_file  &&
  1020.              (bio=BIO_new_file(ssl_dh_param_file,"r")) != NULL)
  1021.             dh_tmp=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
  1022.         if (bio != NULL)
  1023.             BIO_free(bio);
  1024.  
  1025.         if ( dh_tmp == NULL ) {
  1026.             if ( keylength < 768 )
  1027.                 dh_tmp = get_dh512();
  1028.             else if ( keylength < 1024 )
  1029.                 dh_tmp = get_dh768();
  1030.             else if ( keylength < 1536 )
  1031.                 dh_tmp = get_dh1024();
  1032.             else if ( keylength < 2048 )
  1033.                 dh_tmp = get_dh1536();
  1034.             else
  1035.                 dh_tmp = get_dh2048();
  1036.         }
  1037.     }
  1038. #else /* NO_DH */
  1039.     if (ssl_debug_flag)
  1040.         printf("DH not supported...\r\n");
  1041. #endif /* NO_DH */
  1042.     return(dh_tmp);
  1043. }
  1044.  
  1045. static void
  1046. ssl_display_comp(SSL * ssl)
  1047. {
  1048.     if ( quiet )            /* fdc - Mon Nov 28 11:44:15 2005 */
  1049.         return;
  1050.  
  1051.     if ( !ck_ssleay_is_installed() )
  1052.         return;
  1053.  
  1054.     if (ssl == NULL)
  1055.         return;
  1056.  
  1057.     if (ssl->expand == NULL || ssl->expand->meth == NULL)
  1058.         printf("Compression: None\r\n");
  1059.     else {
  1060.         printf("Compression: %s\r\n",ssl->expand->meth->name);
  1061.     }
  1062. }
  1063.  
  1064. int
  1065. #ifdef CK_ANSIC
  1066. ssl_display_connect_details(SSL * ssl_con, int server, int verbose)
  1067. #else /* CK_ANSIC */
  1068. ssl_display_connect_details(ssl_con,server,verbose)
  1069. SSL *ssl_con;
  1070. int server;
  1071. int verbose;
  1072. #endif /* CK_ANSIC */
  1073. {
  1074.     X509 *peer;
  1075.     SSL_CIPHER * cipher;
  1076.     const char *cipher_list;
  1077.     char buf[512]="";
  1078.  
  1079.     if ( quiet )            /* fdc - Mon Nov 28 11:44:15 2005 */
  1080.         return(0);
  1081.  
  1082.     if ( !ck_ssleay_is_installed() )
  1083.         return(0);
  1084.  
  1085.     if ( inserver && !tn_deb )
  1086.         return(0);
  1087.  
  1088.     /* the cipher list *can* be NULL ... useless but it happens! */
  1089.     cipher = SSL_get_current_cipher(ssl_con);
  1090.     cipher_list = SSL_CIPHER_get_name(cipher);
  1091.     SSL_CIPHER_description(cipher,buf,sizeof(buf));
  1092.     if (cipher_list==NULL)
  1093.         cipher_list="<NULL>";
  1094.     printf("[TLS - %s",buf);
  1095.     ssl_display_comp(ssl_con);
  1096.  
  1097.     if ( server ) {
  1098.         cipher_list=SSL_get_shared_ciphers(ssl_con,buf,512);
  1099.         if (cipher_list==NULL)
  1100.             cipher_list="<NULL>";
  1101.         printf("[TLS - shared ciphers=%s]\r\n",
  1102.                 cipher_list);
  1103.         }       
  1104.     if ( server || tn_deb ) {
  1105.         peer=SSL_get_peer_certificate(ssl_con);
  1106.         if (peer != NULL) {
  1107.             X509_NAME_oneline(X509_get_subject_name(peer),buf,512);
  1108.             printf("[TLS - subject=%s]\r\n",buf);
  1109.             X509_NAME_oneline(X509_get_issuer_name(peer),buf,512);
  1110.             printf("[TLS - issuer=%s]\r\n",buf);
  1111.             /* X509_free(peer); */
  1112.         } else if (!tls_is_krb5(0)) {
  1113.             if ( !sstelnet && !tcp_incoming ) {
  1114.                 printf("[TLS - No certificate provided.]\r\n");
  1115.                 printf(
  1116.      "[TLS - The identity of the host could not be verified.]\r\n");
  1117.             }
  1118.         }
  1119.     }
  1120.     return(0);
  1121. }
  1122.  
  1123. /*
  1124.  * Use SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void * userdata)
  1125.  * to set the value of the userdata.  We are going to use it to store the
  1126.  * prompt.
  1127.  */
  1128.  
  1129. int
  1130. #ifdef CK_ANSIC
  1131. ssl_passwd_callback(char *buf, int len, int rwflag, VOID * userdata)
  1132. #else /* CK_ANSIC */
  1133. ssl_passwd_callback(buf,len,rwflag,userdata)
  1134.     char * buf; int len; int rwflag; VOID *userdata;
  1135. #endif /* CK_ANSIC */
  1136. {
  1137.     extern char pwbuf[];
  1138.     extern int  pwflg, pwcrypt;
  1139.     int   ok;
  1140.     char *prompt=NULL;
  1141.  
  1142.     if ( pwbuf[0] && pwflg ) {
  1143.         int n;
  1144.         n = ckstrncpy(buf,pwbuf,len);
  1145. #ifdef OS2
  1146.         if ( pwcrypt )
  1147.             ck_encrypt((char *)buf);
  1148. #endif /* OS2 */
  1149.         return(n);
  1150.     }
  1151.  
  1152.     if ( userdata == NULL )
  1153.         prompt="Enter certificate passphrase: ";
  1154.     else
  1155.         prompt=(char*)userdata;
  1156.     ok = uq_txt(NULL,prompt,2,NULL,buf,len,NULL,DEFAULT_UQ_TIMEOUT);
  1157.     return(ok > 0 ? strlen(buf) : 0);
  1158. }
  1159.  
  1160.  
  1161. /* Attempts to load certificate data into the TLS context structures */
  1162. /* Returns 1 on success; 0 on failure */
  1163. int
  1164. tls_load_certs(SSL_CTX * ctx, SSL * con, int server)
  1165. {
  1166.     int rc = 1;
  1167.  
  1168.     if ( !ck_ssleay_is_installed() )
  1169.         return(0);
  1170.  
  1171.     debug(F110,"tls_load_certs","SSL_CTX",0);
  1172.     debug(F110,"tls_load_certs","SSL",0);
  1173.     debug(F110,"tls_load_certs","server",0);
  1174.  
  1175.     if ( con ) {
  1176.         if (ssl_rsa_cert_file) {
  1177.             if ( ssl_debug_flag )
  1178.                 printf("Loading RSA certificate into SSL\r\n");
  1179.  
  1180.             rc = SSL_use_certificate_file(con, ssl_rsa_cert_file,
  1181.                                                X509_FILETYPE_PEM);
  1182.             if (!rc)
  1183.             {
  1184.                 if ( !quiet || ssl_debug_flag )
  1185.                     printf("Error loading certificate from %s\r\n",
  1186.                             ssl_rsa_cert_file);
  1187.             } else {
  1188.                 if (!ssl_rsa_key_file || !ssl_rsa_key_file[0])
  1189.                     makestr(&ssl_rsa_key_file,ssl_rsa_cert_file);
  1190.  
  1191.                 rc = SSL_use_PrivateKey_file(con, ssl_rsa_key_file,
  1192.                                                   X509_FILETYPE_PEM);
  1193.                 if (!rc)
  1194.                     rc = SSL_use_PrivateKey_file(con, ssl_rsa_cert_file,
  1195.                                                       X509_FILETYPE_PEM);
  1196.                 if (!rc)
  1197.                 {
  1198.                     if ( !quiet || ssl_debug_flag )
  1199.                         printf("Error loading key from %s\r\n",
  1200.                                 ssl_rsa_key_file);
  1201.                 } else {
  1202.                     rc = SSL_check_private_key(con);
  1203.                     if (!rc)
  1204.                     {
  1205.                         if ( ssl_debug_flag )
  1206.                             printf(
  1207.                 "Private key does not match the certificate public key\r\n");
  1208.                     }
  1209.                 }
  1210.             }
  1211.         }
  1212.  
  1213.         if (ssl_dsa_cert_file) {
  1214.             if ( ssl_debug_flag )
  1215.                 printf("Loading DSA certificate into SSL\r\n");
  1216.  
  1217.             rc = SSL_use_certificate_file(con, ssl_dsa_cert_file,
  1218.                                                X509_FILETYPE_PEM);
  1219.             if (!rc)
  1220.             {
  1221.                 if ( ssl_debug_flag ) {
  1222.                     printf("Error loading certificate from %s\r\n",
  1223.                             ssl_dsa_cert_file);
  1224.                 }
  1225.             } else {
  1226.                 if (!ssl_dh_key_file || !ssl_dh_key_file[0])
  1227.                     makestr(&ssl_dh_key_file,ssl_dsa_cert_file);
  1228.                 rc = SSL_use_PrivateKey_file(con, ssl_dh_key_file,
  1229.                                                   X509_FILETYPE_PEM);
  1230.                 if (!rc)
  1231.                     rc = SSL_use_PrivateKey_file(con, ssl_dsa_cert_file,
  1232.                                                       X509_FILETYPE_PEM);
  1233.                 if (!rc)
  1234.                 {
  1235.                     if ( !quiet || ssl_debug_flag ) {
  1236.                         printf("Error loading key from %s\r\n",
  1237.                                 ssl_dh_key_file);
  1238.                     }
  1239.                 } else {
  1240.                     rc = SSL_check_private_key(con);
  1241.                     if (!rc)
  1242.                     {
  1243.                         if ( ssl_debug_flag )
  1244.                             printf(
  1245.                    "Private key does not match the certificate public key\n");
  1246.                     }
  1247.                 }
  1248.             }
  1249.         }
  1250.     } else {
  1251.         if (ssl_rsa_cert_file) {
  1252.             if ( ssl_debug_flag )
  1253.                 printf("Loading RSA certificate into SSL\r\n");
  1254.  
  1255.             rc = SSL_CTX_use_certificate_file(ctx, ssl_rsa_cert_file,
  1256.                                        X509_FILETYPE_PEM);
  1257.             if (!rc)
  1258.             {
  1259.                 if ( !quiet || ssl_debug_flag )
  1260.                     printf("Error loading certificate from %s\r\n",
  1261.                             ssl_rsa_cert_file);
  1262.             } else {
  1263.                 if (!ssl_rsa_key_file || !ssl_rsa_key_file[0])
  1264.                     makestr(&ssl_rsa_key_file,ssl_rsa_cert_file);
  1265.  
  1266.                 rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_rsa_key_file,
  1267.                                                   X509_FILETYPE_PEM);
  1268.                 if (!rc)
  1269.                   rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_rsa_cert_file,
  1270.                                                    X509_FILETYPE_PEM);
  1271.                 if (!rc) {
  1272.                     if ( ssl_debug_flag )
  1273.                       printf("Error loading key from %s\r\n",ssl_rsa_key_file);
  1274.                 } else {
  1275.                     rc = SSL_CTX_check_private_key(ctx);
  1276.                     if (!rc) {
  1277.                         if ( ssl_debug_flag )
  1278.                           printf(
  1279.                 "Private key does not match the certificate public key\r\n");
  1280.                     }
  1281.                 }
  1282.             }
  1283.         }
  1284.         if (ssl_dsa_cert_file) {
  1285.             if ( ssl_debug_flag )
  1286.               printf("Loading DSA certificate into SSL\r\n");
  1287.  
  1288.             rc = SSL_CTX_use_certificate_file(ctx, ssl_dsa_cert_file,
  1289.                                               X509_FILETYPE_PEM);
  1290.             if (!rc) {
  1291.                 if ( ssl_debug_flag ) {
  1292.                     printf("Error loading certificate from %s\r\n",
  1293.                            ssl_dsa_cert_file);
  1294.                 }
  1295.             } else {
  1296.                 if (!ssl_dh_key_file || !ssl_dh_key_file[0])
  1297.                     makestr(&ssl_dh_key_file,ssl_dsa_cert_file);
  1298.                 rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_dh_key_file,
  1299.                                                   X509_FILETYPE_PEM);
  1300.                 if (!rc)
  1301.                   rc = SSL_CTX_use_PrivateKey_file(ctx, ssl_dsa_cert_file,
  1302.                                                       X509_FILETYPE_PEM);
  1303.                 if (!rc) {
  1304.                     if ( ssl_debug_flag )
  1305.                       printf("Error loading key from %s\r\n",ssl_dh_key_file);
  1306.                 } else {
  1307.                     rc = SSL_CTX_check_private_key(ctx);
  1308.                     if (!rc) {
  1309.                         if ( ssl_debug_flag )
  1310.                           printf(
  1311.                    "Private key does not match the certificate public key\n");
  1312.                     }
  1313.                 }
  1314.             }
  1315.         }
  1316.     }
  1317.  
  1318.     if (ssl_rsa_cert_chain_file && server) {
  1319.         int skip1st = 0;
  1320.         if (ssl_debug_flag)
  1321.             printf("Loading RSA Certificate Chain into SSL\r\n");
  1322.         if (!ckstrcmp(ssl_rsa_cert_chain_file,ssl_rsa_cert_file,-1,
  1323. #ifdef OS2
  1324.                        0
  1325. #else
  1326.                        1
  1327. #endif /* OS2 */
  1328.                        ))
  1329.             skip1st = 1;
  1330.         rc = SSL_CTX_use_certificate_chain_file(ctx,ssl_rsa_cert_chain_file);
  1331.         if (!rc && ssl_debug_flag)
  1332.                 printf("Error loading RSA Certificate Chain into SSL\r\n");
  1333.     }
  1334.     if (ssl_dsa_cert_chain_file && server) {
  1335.         int skip1st = 0;
  1336.         if (ssl_debug_flag)
  1337.             printf("Loading DSA Certificate Chain into SSL\r\n");
  1338.         if (!ckstrcmp(ssl_dsa_cert_chain_file,ssl_dsa_cert_file,-1,
  1339. #ifdef OS2
  1340.                        0
  1341. #else
  1342.                        1
  1343. #endif /* OS2 */
  1344.                        ))
  1345.             skip1st = 1;
  1346.         rc = SSL_CTX_use_certificate_chain_file(ctx,ssl_dsa_cert_chain_file);
  1347.         if (!rc && ssl_debug_flag)
  1348.                 printf("Error loading DSA Certificate Chain into SSL\r\n");
  1349.     }
  1350.     return(rc);
  1351. }
  1352.  
  1353. VOID
  1354. #ifdef CK_ANSIC
  1355. ssl_once_init(void)
  1356. #else
  1357. ssl_once_init()
  1358. #endif /* CK_ANSIC */
  1359. {
  1360.     COMP_METHOD * cm;
  1361.     char * s;
  1362.  
  1363.     if ( !ck_ssleay_is_installed() )
  1364.         return;
  1365. /*
  1366.   OpenSSL does not provide for ABI compatibility between releases prior
  1367.   to version 1.0.0.  If the version does not match, it is not safe to
  1368.   assume that any function you call takes the same parameters or does
  1369.   the same thing with them.  Removing this test prior to the OpenSSL 1.0.0
  1370.   release will result in an increase in unexplained or incorrect behaviors.
  1371.   The test should be revised once OpenSSL 1.0.0 is released and we see what
  1372.   its claims are as to ABI compatibility.
  1373. */
  1374.     debug(F111,"Kermit built for OpenSSL",OPENSSL_VERSION_TEXT,SSLEAY_VERSION_NUMBER);
  1375. #ifndef OS2ONLY
  1376.     debug(F111,"OpenSSL Library",SSLeay_version(SSLEAY_VERSION),
  1377.            SSLeay());
  1378.     debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_BUILT_ON),0);
  1379.     debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_CFLAGS),0);
  1380.     debug(F110,"OpenSSL Library",SSLeay_version(SSLEAY_PLATFORM),0);
  1381.  
  1382.     /* The following test is suggested by Richard Levitte */
  1383.     if (((OPENSSL_VERSION_NUMBER ^ SSLeay()) & 0xffffff0f) 
  1384. #ifdef OS2
  1385.          || ckstrcmp(OPENSSL_VERSION_TEXT,(char *)SSLeay_version(SSLEAY_VERSION),-1,1)
  1386. #endif /* OS2 */
  1387.          ) {
  1388.         ssl_installed = 0;
  1389.         debug(F111,"OpenSSL Version does not match.  Built with",
  1390.                SSLeay_version(SSLEAY_VERSION),SSLEAY_VERSION_NUMBER);
  1391.         printf("?OpenSSL libraries do not match required version:\r\n");
  1392.         printf("  . C-Kermit built with %s\r\n",OPENSSL_VERSION_TEXT);
  1393.         printf("  . Version found  %s\r\n",SSLeay_version(SSLEAY_VERSION));
  1394.         printf("  OpenSSL versions prior to 1.0.0 must be the same.\r\n");    
  1395.  
  1396.     s = "R";
  1397. #ifdef SOLARIS
  1398.     printf("  Set CD_LIBRARY_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
  1399.     s = " Or r";
  1400. #endif    /* SOLARIS */
  1401.  
  1402. #ifdef HPUX
  1403.     printf("  Set SHLIB_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
  1404.     s = " Or r";
  1405. #endif    /* HPUX */
  1406.  
  1407. #ifdef AIX
  1408.     printf("  Set LIBPATH for %s.\r\n",OPENSSL_VERSION_TEXT);
  1409.     s = " Or r";
  1410. #endif    /* AIX */
  1411.  
  1412. #ifdef LINUX
  1413.     printf("  Set LD_LIBRARY_PATH for %s.\r\n",OPENSSL_VERSION_TEXT);
  1414.     s = " Or r";
  1415. #endif    /* LINUX */
  1416.  
  1417.         printf(" %sebuild C-Kermit from source on this computer to make \
  1418. versions agree.\r\n",s);
  1419.  
  1420. #ifdef KTARGET
  1421.     {
  1422.         char * s;
  1423.         s = KTARGET;
  1424.         if (!s) s = "";
  1425.         if (!*s) s = "(unknown)";
  1426.         printf("  C-Kermit makefile target: %s\r\n",s);
  1427.     }
  1428. #endif    /* KTARGET */
  1429.         printf("  Or if that is what you did then try to find out why\r\n");
  1430.         printf("  the program loader (image activator) is choosing a\r\n");
  1431.         printf("  different OpenSSL library than the one specified in \
  1432. the build.\r\n\r\n");
  1433.         printf("  All SSL/TLS features disabled.\r\n\r\n");
  1434.         bleep(BP_FAIL);
  1435. #ifdef SSLDLL
  1436.         ck_ssl_unloaddll();
  1437.         ck_crypto_unloaddll();
  1438. #endif /* SSLDLL */
  1439.         return;
  1440.     }
  1441. #endif /* OS2ONLY */
  1442.  
  1443.     /* init things so we will get meaningful error messages
  1444.      * rather than numbers
  1445.      */
  1446.     SSL_load_error_strings();
  1447.  
  1448. #ifdef SSHBUILTIN
  1449.     OPENSSL_add_all_algorithms_noconf();
  1450. #else
  1451.     /* SSL_library_init() only loads those ciphers needs for SSL  */
  1452.     /* These happen to be a similar set to those required for SSH */
  1453.     /* but they are not a complete set of ciphers provided by the */
  1454.     /* crypto library.                                            */
  1455.     SSL_library_init();
  1456. #endif /* SSHBUILTIN */
  1457.  
  1458. #ifdef ZLIB
  1459.     cm = COMP_zlib();
  1460.     if (cm != NULL && cm->type != NID_undef) {
  1461.         SSL_COMP_add_compression_method(0xe0, cm); /* EAY's ZLIB ID */
  1462.     }
  1463. #endif /* ZLIB */
  1464.     cm = COMP_rle();
  1465.     if (cm != NULL && cm->type != NID_undef)
  1466.         SSL_COMP_add_compression_method(0xe1, cm); /* EAY's RLE ID */
  1467.  
  1468.     /* Ensure the Random number generator has enough entropy */
  1469.     if ( !RAND_status() ) {
  1470.         char buffer[256]="";
  1471.         char randombytes[256];
  1472.         int rc1 = -1, rc2 = 1;  /* assume failure and success */
  1473.  
  1474.         debug(F110,"ssl_once_init","!RAND_status()",0);
  1475.  
  1476.         if ( ssl_rnd_file == NULL ) {
  1477.             debug(F110,"ssl_rnd_file","ssl_rnd_file is NULL",0);
  1478.             RAND_file_name(buffer,256);
  1479.             if ( buffer[0] )
  1480.                 makestr(&ssl_rnd_file, buffer);
  1481.             else
  1482.                 makestr(&ssl_rnd_file,".rnd");
  1483.         }
  1484.         debug(F110,"ssl_rnd_file",ssl_rnd_file,0);
  1485.  
  1486.         rc1 = RAND_egd(ssl_rnd_file);
  1487.         debug(F111,"ssl_once_init","RAND_egd()",rc1);
  1488.         if ( rc1 <= 0 ) {
  1489.             rc2 = RAND_load_file(ssl_rnd_file, -1);
  1490.             debug(F111,"ssl_once_init","RAND_load_file()",rc1);
  1491.         }
  1492.  
  1493.         if ( rc1 <= 0 && !rc2 )
  1494.         {
  1495.             time_t t = time(NULL);
  1496.             int tlen = sizeof(time_t);
  1497.             int pid = getpid();
  1498.             int plen = sizeof(int);
  1499.             int n;
  1500. #ifndef RAND_MAX
  1501. #define RAND_MAX 0x7FFF
  1502. #endif
  1503.             debug(F110,"ssl_once_init","calling RAND_seed()",0);
  1504.  
  1505.             RAND_seed((unsigned char *)&t, tlen);
  1506.             RAND_seed((unsigned char *)&pid, plen);
  1507.  
  1508.             srand((unsigned int)t);
  1509.             sprintf(buffer, "%.0f", (((double)(rand()%RAND_MAX)/RAND_MAX)*
  1510.                                       (sizeof(randombytes)-128-1)));
  1511.             n = (atoi(buffer)+1)%(sizeof(randombytes)-128-1);
  1512.             RAND_seed(randombytes, 128);
  1513.         }
  1514.  
  1515.         if ( !RAND_status() ) {
  1516.             debug(F110,"ssl_once_init","Unable to initialize PRNG",0);
  1517.             printf(" Unable to load 'random state'\n");
  1518.             printf(" SSL and TLS are unavailble.\n");
  1519.             printf(" Use SET AUTH SSL RANDOM-FILE <file> command to provide random data.\n");
  1520.             printf(" Specified file will be overwritten with new random data after use.\n");
  1521.             return;
  1522.         }
  1523.  
  1524.         if ( ssl_rnd_file ) {
  1525.             int rc = RAND_write_file(ssl_rnd_file);
  1526.             debug(F111,"ssl_once_init","RAND_write_file()",rc);
  1527.         }
  1528.     }
  1529.  
  1530. #ifdef NT
  1531.     // Initialize additional OID types for use when saving certs to a file
  1532.     OBJ_create("2.99999.3","SET.ex3","SET x509v3 extension 3");
  1533. #endif /* NT */
  1534.  
  1535.     /* make sure we have somewhere we can log errors to */
  1536.     bio_err=BIO_new(BIO_s_mem());
  1537.  
  1538.     debug(F100,"ssl_once_init() complete","",0);
  1539. }
  1540.  
  1541. int
  1542. #ifdef CK_ANSIC
  1543. ssl_tn_init(int mode)
  1544. #else
  1545. ssl_tn_init(mode) int mode;
  1546. #endif /* CK_ANSIC */
  1547. {
  1548. #ifdef KRB5
  1549.     extern char * k5_keytab;
  1550.     extern char * krb5_d_srv;
  1551. #endif /* KRB5 */
  1552.     static int last_ssl_mode = -1;
  1553.     SSL * ssl_conx=NULL, * tls_conx=NULL;
  1554.  
  1555.     ssl_initialized = 0;
  1556.  
  1557.     if ( !ck_ssleay_is_installed() )
  1558.         return(0);
  1559.  
  1560.     debug(F111,"ssl_tn_init","mode",mode);
  1561.  
  1562.     if (ssl_debug_flag)
  1563.         printf("SSL_DEBUG_FLAG on\r\n");
  1564.  
  1565.     if (last_ssl_mode != mode) {
  1566.         if (ssl_ctx) {
  1567.             SSL_CTX_free(ssl_ctx);
  1568.             ssl_ctx = NULL;
  1569.         }
  1570.         if (tls_ctx) {
  1571.             SSL_CTX_free(tls_ctx);
  1572.             tls_ctx = NULL;
  1573.         }
  1574.     }
  1575.  
  1576.     if ( (last_ssl_mode != mode) || !ssl_ctx || !tls_ctx ) {
  1577.         if ( mode == SSL_CLIENT ) {
  1578.             ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
  1579.             /* This can fail because we do not have RSA available */
  1580.             if ( !ssl_ctx ) {
  1581.                 debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
  1582.                 ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
  1583.             }
  1584.             if ( !ssl_ctx ) {
  1585.                 debug(F110,"ssl_tn_init","SSLv3_client_method failed",0);
  1586.                 last_ssl_mode = -1;
  1587.                 return(0);
  1588.             }
  1589. #ifndef COMMENT
  1590.             tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
  1591. #else /* COMMENT */
  1592.             tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
  1593.             /* This can fail because we do not have RSA available */
  1594.             if ( !tls_ctx ) {
  1595.                 debug(F110,"ssl_tn_init","SSLv23_client_method failed",0);
  1596.                 tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
  1597.             }
  1598. #endif /* COMMENT */
  1599.             if ( !tls_ctx ) {
  1600.                 debug(F110,"ssl_tn_init","TLSv1_client_method failed",0);
  1601.                 last_ssl_mode = -1;
  1602.                 return(0);
  1603.             }
  1604. #ifdef USE_CERT_CB
  1605.             SSL_CTX_set_client_cert_cb(ssl_ctx,ssl_client_cert_callback);
  1606.             SSL_CTX_set_client_cert_cb(tls_ctx,ssl_client_cert_callback);
  1607. #endif /* USE_CERT_CB */
  1608.         } else if (mode == SSL_SERVER) {
  1609.             /* We are a server */
  1610.             ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_server_method());
  1611.             /* This can fail because we do not have RSA available */
  1612.             if ( !ssl_ctx ) {
  1613.                 debug(F110,"ssl_tn_init","SSLv23_server_method failed",0);
  1614.                 ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_server_method());
  1615.             }
  1616.             if ( !ssl_ctx ) {
  1617.                 debug(F110,"ssl_tn_init","SSLv3_server_method failed",0);
  1618.                 last_ssl_mode = -1;
  1619.                 return(0);
  1620.             }
  1621. #ifdef COMMENT
  1622.             tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_server_method());
  1623. #else /* COMMENT */
  1624.             tls_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_server_method());
  1625.             /* This can fail because we do not have RSA available */
  1626.             if ( !tls_ctx ) {
  1627.                 debug(F110,"ssl_tn_init","SSLv23_server_method failed",0);
  1628.                 tls_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_server_method());
  1629.             }
  1630. #endif /* COMMENT */
  1631.             if ( !tls_ctx ) {
  1632.                 debug(F110,"ssl_tn_init","TLSv1_server_method failed",0);
  1633.                 last_ssl_mode = -1;
  1634.                 return(0);
  1635.             }
  1636.         } else /* Unknown mode */
  1637.             return(0);
  1638.  
  1639.         if ( !inserver ) {
  1640.             SSL_CTX_set_default_passwd_cb(ssl_ctx,
  1641.                                    (pem_password_cb *)ssl_passwd_callback);
  1642.             SSL_CTX_set_default_passwd_cb(tls_ctx,
  1643.                                    (pem_password_cb *)ssl_passwd_callback);
  1644.         }
  1645.  
  1646.         /* for SSL switch on all the interoperability and bug
  1647.          * workarounds so that we will communicate with people
  1648.          * that cannot read poorly written specs :-)
  1649.          * for TLS be sure to prevent use of SSLv2
  1650.          */
  1651.         SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL|SSL_OP_NO_SSLv2);
  1652.         SSL_CTX_set_options(tls_ctx,
  1653.                  SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
  1654.  
  1655.         SSL_CTX_set_info_callback(ssl_ctx,ssl_client_info_callback);
  1656.         SSL_CTX_set_info_callback(tls_ctx,ssl_client_info_callback);
  1657.  
  1658. #ifndef COMMENT
  1659.         /* Set the proper caching mode */
  1660.         if ( mode == SSL_SERVER ) {
  1661.             SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_SERVER);
  1662.             SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_SERVER);
  1663.         } else {
  1664.             SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_CLIENT);
  1665.             SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_CLIENT);
  1666.         }
  1667.         SSL_CTX_set_session_id_context(ssl_ctx,(CHAR *)"1",1);
  1668.         SSL_CTX_set_session_id_context(tls_ctx,(CHAR *)"2",1);
  1669. #else /* COMMENT */
  1670.         SSL_CTX_set_session_cache_mode(ssl_ctx,SSL_SESS_CACHE_OFF);
  1671.         SSL_CTX_set_session_cache_mode(tls_ctx,SSL_SESS_CACHE_OFF);
  1672. #endif /* COMMENT */
  1673.     }
  1674.  
  1675.     /* The server uses defaults for the certificate files. */
  1676.     /* The client does not.                                */
  1677.     if (mode == SSL_SERVER) {
  1678.         char cert_filepath[1024];
  1679.         const char * defdir = NULL;
  1680.         DH * dh = NULL;
  1681.  
  1682.         defdir = getenv("SSL_CERT_DIR");
  1683.         if ( !defdir ) {
  1684. #ifdef OS2
  1685.             defdir = exedir;
  1686. #else /* OS2 */
  1687.             defdir = X509_get_default_cert_dir();
  1688. #endif /* OS2 */
  1689.             debug(F110,"ssl_tn_init - setting default directory to",defdir,0);
  1690.         }
  1691.         if ( !defdir )
  1692.             defdir = "";
  1693.  
  1694.         if (!ssl_rsa_cert_file) {
  1695.             /* we need to know the fullpath to the location of the
  1696.             * certificate that we will be running with as we cannot
  1697.             * be sure of the cwd when we are launched
  1698.             */
  1699.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-rsa.pem");
  1700.             if (zchki(cert_filepath) > 0)
  1701.                 makestr(&ssl_rsa_cert_file,cert_filepath);
  1702.         }
  1703.         if (ssl_rsa_cert_file && !ssl_rsa_key_file) {
  1704.             /* we need to know the fullpath to the location of the
  1705.             * certificate that we will be running with as we cannot
  1706.             * be sure of the cwd when we are launched
  1707.             */
  1708.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-rsa-key.pem");
  1709.             if (zchki(cert_filepath) > 0)
  1710.                 makestr(&ssl_rsa_key_file,cert_filepath);
  1711.         }
  1712.         if (!ssl_dsa_cert_file) {
  1713.             /* we need to know the fullpath to the location of the
  1714.             * certificate that we will be running with as we cannot
  1715.             * be sure of the cwd when we are launched
  1716.             */
  1717.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-dsa.pem");
  1718.             if (zchki(cert_filepath) > 0)
  1719.                 makestr(&ssl_dsa_cert_file,cert_filepath);
  1720.         }
  1721.         if (ssl_dsa_cert_file && !ssl_dh_key_file) {
  1722.             /* we need to know the fullpath to the location of the
  1723.             * certificate that we will be running with as we cannot
  1724.             * be sure of the cwd when we are launched
  1725.             */
  1726.             sprintf(cert_filepath,"%s/%s",defdir,"telnetd-dsa-key.pem");
  1727.             if (zchki(cert_filepath) > 0)
  1728.                 makestr(&ssl_dh_key_file,cert_filepath);
  1729.         }
  1730.         if (!ssl_crl_dir) {
  1731.             /* we need to know the fullpath to the location of the
  1732.             * certificate that we will be running with as we cannot
  1733.             * be sure of the cwd when we are launched
  1734.             */
  1735.             sprintf(cert_filepath,"%s/crl",defdir);
  1736.             if (zchki(cert_filepath) > 0)
  1737.                 makestr(&ssl_crl_dir,cert_filepath);
  1738.         }
  1739.  
  1740.         if (ssl_only_flag && !tls_load_certs(ssl_ctx,ssl_con,1)) {
  1741.             debug(F110,"ssl_tn_init","Unable to load SSL certs",0);
  1742.             last_ssl_mode = -1;
  1743.             return(0);
  1744.         }
  1745.         if (tls_only_flag && !tls_load_certs(tls_ctx,tls_con,1)) {
  1746.             debug(F110,"ssl_tn_init","Unable to load TLS certs",0);
  1747.             last_ssl_mode = -1;
  1748.             return(0);
  1749.         }
  1750.  
  1751.         if ( (last_ssl_mode != mode) || !ssl_ctx || !tls_ctx ) {
  1752.             /* we may require a temp 512 bit RSA key because of the
  1753.              * wonderful way export things work ... if so we generate
  1754.              * one now!
  1755.              */
  1756.  
  1757.             SSL_CTX_set_tmp_rsa_callback(ssl_ctx, tmp_rsa_cb);
  1758.             SSL_CTX_set_tmp_dh_callback( ssl_ctx, tmp_dh_cb);
  1759.             SSL_CTX_set_tmp_rsa_callback(tls_ctx, tmp_rsa_cb);
  1760.             SSL_CTX_set_tmp_dh_callback( tls_ctx, tmp_dh_cb);
  1761.  
  1762.             dh = tmp_dh_cb(NULL,0,512);
  1763.             SSL_CTX_set_tmp_dh(ssl_ctx,dh);
  1764.             SSL_CTX_set_tmp_dh(tls_ctx,dh);
  1765.  
  1766.             /* The following code is only called if we are using a
  1767.              * certificate with an RSA public key and where the
  1768.              * certificate has a key length less than 512 bits or is
  1769.              * marked for signing only.  This is so we can support
  1770.              * the greatest legal privacy level with exportable clients.
  1771.              */
  1772.  
  1773.             if (SSL_CTX_need_tmp_RSA(ssl_ctx) ||
  1774.                  SSL_CTX_need_tmp_RSA(tls_ctx))
  1775.             {
  1776.                 RSA *rsa;
  1777.  
  1778.                 if ( ssl_debug_flag )
  1779.                     printf("Generating temp (512 bit) RSA key ...\r\n");
  1780.                 rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
  1781.                 if ( ssl_debug_flag )
  1782.                     printf("Generation of temp (512 bit) RSA key done\r\n");
  1783.  
  1784.                 if (SSL_CTX_need_tmp_RSA(ssl_ctx)) {
  1785.                     if (!SSL_CTX_set_tmp_rsa(ssl_ctx,rsa)) {
  1786.                         if ( ssl_debug_flag )
  1787.                             printf(
  1788.   "Failed to assign generated temp RSA key to SSL!\r\n");
  1789.                     }
  1790.                 }
  1791.                 if (SSL_CTX_need_tmp_RSA(tls_ctx)) {
  1792.                     if (!SSL_CTX_set_tmp_rsa(tls_ctx,rsa)) {
  1793.                         if ( ssl_debug_flag )
  1794.                             printf(
  1795.   "Failed to assign generated temp RSA key to TLS!\r\n");
  1796.                     }
  1797.                 }
  1798.                 RSA_free(rsa);
  1799.                 if ( ssl_debug_flag )
  1800.                     printf("Assigned temp (512 bit) RSA key\r\n");
  1801.             }
  1802.         }
  1803.     }
  1804.  
  1805.     /* make sure we will find certificates in the standard
  1806.      * location ... otherwise we don't look anywhere for
  1807.      * these things which is going to make client certificate
  1808.      * exchange rather useless :-)
  1809.      * In OS2, default values for ssl_verify_file and ssl_verify_path.
  1810.      */
  1811.  
  1812. #ifdef OS2
  1813. #ifdef NT
  1814.     {
  1815.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  1816.         char path[CKMAXPATH];
  1817.  
  1818.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  1819.         if (isdir(path) && 
  1820.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1821.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1822.             if (ssl_debug_flag)
  1823.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1824.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1825.         }
  1826.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/certs",NULL,NULL);
  1827.         if (isdir(path) &&
  1828.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1829.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1830.             if (ssl_debug_flag)
  1831.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1832.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1833.         }
  1834.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs",NULL,NULL);
  1835.         if (isdir(path) &&
  1836.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1837.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1838.             if (ssl_debug_flag)
  1839.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1840.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1841.         }
  1842.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  1843.         if (zchki(path) > 0 && 
  1844.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1845.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1846.             if (ssl_debug_flag)
  1847.                 printf("  Certificate Verification File: %s\r\n",path);
  1848.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1849.         }
  1850.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_certs.pem",NULL,NULL);
  1851.         if (zchki(path) > 0 && 
  1852.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1853.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1854.             if (ssl_debug_flag)
  1855.                 printf("  Certificate Verification File: %s\r\n",path);
  1856.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1857.         }
  1858.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_certs.pem",NULL,NULL);
  1859.         if (zchki(path) > 0 && 
  1860.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1861.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1862.             if (ssl_debug_flag)
  1863.                 printf("  Certificate Verification File: %s\r\n",path);
  1864.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1865.         }
  1866.     }
  1867. #else /* NT */
  1868.     {
  1869.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  1870.         char path[CKMAXPATH];
  1871.  
  1872.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  1873.         if (isdir(path) && 
  1874.             SSL_CTX_load_verify_locations(tls_ctx,NULL,path) == 1)  {
  1875.             debug(F110,"ssl_tn_init certificate verify dir",path,0);
  1876.             if (ssl_debug_flag)
  1877.                 printf("  Certificate Verification Directory: %s\r\n",path);
  1878.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,path);
  1879.         }
  1880.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  1881.         if (zchki(path) > 0 && 
  1882.             SSL_CTX_load_verify_locations(tls_ctx,path,NULL) == 1) {
  1883.             debug(F110,"ssl_tn_init certificate verify file",path,0);
  1884.             if (ssl_debug_flag)
  1885.                 printf("  Certificate Verification File: %s\r\n",path);
  1886.             SSL_CTX_load_verify_locations(ssl_ctx,path,NULL);
  1887.         }
  1888.     }
  1889. #endif /* NT */
  1890. #else /* OS2 */
  1891.     SSL_CTX_set_default_verify_paths(ssl_ctx);
  1892.     SSL_CTX_set_default_verify_paths(tls_ctx);
  1893. #endif /* OS2 */
  1894.  
  1895.     if (ssl_verify_file) {
  1896.         if (zchki(ssl_verify_file) > 0 && 
  1897.             SSL_CTX_load_verify_locations(tls_ctx,ssl_verify_file,NULL) == 1) {
  1898.             debug(F110,"ssl_tn_init certificate verify file",ssl_verify_file,0);
  1899.             if (ssl_debug_flag)
  1900.                 printf("  Certificate Verification File: %s\r\n",ssl_verify_file);
  1901.             SSL_CTX_load_verify_locations(ssl_ctx,ssl_verify_file,NULL);
  1902.         }
  1903.     }
  1904.     if (ssl_verify_dir && isdir(ssl_verify_dir)) {
  1905.         if (SSL_CTX_load_verify_locations(tls_ctx,NULL,ssl_verify_dir) == 1)  {
  1906.             debug(F110,"ssl_tn_init certificate verify dir",ssl_verify_dir,0);
  1907.             if (ssl_debug_flag)
  1908.                 printf("  Certificate Verification Directory: %s\r\n",ssl_verify_dir);
  1909.             SSL_CTX_load_verify_locations(ssl_ctx,NULL,ssl_verify_dir);
  1910.         }
  1911.     }
  1912.     if (mode == SSL_SERVER) {
  1913.         SSL_CTX_set_verify(ssl_ctx,
  1914.                      ssl_verify_flag?ssl_verify_flag|SSL_VERIFY_CLIENT_ONCE:0,
  1915.                            ssl_server_verify_callback);
  1916.         SSL_CTX_set_verify(tls_ctx,
  1917.                      ssl_verify_flag?ssl_verify_flag|SSL_VERIFY_CLIENT_ONCE:0,
  1918.                            ssl_server_verify_callback);
  1919.     } else {
  1920.         SSL_CTX_set_verify(ssl_ctx,ssl_verify_flag,
  1921.                            ssl_client_verify_callback);
  1922.         SSL_CTX_set_verify(tls_ctx,ssl_verify_flag,
  1923.                            ssl_client_verify_callback);
  1924.     }
  1925.  
  1926.     /* Free the existing CRL Store */
  1927.     if (crl_store) {
  1928.         X509_STORE_free(crl_store);
  1929.         crl_store = NULL;
  1930.     }
  1931.  
  1932.     /* set up the new CRL Store */
  1933.     crl_store = X509_STORE_new();
  1934.     if (crl_store) {
  1935. #ifdef OS2
  1936.         char path[CKMAXPATH];
  1937.  
  1938.         ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
  1939.         if (isdir(path) &&
  1940.             X509_STORE_load_locations(crl_store,NULL,path) == 1) {
  1941.             debug(F110,"ssl_tn_init crl dir",path,0);
  1942.             if (ssl_debug_flag)
  1943.                 printf("  CRL Directory: %s\r\n",path);
  1944.         }
  1945. #ifdef NT
  1946.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/crls",NULL,NULL);
  1947.         if (isdir(path) && 
  1948.             X509_STORE_load_locations(crl_store,NULL,path) == 1) {
  1949.             debug(F110,"ssl_tn_init crl dir",path,0);
  1950.             if (ssl_debug_flag)
  1951.                 printf("  CRL Directory: %s\r\n",path);
  1952.         }
  1953.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/crls",NULL,NULL);
  1954.         if (isdir(path) && 
  1955.             X509_STORE_load_locations(crl_store,NULL,path) == 1) {
  1956.             debug(F110,"ssl_tn_init crl dir",path,0);
  1957.             if (ssl_debug_flag)
  1958.                 printf("  CRL Directory: %s\r\n",path);
  1959.         }
  1960. #endif /* NT */
  1961.         
  1962.         ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
  1963.         if (zchki(path) > 0 && 
  1964.             X509_STORE_load_locations(crl_store,path,NULL) == 1) {
  1965.             debug(F110,"ssl_tn_init crl file",path,0);
  1966.             if (ssl_debug_flag)
  1967.                 printf("  CRL File: %s\r\n",path);
  1968.         }
  1969. #ifdef NT
  1970.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_crls.pem",NULL,NULL);
  1971.         if (zchki(path) > 0 && 
  1972.             X509_STORE_load_locations(crl_store,path,NULL) == 1) {
  1973.             debug(F110,"ssl_tn_init crl file",path,0);
  1974.             if (ssl_debug_flag)
  1975.                 printf("  CRL File: %s\r\n",path);
  1976.         }
  1977.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_crls.pem",NULL,NULL);
  1978.         if (zchki(path) > 0 && 
  1979.             X509_STORE_load_locations(crl_store,path,NULL) == 1) {
  1980.             debug(F110,"ssl_tn_init crl file",path,0);
  1981.             if (ssl_debug_flag)
  1982.                 printf("  CRL File: %s\r\n",path);
  1983.         }
  1984. #endif /* NT */
  1985. #endif /* OS2 */
  1986.  
  1987.         if (ssl_crl_file || ssl_crl_dir) {
  1988.             if (ssl_crl_file && zchki(ssl_crl_file) > 0 && 
  1989.                 X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 1) {
  1990.                 debug(F110,"ssl_tn_init crl file",ssl_crl_file,0);
  1991.                 if (ssl_debug_flag)
  1992.                     printf("  CRL File: %s\r\n",ssl_crl_file);
  1993.             }
  1994.             if (ssl_crl_dir && isdir(ssl_crl_dir) &&
  1995.                 X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 1) {
  1996.                 debug(F110,"ssl_tn_init crl dir",ssl_crl_dir,0);
  1997.                 if (ssl_debug_flag)
  1998.                     printf("  CRL Directory: %s\r\n",ssl_crl_dir);
  1999.             }
  2000.         } 
  2001. #ifndef OS2
  2002.         else {
  2003.             X509_STORE_set_default_paths(crl_store);
  2004.         }
  2005. #endif /* OS2 */
  2006.     }
  2007.  
  2008. #ifndef COMMENT
  2009.     ssl_conx = ssl_con;
  2010.     ssl_con=(SSL *)SSL_new(ssl_ctx);
  2011.     if ( !ssl_con ) {
  2012.         debug(F110,"ssl_tn_init","SSL_new(ssl_con) failed",0);
  2013.         last_ssl_mode = -1;
  2014.         ssl_con = ssl_conx;
  2015.         return(0);
  2016.     }
  2017.     if (ssl_conx) {
  2018.         if ( mode == SSL_CLIENT ) {
  2019.             SSL_set_session(ssl_con, SSL_get_session(ssl_conx));
  2020.         }
  2021. #ifdef SSL_KRB5
  2022.         if (ssl_conx->kssl_ctx) {
  2023.             kssl_ctx_free(ssl_conx->kssl_ctx);
  2024.             ssl_conx->kssl_ctx = NULL;
  2025.         }
  2026. #endif /* SSL_KRB5 */
  2027.         SSL_free(ssl_conx);
  2028.         ssl_conx = NULL;
  2029.     }
  2030.     tls_conx = tls_con;
  2031.     tls_con=(SSL *)SSL_new(tls_ctx);
  2032.     if ( !tls_con ) {
  2033.         debug(F110,"ssl_tn_init","SSL_new(tls_con) failed",0);
  2034.         last_ssl_mode = -1;
  2035.         tls_con = tls_conx;
  2036.         return(0);
  2037.     }
  2038.     if (tls_conx) {
  2039.         if ( mode == SSL_CLIENT )
  2040.             SSL_set_session(tls_con, SSL_get_session(tls_conx));
  2041. #ifdef SSL_KRB5
  2042.         if (tls_conx->kssl_ctx) {
  2043.             kssl_ctx_free(tls_conx->kssl_ctx);
  2044.             tls_conx->kssl_ctx = NULL;
  2045.         }
  2046. #endif /* SSL_KRB5 */
  2047.         SSL_free(tls_conx);
  2048.         tls_conx = NULL;
  2049.     }
  2050. #else /* COMMENT */
  2051.     /* I don't know why this does not work to reuse the connection. */
  2052.     if ( ssl_con ) {
  2053.         SSL_clear(ssl_con);
  2054.         SSL_set_session(ssl_con,NULL);
  2055.         SSL_set_accept_state(ssl_con) ;
  2056.     } else {
  2057.         ssl_con=(SSL *)SSL_new(ssl_ctx);
  2058.         if (!ssl_con) {
  2059.             debug(F110,"ssl_tn_init","SSL_new(ssl_ctx) failed",0);
  2060.             last_ssl_mode = -1;
  2061.             ssl_con = ssl_conx;
  2062.             return(0);
  2063.         }
  2064.     }
  2065.  
  2066.     if ( tls_con ) {
  2067.         SSL_clear(tls_con);
  2068.         SSL_set_session(tls_con,NULL);
  2069.         SSL_set_accept_state(tls_con) ;
  2070.     } else {
  2071.         tls_con=(SSL *)SSL_new(tls_ctx);
  2072.         if ( !tls_con ) {
  2073.             debug(F110,"ssl_tn_init","SSL_new(tls_ctx) failed",0);
  2074.             last_ssl_mode = -1;
  2075.             tls_con = tls_conx;
  2076.             return(0);
  2077.         }
  2078.     }
  2079. #endif /* COMMENT */
  2080.  
  2081. #ifdef SSL_KRB5
  2082. #ifndef KRB5_SERVICE_NAME
  2083. #define KRB5_SERVICE_NAME    "host"
  2084. #endif
  2085.  
  2086.     if (ssl_con->kssl_ctx == NULL)
  2087.         ssl_con->kssl_ctx = kssl_ctx_new();
  2088.     if (tls_con->kssl_ctx == NULL)
  2089.     tls_con->kssl_ctx = kssl_ctx_new();
  2090.     if (mode == SSL_SERVER) {
  2091.         if (ssl_con->kssl_ctx != NULL)
  2092.             kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_KEYTAB, k5_keytab);
  2093.         if (tls_con->kssl_ctx != NULL)
  2094.             kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_KEYTAB, k5_keytab);
  2095.     } else {
  2096.         if (ssl_con->kssl_ctx != NULL)
  2097.             kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_SERVER, szHostName);
  2098.         if (tls_con->kssl_ctx != NULL)
  2099.             kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_SERVER, szHostName);
  2100.     }
  2101.     kssl_ctx_setstring(ssl_con->kssl_ctx, KSSL_SERVICE,
  2102.                         krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
  2103.     kssl_ctx_setstring(tls_con->kssl_ctx, KSSL_SERVICE,
  2104.                         krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
  2105. #endif /* SSL_KRB5 */
  2106.  
  2107.     if (ssl_cipher_list) {
  2108.         SSL_set_cipher_list(ssl_con,ssl_cipher_list);
  2109.         SSL_set_cipher_list(tls_con,ssl_cipher_list);
  2110.     } else {
  2111.         char * p;
  2112.         if (p = getenv("SSL_CIPHER")) {
  2113.             SSL_set_cipher_list(ssl_con,p);
  2114.             SSL_set_cipher_list(tls_con,p);
  2115.         } else {
  2116.             SSL_set_cipher_list(ssl_con,DEFAULT_CIPHER_LIST);
  2117.             SSL_set_cipher_list(tls_con,DEFAULT_CIPHER_LIST);
  2118.         }
  2119.     }
  2120.  
  2121.     ssl_verify_depth = -1;
  2122.  
  2123.     if ( ssl_debug_flag )
  2124.         printf("SSL/TLS init done!\r\n");
  2125.  
  2126.     ssl_initialized = 1;
  2127.     last_ssl_mode = mode;
  2128.     debug(F110,"ssl_tn_init","done",0);
  2129.     return(1);
  2130. }
  2131.  
  2132. #ifndef NOHTTP
  2133. int
  2134. #ifdef CK_ANSIC
  2135. ssl_http_init(char * hostname)
  2136. #else
  2137. ssl_http_init(hostname) char * hostname;
  2138. #endif /* CK_ANSIC */
  2139. {
  2140. #ifdef KRB5
  2141.     extern char * k5_keytab;
  2142.     extern char * krb5_d_srv;
  2143. #endif /* KRB5 */
  2144.     SSL * tls_conx=NULL;
  2145.  
  2146.     ssl_http_initialized = 0;
  2147.  
  2148.     if ( !ck_ssleay_is_installed() )
  2149.         return(0);
  2150.     debug(F110,"ssl_http_init",hostname,0);
  2151.  
  2152.     if (ssl_debug_flag)
  2153.         printf("SSL_DEBUG_FLAG on\r\n");
  2154.  
  2155.     if (!tls_http_ctx ) {
  2156. #ifdef COMMENT
  2157.         /* too many web servers still do not support TLSv1 */
  2158.         tls_http_ctx=(SSL_CTX *)SSL_CTX_new(TLSv1_client_method());
  2159. #else /* COMMENT */
  2160.         tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_client_method());
  2161.         /* This can fail because we do not have RSA available */
  2162.         if ( !tls_http_ctx ) {
  2163.             debug(F110,"ssl_http_init","SSLv23_client_method failed",0);
  2164.             tls_http_ctx=(SSL_CTX *)SSL_CTX_new(SSLv3_client_method());
  2165.         }
  2166. #endif /* COMMENT */
  2167.         if ( !tls_http_ctx ) {
  2168.             debug(F110,"ssl_http_init","TLSv1_client_method failed",0);
  2169.             return(0);
  2170.         }
  2171. #ifdef USE_CERT_CB
  2172.         SSL_CTX_set_client_cert_cb(tls_http_ctx,ssl_client_cert_callback);
  2173. #endif /* USE_CERT_CB */
  2174.     }
  2175.  
  2176.     SSL_CTX_set_default_passwd_cb(tls_http_ctx,
  2177.                                   (pem_password_cb *)ssl_passwd_callback);
  2178.  
  2179.     /* for SSL switch on all the interoperability and bug
  2180.      * workarounds so that we will communicate with people
  2181.      * that cannot read poorly written specs :-)
  2182.      * for TLS be sure to prevent use of SSLv2
  2183.      */
  2184.     SSL_CTX_set_options(tls_http_ctx,
  2185.             SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA);
  2186.  
  2187.     SSL_CTX_set_info_callback(tls_http_ctx,ssl_client_info_callback);
  2188.  
  2189. #ifndef COMMENT
  2190.     SSL_CTX_set_session_cache_mode(tls_http_ctx,SSL_SESS_CACHE_CLIENT);
  2191.     SSL_CTX_set_session_id_context(tls_http_ctx,(CHAR *)"3",1);
  2192. #else /* COMMENT */
  2193.     SSL_CTX_set_session_cache_mode(tls_http_ctx,SSL_SESS_CACHE_OFF);
  2194. #endif /* COMMENT */
  2195.  
  2196.     /* make sure we will find certificates in the standard
  2197.      * location ... otherwise we don't look anywhere for
  2198.      * these things which is going to make client certificate
  2199.      * exchange rather useless :-)
  2200.      */
  2201.  
  2202. #ifdef OS2
  2203. #ifdef NT
  2204.     {
  2205.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  2206.         char path[CKMAXPATH];
  2207.  
  2208.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  2209.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2210.             debug(F110,"ssl_http_init unable to load path",path,0);
  2211.             if (ssl_debug_flag)
  2212.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2213.         }
  2214.  
  2215.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/certs",NULL,NULL);
  2216.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2217.             debug(F110,"ssl_http_init unable to load path",path,0);
  2218.             if (ssl_debug_flag)
  2219.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2220.         }
  2221.  
  2222.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs",NULL,NULL);
  2223.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2224.             debug(F110,"ssl_http_init unable to load path",path,0);
  2225.             if (ssl_debug_flag)
  2226.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2227.         }
  2228.  
  2229.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  2230.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2231.             debug(F110,"ssl_http_init unable to load path",path,0);
  2232.             if (ssl_debug_flag)
  2233.                 printf("?Unable to load verify-file: %s\r\n",path);
  2234.         }
  2235.  
  2236.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_certs.pem",NULL,NULL);
  2237.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2238.             debug(F110,"ssl_http_init unable to load path",path,0);
  2239.             if (ssl_debug_flag)
  2240.                 printf("?Unable to load verify-file: %s\r\n",path);
  2241.         }
  2242.  
  2243.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_certs.pem",NULL,NULL);
  2244.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2245.             debug(F110,"ssl_http_init unable to load path",path,0);
  2246.             if (ssl_debug_flag)
  2247.                 printf("?Unable to load verify-file: %s\r\n",path);
  2248.         }
  2249.     }
  2250. #else /* NT */
  2251.     {
  2252.         /* The defaults in the SSL crypto library are not appropriate for OS/2 */
  2253.         char path[CKMAXPATH];
  2254.  
  2255.         ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
  2256.         if (SSL_CTX_load_verify_locations(tls_http_ctx,NULL,path) == 0)  {
  2257.             debug(F110,"ssl_http_init unable to load path",path,0);
  2258.             if (ssl_debug_flag)
  2259.                 printf("?Unable to load verify-dir: %s\r\n",path);
  2260.         }
  2261.         ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
  2262.         if (SSL_CTX_load_verify_locations(tls_http_ctx,path,NULL) == 0) {
  2263.             debug(F110,"ssl_http_init unable to load path",path,0);
  2264.             if (ssl_debug_flag)
  2265.                 printf("?Unable to load verify-file: %s\r\n",path);
  2266.         }
  2267.     }
  2268. #endif /* NT */
  2269. #else /* OS2 */
  2270.     SSL_CTX_set_default_verify_paths(tls_http_ctx);
  2271. #endif /* OS2 */
  2272.  
  2273.     if (ssl_verify_file &&
  2274.         SSL_CTX_load_verify_locations(tls_http_ctx,ssl_verify_file,NULL) == 0)  {
  2275.         debug(F110,"ssl_http_init unable to load ssl_verify_file",ssl_verify_file,0);
  2276.         if (ssl_debug_flag)
  2277.             printf("?Unable to load verify-file: %s\r\n",ssl_verify_file);
  2278.     }
  2279.     if (ssl_verify_dir &&
  2280.         SSL_CTX_load_verify_locations(tls_http_ctx,NULL,ssl_verify_dir) == 0)  {
  2281.         debug(F110,"ssl_http_init unable to load ssl_verify_dir",ssl_verify_dir,0);
  2282.         if (ssl_debug_flag)
  2283.             printf("?Unable to load verify-dir: %s\r\n",ssl_verify_dir);
  2284.     }
  2285.  
  2286.     SSL_CTX_set_verify(tls_http_ctx,ssl_verify_flag,
  2287.                            ssl_client_verify_callback);
  2288.  
  2289.     /* Free the existing CRL Store */
  2290.     if (crl_store) {
  2291.         X509_STORE_free(crl_store);
  2292.         crl_store = NULL;
  2293.     }
  2294.  
  2295.     /* set up the new CRL Store */
  2296.     crl_store = X509_STORE_new();
  2297.     if (crl_store) {
  2298. #ifdef OS2
  2299.         char path[CKMAXPATH];
  2300.  
  2301.         ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
  2302.         if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
  2303.             debug(F110,"ssl_http_init unable to load dir",path,0);
  2304.             if (ssl_debug_flag)
  2305.                 printf("?Unable to load crl-dir: %s\r\n",path);
  2306.         }
  2307. #ifdef NT
  2308.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/crls",NULL,NULL);
  2309.         if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
  2310.             debug(F110,"ssl_http_init unable to load dir",path,0);
  2311.             if (ssl_debug_flag)
  2312.                 printf("?Unable to load crl-dir: %s\r\n",path);
  2313.         }
  2314.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/crls",NULL,NULL);
  2315.         if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
  2316.             debug(F110,"ssl_http_init unable to load dir",path,0);
  2317.             if (ssl_debug_flag)
  2318.                 printf("?Unable to load crl-dir: %s\r\n",path);
  2319.         }
  2320. #endif /* NT */
  2321.         
  2322.         ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
  2323.         if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
  2324.             debug(F110,"ssl_http_init unable to load file",path,0);
  2325.             if (ssl_debug_flag)
  2326.                 printf("?Unable to load crl-file: %s\r\n",path);
  2327.         }
  2328. #ifdef NT
  2329.         ckmakmsg(path,CKMAXPATH,GetAppData(1),"kermit 95/ca_crls.pem",NULL,NULL);
  2330.         if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
  2331.             debug(F110,"ssl_http_init unable to load file",path,0);
  2332.             if (ssl_debug_flag)
  2333.                 printf("?Unable to load crl-file: %s\r\n",path);
  2334.         }
  2335.         ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/ca_crls.pem",NULL,NULL);
  2336.         if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
  2337.             debug(F110,"ssl_http_init unable to load file",path,0);
  2338.             if (ssl_debug_flag)
  2339.                 printf("?Unable to load crl-file: %s\r\n",path);
  2340.         }
  2341. #endif /* NT */
  2342. #endif /* OS2 */
  2343.  
  2344.         if (ssl_crl_file || ssl_crl_dir) {
  2345.             if (ssl_crl_file &&
  2346.                 X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 0) {
  2347.                 debug(F110,"ssl_http_init unable to load ssl_crl_file",ssl_crl_file,0);
  2348.                 if (ssl_debug_flag)
  2349.                     printf("?Unable to load crl-file: %s\r\n",ssl_crl_file);
  2350.             }
  2351.             if (ssl_crl_dir &&
  2352.                 X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 0) {
  2353.                 debug(F110,"ssl_http_init unable to load ssl_crl_dir",ssl_crl_dir,0);
  2354.                 if (ssl_debug_flag)
  2355.                     printf("?Unable to load crl-dir: %s\r\n",ssl_crl_dir);
  2356.             }
  2357.         } else {
  2358.             X509_STORE_set_default_paths(crl_store);
  2359.         }
  2360.     }
  2361.  
  2362. #ifndef COMMENT
  2363.     tls_conx = tls_http_con;
  2364.     tls_http_con=(SSL *)SSL_new(tls_http_ctx);
  2365.     if ( !tls_http_con ) {
  2366.         debug(F110,"ssl_http_init","SSL_new(tls_http_con) failed",0);
  2367.         tls_http_con = tls_conx;
  2368.         return(0);
  2369.     }
  2370.     if (tls_conx) {
  2371.         SSL_set_session(tls_http_con, SSL_get_session(tls_conx));
  2372. #ifdef SSL_KRB5
  2373.         if (tls_conx->kssl_ctx) {
  2374.             kssl_ctx_free(tls_conx->kssl_ctx);
  2375.             tls_conx->kssl_ctx = NULL;
  2376.         }
  2377. #endif /* SSL_KRB5 */
  2378.         SSL_free(tls_conx);
  2379.         tls_conx = NULL;
  2380.     }
  2381. #else /* COMMENT */
  2382.     /* I don't know why this does not work to reuse the connection. */
  2383.     if ( tls_http_con ) {
  2384.         SSL_clear(tls_http_con);
  2385.         SSL_set_session(tls_http_con,NULL);
  2386.         SSL_set_accept_state(tls_http_con) ;
  2387.     } else {
  2388.         tls_http_con=(SSL *)SSL_new(tls_http_ctx);
  2389.         if ( !tls_http_con ) {
  2390.             debug(F110,"ssl_http_init","SSL_new(tls_http_ctx) failed",0);
  2391.             tls_http_con = tls_conx;
  2392.             return(0);
  2393.         }
  2394.     }
  2395. #endif /* COMMENT */
  2396.  
  2397. #ifdef SSL_KRB5
  2398. #ifndef KRB5_SERVICE_NAME
  2399. #define KRB5_SERVICE_NAME    "host"
  2400. #endif
  2401.  
  2402.     if (tls_http_con->kssl_ctx == NULL)
  2403.     tls_http_con->kssl_ctx = kssl_ctx_new();
  2404.     if (tls_http_con->kssl_ctx != NULL)
  2405.         kssl_ctx_setstring(tls_http_con->kssl_ctx, KSSL_SERVER, hostname);
  2406.  
  2407.     kssl_ctx_setstring(tls_http_con->kssl_ctx, KSSL_SERVICE,
  2408.                         krb5_d_srv ? krb5_d_srv : KRB5_SERVICE_NAME);
  2409. #endif /* SSL_KRB5 */
  2410.  
  2411.     if (ssl_cipher_list)
  2412.         SSL_set_cipher_list(tls_http_con,ssl_cipher_list);
  2413.     else {
  2414.         char * p;
  2415.         if (p = getenv("SSL_CIPHER")) {
  2416.             SSL_set_cipher_list(tls_http_con,p);
  2417.         } else {
  2418.             SSL_set_cipher_list(tls_http_con,DEFAULT_CIPHER_LIST);
  2419.         }
  2420.     }
  2421.  
  2422.     ssl_verify_depth = -1;
  2423.  
  2424.     if ( ssl_debug_flag )
  2425.         printf("SSL/TLS init done!\r\n");
  2426.  
  2427.     ssl_http_initialized = 1;
  2428.     return(1);
  2429. }
  2430. #endif /* NOHTTP */
  2431.  
  2432. char *
  2433. ssl_get_dNSName(ssl) SSL * ssl;
  2434. {
  2435.     static char *dns = NULL;
  2436.     X509 *server_cert = NULL;
  2437.     int i;
  2438.     X509_EXTENSION *ext = NULL;
  2439.     STACK_OF(GENERAL_NAME) *ialt = NULL;
  2440.     GENERAL_NAME *gen = NULL;
  2441.  
  2442.     if ( dns ) {
  2443.         free(dns);
  2444.         dns = NULL;
  2445.     }
  2446.  
  2447.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2448.         if ((i = X509_get_ext_by_NID(server_cert, NID_subject_alt_name, -1))<0)
  2449.             return NULL;
  2450.         if (!(ext = X509_get_ext(server_cert, i)))
  2451.             return NULL;
  2452.         X509V3_add_standard_extensions();
  2453.         if (!(ialt = X509V3_EXT_d2i(ext)))
  2454.             return NULL;
  2455.         for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
  2456.             gen = sk_GENERAL_NAME_value(ialt, i);
  2457.             if (gen->type == GEN_DNS) {
  2458.                 if (!gen->d.ia5 || !gen->d.ia5->length)
  2459.           break;
  2460.                 if (strlen((char *)gen->d.ia5->data) != gen->d.ia5->length) {
  2461.                     /* Ignoring IA5String containing null character */
  2462.                     continue;
  2463.                 }
  2464.                 dns = malloc(gen->d.ia5->length + 1);
  2465.                 if (dns) {
  2466.                     memcpy(dns, gen->d.ia5->data, gen->d.ia5->length);
  2467.                     dns[gen->d.ia5->length] = 0;
  2468.                 }
  2469.                 break;
  2470.             }
  2471.         }
  2472.         X509V3_EXT_cleanup();
  2473.     }
  2474. cleanup:
  2475.     if (ialt)           sk_GENERAL_NAME_free(ialt);
  2476.     if (server_cert)    X509_free(server_cert);
  2477.     return dns;
  2478. }
  2479.  
  2480. char *
  2481. ssl_get_commonName(ssl) SSL * ssl; {
  2482.     static char name[256];
  2483.     int name_text_len;
  2484.     int err;
  2485.     X509 *server_cert;
  2486.  
  2487.     name_text_len = 0;
  2488.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2489.         name_text_len =
  2490.         X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert),
  2491.                       NID_commonName, name, sizeof(name));
  2492.         X509_free(server_cert);
  2493.     }
  2494.     if (name_text_len <= 0) {
  2495.     /* Common Name was empty or not retrieved */
  2496.         err = 0;
  2497.     } else if (strlen(name) != name_text_len) {
  2498.         /* Ignoring Common Name containing null character */
  2499.     err = 0;
  2500.     } else {
  2501.     err = 1;
  2502.     }
  2503.     if (err > 0)
  2504.       return name;
  2505.     else
  2506.       return NULL;
  2507. }
  2508.  
  2509. char *
  2510. ssl_get_issuer_name(ssl) SSL * ssl;
  2511. {
  2512.     static char name[256];
  2513.     X509 *server_cert;
  2514.  
  2515.     name[0] = '\0';
  2516.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2517.         X509_NAME_oneline(X509_get_issuer_name(server_cert),name,sizeof(name));
  2518.         X509_free(server_cert);
  2519.         return name;
  2520.     }
  2521.     else {
  2522. #ifdef COMMENT
  2523.       fprintf(stderr, "Warning: No certificate from server!\r\n");
  2524. #endif /* COMMENT */
  2525.         return NULL;
  2526.     }
  2527. }
  2528.  
  2529. char *
  2530. ssl_get_subject_name(ssl) SSL * ssl;
  2531. {
  2532.     static char name[256];
  2533.     X509 *server_cert;
  2534.  
  2535.     name[0] = '\0';
  2536.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2537.        X509_NAME_oneline(X509_get_subject_name(server_cert),name,sizeof(name));
  2538.        X509_free(server_cert);
  2539.        return name;
  2540.     }
  2541.     else
  2542.         return NULL;
  2543. }
  2544.  
  2545. #ifdef COMMENT
  2546. #ifdef CK_SSL
  2547.             && !(ck_ssleay_is_installed() &&
  2548.                (tls_active_flag || ssl_active_flag) &&
  2549.                ssl_anonymous_cipher(tls_active_flag?tls_con:ssl_con))
  2550. #endif /* CK_SSL */
  2551.  
  2552. int
  2553. ssl_anonymous_cipher(ssl) SSL * ssl;
  2554. {
  2555.     X509 * cert;
  2556.  
  2557.     if (sstelnet)
  2558.         cert = SSL_get_certificate(ssl);
  2559.     else
  2560.         cert = SSL_get_peer_certificate(ssl);
  2561.  
  2562.     if ( cert ) {
  2563.         X509_free(cert);
  2564.         return 0;
  2565.     }
  2566.     return 1;
  2567. }
  2568. #endif /* COMMENT */
  2569.  
  2570. /*
  2571.   This one is (very much!) based on work by
  2572.   Ralf S. Engelschall <rse@engelschall.com>.
  2573.   Comments by Ralf.
  2574. */
  2575. int
  2576. ssl_verify_crl(int ok, X509_STORE_CTX *ctx)
  2577. {
  2578.     X509_OBJECT obj;
  2579.     X509_NAME *subject = NULL;
  2580.     X509_NAME *issuer = NULL;
  2581.     X509 *xs = NULL;
  2582.     X509_CRL *crl = NULL;
  2583.     X509_REVOKED *revoked = NULL;
  2584.     X509_STORE_CTX * store_ctx = NULL;
  2585.     long serial;
  2586.     BIO *bio = NULL;
  2587.     int i, n, rc;
  2588.     char *cp;
  2589.     char *cp2;
  2590.  
  2591.     /*
  2592.      * Unless a revocation store for CRLs was created we
  2593.      * cannot do any CRL-based verification, of course.
  2594.      */
  2595.     if (!crl_store)
  2596.         return ok;
  2597.  
  2598.     store_ctx = X509_STORE_CTX_new();
  2599.     if ( !store_ctx )
  2600.         return(ok);
  2601.  
  2602.     /*
  2603.      * Determine certificate ingredients in advance
  2604.      */
  2605.     xs      = X509_STORE_CTX_get_current_cert(ctx);
  2606.     subject = X509_get_subject_name(xs);
  2607.     issuer  = X509_get_issuer_name(xs);
  2608.  
  2609.     /*
  2610.      * OpenSSL provides the general mechanism to deal with CRLs but does not
  2611.      * use them automatically when verifying certificates, so we do it
  2612.      * explicitly here. We will check the CRL for the currently checked
  2613.      * certificate, if there is such a CRL in the store.
  2614.      *
  2615.      * We come through this procedure for each certificate in the certificate
  2616.      * chain, starting with the root-CA's certificate. At each step we've to
  2617.      * both verify the signature on the CRL (to make sure it's a valid CRL)
  2618.      * and it's revocation list (to make sure the current certificate isn't
  2619.      * revoked).  But because to check the signature on the CRL we need the
  2620.      * public key of the issuing CA certificate (which was already processed
  2621.      * one round before), we've a little problem. But we can both solve it and
  2622.      * at the same time optimize the processing by using the following
  2623.      * verification scheme (idea and code snippets borrowed from the GLOBUS
  2624.      * project):
  2625.      *
  2626.      * 1. We'll check the signature of a CRL in each step when we find a CRL
  2627.      *    through the _subject_ name of the current certificate. This CRL
  2628.      *    itself will be needed the first time in the next round, of course.
  2629.      *    But we do the signature processing one round before this where the
  2630.      *    public key of the CA is available.
  2631.      *
  2632.      * 2. We'll check the revocation list of a CRL in each step when
  2633.      *    we find a CRL through the _issuer_ name of the current certificate.
  2634.      *    This CRLs signature was then already verified one round before.
  2635.      *
  2636.      * This verification scheme allows a CA to revoke its own certificate as
  2637.      * well, of course.
  2638.      */
  2639.  
  2640.     /*
  2641.      * Try to retrieve a CRL corresponding to the _subject_ of
  2642.      * the current certificate in order to verify it's integrity.
  2643.      */
  2644.     memset((char *)&obj, 0, sizeof(obj));
  2645.     X509_STORE_CTX_init(store_ctx, crl_store, NULL, NULL);
  2646.     rc = X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, subject, &obj);
  2647.     X509_STORE_CTX_cleanup(store_ctx);
  2648.     crl = obj.data.crl;
  2649.     if (rc > 0 && crl != NULL) {
  2650.         /*
  2651.          * Verify the signature on this CRL
  2652.          */
  2653.         if (X509_CRL_verify(crl, X509_get_pubkey(xs)) <= 0) {
  2654.             fprintf(stderr, "Invalid signature on CRL!\n");
  2655.             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
  2656.             X509_OBJECT_free_contents(&obj);
  2657.             X509_STORE_CTX_free(store_ctx);
  2658.             return 0;
  2659.         }
  2660.  
  2661.         /*
  2662.          * Check date of CRL to make sure it's not expired
  2663.          */
  2664.         i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl));
  2665.         if (i == 0) {
  2666.             fprintf(stderr, "Found CRL has invalid nextUpdate field.\n");
  2667.             X509_STORE_CTX_set_error(ctx,
  2668.                                     X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
  2669.             X509_OBJECT_free_contents(&obj);
  2670.             X509_STORE_CTX_free(store_ctx);
  2671.             return 0;
  2672.         }
  2673.         if (i < 0) {
  2674.             fprintf(stderr,
  2675. "Found CRL is expired - revoking all certificates until you get updated CRL.\n"
  2676.                     );
  2677.             X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED);
  2678.             X509_OBJECT_free_contents(&obj);
  2679.             X509_STORE_CTX_free(store_ctx);
  2680.             return 0;
  2681.         }
  2682.         X509_OBJECT_free_contents(&obj);
  2683.     }
  2684.  
  2685.     /*
  2686.      * Try to retrieve a CRL corresponding to the _issuer_ of
  2687.      * the current certificate in order to check for revocation.
  2688.      */
  2689.     memset((char *)&obj, 0, sizeof(obj));
  2690.     X509_STORE_CTX_init(store_ctx, crl_store, NULL, NULL);
  2691.     rc = X509_STORE_get_by_subject(store_ctx, X509_LU_CRL, issuer, &obj);
  2692.     X509_STORE_CTX_free(store_ctx);        /* calls X509_STORE_CTX_cleanup() */
  2693.     crl = obj.data.crl;
  2694.     if (rc > 0 && crl != NULL) {
  2695.         /*
  2696.          * Check if the current certificate is revoked by this CRL
  2697.          */
  2698.         n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
  2699.         for (i = 0; i < n; i++) {
  2700.             revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
  2701.             if (ASN1_INTEGER_cmp(revoked->serialNumber,
  2702.                                  X509_get_serialNumber(xs)) == 0) {
  2703.  
  2704.                 serial = ASN1_INTEGER_get(revoked->serialNumber);
  2705.                 cp = X509_NAME_oneline(issuer, NULL, 0);
  2706.                 free(cp);
  2707.  
  2708.                 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
  2709.                 X509_OBJECT_free_contents(&obj);
  2710.                 return 0;
  2711.             }
  2712.         }
  2713.         X509_OBJECT_free_contents(&obj);
  2714.     }
  2715.     return ok;
  2716. }
  2717.  
  2718. char *
  2719. tls_userid_from_client_cert(ssl) SSL * ssl;
  2720. {
  2721.     static char cn[256];
  2722.     static char *r = cn;
  2723.     int err;
  2724.     X509 *client_cert;
  2725.  
  2726.     if (client_cert = SSL_get_peer_certificate(ssl)) {
  2727.         /* call the custom function */
  2728.         err = X509_to_user(client_cert, cn, sizeof(cn));
  2729.         X509_free(client_cert);
  2730.         if (err)
  2731.             return r = NULL;
  2732.         else
  2733.             return r;
  2734.     }
  2735.     else
  2736.         return r = NULL;
  2737. }
  2738.  
  2739. unsigned char **
  2740. tls_get_SAN_objs(SSL * ssl, int type)
  2741. /* returns NULL or an array of malloc'ed objects of type `type' from the server's
  2742.  * subjectAltName, remember to free() them all!
  2743.  */
  2744. {
  2745. #define NUM_SAN_OBJS 64
  2746.     static unsigned char *objs[NUM_SAN_OBJS];
  2747.     unsigned char **rv = NULL;
  2748.     X509 *server_cert = NULL;
  2749.     int i, j;
  2750.     X509_EXTENSION *ext = NULL;
  2751.     STACK_OF(GENERAL_NAME) *ialt = NULL;
  2752.     GENERAL_NAME *gen = NULL;
  2753.  
  2754.     memset(objs, 0, sizeof(objs));
  2755.     if (server_cert = SSL_get_peer_certificate(ssl)) {
  2756.         if ((i = X509_get_ext_by_NID(server_cert, NID_subject_alt_name, -1)) < 0)
  2757.             goto eject;
  2758.         if (!(ext = X509_get_ext(server_cert, i)))
  2759.             goto eject;
  2760.         X509V3_add_standard_extensions();
  2761.         if (!(ialt = X509V3_EXT_d2i(ext)))
  2762.             goto eject;
  2763.         rv = objs;
  2764.         for (i = 0, j = 0; i < sk_GENERAL_NAME_num(ialt) && j < NUM_SAN_OBJS - 2; i++) {
  2765.             gen = sk_GENERAL_NAME_value(ialt, i);
  2766.             /* The use of V_ASN1_CONTEXT_SPECIFIC is because OpenSSL 0.9.6 defined its
  2767.              * types | V_ASN1_CONTEXT_SPECIFIC.  0.9.7 does not.  In case, we are built
  2768.              * with one and linked to the other we use this hack.
  2769.              */
  2770.             if ((gen->type | V_ASN1_CONTEXT_SPECIFIC) == (type | V_ASN1_CONTEXT_SPECIFIC)) {
  2771.                 if (!gen->d.ia5 || !gen->d.ia5->length)
  2772.           break;
  2773.                 if (strlen((char *)gen->d.ia5->data) != gen->d.ia5->length) {
  2774.                     /* Ignoring IA5String containing null character */
  2775.                     continue;
  2776.                 }
  2777.                 objs[j] = malloc(gen->d.ia5->length + 1);
  2778.                 if (objs[j]) {
  2779.                     memcpy(objs[j], gen->d.ia5->data, gen->d.ia5->length);
  2780.                     objs[j][gen->d.ia5->length] = 0;
  2781.                     j++;
  2782.                 }
  2783.             }
  2784.         }
  2785.         X509V3_EXT_cleanup();
  2786.     }
  2787. eject:
  2788.     if (ialt)           sk_GENERAL_NAME_free(ialt);
  2789.     if (server_cert)    X509_free(server_cert);
  2790.     return rv;
  2791. }
  2792.  
  2793.  
  2794. static int
  2795. dNSName_cmp(const char *host, const char *dNSName)
  2796. {
  2797.     int c1 = 1, c2 = 1, num_comp, rv = -1;
  2798.     char *p, *p1, *p2, *host_copy=NULL, *dNSName_copy=NULL;
  2799.  
  2800.     /* first we count the number of domain name components in both parameters.
  2801.      * they should be equal many, or it's not a match
  2802.      */
  2803.     p = (char *) host;
  2804.     while (p = strstr(p, ".")) {
  2805.         c1++;
  2806.         p++;
  2807.     }
  2808.     p = (char *) dNSName;
  2809.     while (p = strstr(p, ".")) {
  2810.         c2++;
  2811.         p++;
  2812.     }
  2813.     if (c1 != c2)
  2814.         return -1;
  2815.     num_comp = c1;
  2816.  
  2817.     makestr(&host_copy,host);
  2818.     makestr(&dNSName_copy,dNSName);
  2819.     if (host_copy == NULL || dNSName_copy == NULL)
  2820.         goto eject;
  2821.     /* make substrings by replacing '.' with '\0' */
  2822.     p = dNSName_copy;
  2823.     while (p = strstr(p, ".")) {
  2824.         *p = '\0';
  2825.         p++;
  2826.     }
  2827.     p = host_copy;
  2828.     while (p = strstr(p, ".")) {
  2829.         *p = '\0';
  2830.         p++;
  2831.     }
  2832.  
  2833.     /* compare each component */
  2834.     p1 = host_copy;
  2835.     p2 = dNSName_copy;
  2836.     for (; num_comp; num_comp--) {
  2837.         if (!ckmatch(p2, p1,0,1))
  2838.             /* failed match */
  2839.             goto eject;
  2840.         p1 += strlen(p1) + 1;
  2841.         p2 += strlen(p2) + 1;
  2842.     }
  2843.     /* match ok */
  2844.     rv = 0;
  2845.  
  2846.   eject:
  2847.     if (dNSName_copy)   free(dNSName_copy);
  2848.     if (host_copy)      free(host_copy);
  2849.     return rv;
  2850. }
  2851.  
  2852.  
  2853.  
  2854. static int
  2855. show_hostname_warning(char *s1, char *s2)
  2856. {
  2857.     char prefix[1024];
  2858.     int ok = 1;
  2859.     setverbosity();
  2860.     ckmakxmsg(prefix,1024,
  2861.               "Warning: Hostname (\"", s1, 
  2862.               "\") does not match server's certificate (\"", s2, "\")",
  2863.               NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  2864.     if (ssl_verify_flag)
  2865.         ok = uq_ok(prefix,
  2866.                     "Continue? (Y/N) ",
  2867.                     3, NULL, 0);
  2868.     else if (verbosity)
  2869.         printf(prefix);
  2870.     return(ok);
  2871. }
  2872.  
  2873. #ifndef OSF50
  2874. #ifndef HPUX10
  2875. #ifndef HPUX1100
  2876. #ifndef SCO_OSR505
  2877. #ifndef OpenBSD
  2878. #ifndef FREEBSD4
  2879. #ifndef NETBSD15
  2880. #ifndef LINUX
  2881. #ifndef AIX41
  2882. #ifndef UW7
  2883. #ifndef IRIX65
  2884. #ifndef SOLARIS9
  2885. #ifndef SOLARIS8
  2886. #ifndef SOLARIS7
  2887. #ifndef MACOSX
  2888. #ifdef DEC_TCPIP
  2889. #define inet_aton INET_ATON
  2890. #endif /* DEC_TCPIP */
  2891.  
  2892. #ifndef NO_DCL_INET_ATON
  2893. static int
  2894. inet_aton(char * ipaddress, struct in_addr * ia) {
  2895.     struct stringarray * q;
  2896.     union {
  2897.         unsigned long l;
  2898.         unsigned char b[4];
  2899.     } dummy;
  2900.  
  2901.     q = cksplit(1,0,ipaddress,".","0123456789abcdefACDEF",8,0,0);
  2902.     if (q->a_size == 4) {
  2903.         dummy.b[0] = atoi(q->a_head[1]);
  2904.         dummy.b[1] = atoi(q->a_head[2]);
  2905.         dummy.b[2] = atoi(q->a_head[3]);
  2906.         dummy.b[3] = atoi(q->a_head[4]);
  2907.         ia->s_addr = dummy.l;
  2908.         return(ia->s_addr != 0);
  2909.     }
  2910.     return(0);
  2911. }
  2912. #endif    /* NO_DCL_INET_ATON */
  2913.  
  2914. #endif /* MACOSX */
  2915. #endif /* SOLARIS7 */
  2916. #endif /* SOLARIS8 */
  2917. #endif /* SOLARIS9 */
  2918. #endif /* IRIX65 */
  2919. #endif /* UW7 */
  2920. #endif /* AIX41 */
  2921. #endif /* LINUX */
  2922. #endif /* NETBSD15 */
  2923. #endif /* FREEBSD4 */
  2924. #endif /* OpenBSD */
  2925. #endif /* SCO_OSR505 */
  2926. #endif /* HPUX1100 */
  2927. #endif /* HPUX10 */
  2928. #endif /* OSF50 */
  2929.  
  2930. int
  2931. ssl_check_server_name(SSL * ssl, char * hostname)
  2932. /* returns 0 if hostname and server's cert matches, else -1 */
  2933. {
  2934.     char * commonName;
  2935.     unsigned char ** dNSName;
  2936.     unsigned char ** ipAddress;
  2937.     struct in_addr ia;
  2938.     int rv;
  2939.  
  2940.     setverbosity();
  2941.     if (verbosity && !inserver) {
  2942.         if (dNSName = tls_get_SAN_objs(ssl,GEN_DNS)) {
  2943.             int i = 0;
  2944.             for (i = 0; dNSName[i]; i++) {
  2945.                 printf("Certificate[0] altSubjectName DNS=%s\r\n",dNSName[i]);
  2946.                 free(dNSName[i]);
  2947.             }
  2948.         }
  2949.         if (ipAddress = tls_get_SAN_objs(ssl,GEN_IPADD)) {
  2950.             int i = 0;
  2951.             char *server_ip;
  2952.             struct in_addr ia;
  2953.  
  2954.             for (i = 0; ipAddress[i]; i++) {
  2955.                 if (ipAddress[i]) {
  2956.                     ia.s_addr = *(unsigned long *)ipAddress[i];
  2957.                     server_ip = inet_ntoa(ia);
  2958.                     printf("Certificate[0] altSubjectName IPAddr=%s\r\n",server_ip);
  2959.                 }
  2960.                 free(ipAddress[i]);
  2961.             }
  2962.             /* ipAddress points to a static - don't free */
  2963.         }
  2964.         if (dNSName = tls_get_SAN_objs(ssl,GEN_EMAIL)) {
  2965.             int i = 0;
  2966.             for (i = 0; dNSName[i]; i++) {
  2967.                 printf("Certificate[0] altSubjectName Email=%s\r\n",dNSName[i]);
  2968.                 free(dNSName[i]);
  2969.             }
  2970.         }
  2971.         if (dNSName = tls_get_SAN_objs(ssl,GEN_URI)) {
  2972.             int i = 0;
  2973.             for (i = 0; dNSName[i]; i++) {
  2974.                 printf("Certificate[0] altSubjectName URI=%s\r\n",dNSName[i]);
  2975.                 free(dNSName[i]);
  2976.             }
  2977.         }
  2978.         if (dNSName = tls_get_SAN_objs(ssl,GEN_OTHERNAME)) {
  2979.             int i = 0;
  2980.             for (i = 0; dNSName[i]; i++) {
  2981.                 printf("Certificate[0] altSubjectName Other=%s\r\n",dNSName[i]);
  2982.                 free(dNSName[i]);
  2983.             }
  2984.         }
  2985.     }
  2986.  
  2987.     /* first we check if `hostname' is in fact an ip address */
  2988.     if (inet_aton(hostname, &ia)) {
  2989.         ipAddress = tls_get_SAN_objs(ssl,GEN_IPADD);
  2990.         if (ipAddress) {
  2991.             int i = 0;
  2992.             char *server_ip = "UNKNOWN";
  2993.  
  2994.             for (i = 0; ipAddress[i]; i++)
  2995.                 if (*(unsigned long *)ipAddress[i] == ia.s_addr)
  2996.                     return 0;
  2997.  
  2998.             if (ipAddress[i - 1]) {
  2999.                 ia.s_addr = *(unsigned long *)ipAddress[i - 1];
  3000.                 server_ip = inet_ntoa(ia);
  3001.             }
  3002.             rv = show_hostname_warning(hostname, server_ip) ? 0 : -1;
  3003.             for (i = 0; ipAddress[i]; i++)
  3004.                 free(ipAddress[i]);
  3005.         } else {
  3006.             rv = show_hostname_warning(hostname, "NO IP IN CERT") ? 0 : -1;
  3007.         }
  3008.         return(rv);
  3009.     }
  3010.  
  3011.     /* look for dNSName(s) in subjectAltName in the server's certificate */
  3012.     dNSName = tls_get_SAN_objs(ssl,GEN_DNS);
  3013.     if (dNSName) {
  3014.         int i = 0;
  3015.         for (i = 0; dNSName[i]; i++) {
  3016.             if (!dNSName_cmp(hostname,(char *)dNSName[i]))
  3017.                 return 0;
  3018.         }
  3019.         rv = show_hostname_warning(hostname,
  3020.                    (char *)((dNSName[i - 1] == NULL) ? 
  3021.                        (char *)"UNKNOWN" : (char *)dNSName[i - 1]))
  3022.          ? 0 : -1;
  3023.         for (i = 0; dNSName[i]; i++)
  3024.             free(dNSName[i]);
  3025.         return rv;
  3026.     } else if ((commonName = ssl_get_commonName(ssl))) {
  3027.        /* so the server didn't have any dNSName's, check the commonName */
  3028.        if (!dNSName_cmp(hostname, commonName))
  3029.            return 0;
  3030.        else
  3031.            return (show_hostname_warning(hostname, commonName) ? 0 : -1);
  3032.     }
  3033.     return -1;
  3034. }
  3035.  
  3036. /* Is 'user' authorized to access the system without a login */
  3037. int
  3038. tls_is_user_valid(SSL * ssl, const char *user)
  3039. {
  3040.     X509 *client_cert;
  3041.     int r = 0;
  3042.  
  3043.     if ( !ssl || !user || !user[0] )
  3044.         return(0);
  3045.  
  3046.     if (!(client_cert = SSL_get_peer_certificate(ssl)))
  3047.         return 0;
  3048.  
  3049.     /* Use user supplied function */
  3050.     r = X509_userok(client_cert,user);
  3051.  
  3052.     X509_free(client_cert);
  3053.     return r;
  3054. }
  3055.  
  3056. int
  3057. tls_is_anon(int x)
  3058. {
  3059.     char buf[128];
  3060.     SSL_CIPHER * cipher;
  3061.     SSL * ssl = NULL;
  3062.  
  3063.     switch ( x ) {
  3064. #ifndef NOFTP
  3065. #ifndef SYSFTP
  3066.     case 1:     /* ftp command */
  3067.         if ( ssl_ftp_active_flag )
  3068.             ssl = ssl_ftp_con;
  3069.         else
  3070.             return(0);
  3071.         break;
  3072.     case 2:     /* ftp data */
  3073.         if ( ssl_ftp_data_active_flag )
  3074.             ssl = ssl_ftp_data_con;
  3075.         else
  3076.             return(0);
  3077.         break;
  3078. #endif /* SYSFTP */
  3079. #endif /* NOFTP */
  3080.     default:
  3081.         if (tls_active_flag)
  3082.             ssl = tls_con;
  3083.         else if (ssl_active_flag)
  3084.             ssl = ssl_con;
  3085.         else
  3086.             return(0);
  3087.     }
  3088.  
  3089.     cipher = SSL_get_current_cipher(ssl);
  3090.     if (SSL_CIPHER_description(cipher,buf,sizeof(buf))) {
  3091.         if (ckindex("Au=None",buf,0,0,0) != 0)
  3092.             return(1);                  /* anonymous */
  3093.         return(0);                  /* known */
  3094.     } else {
  3095.         /* could not get cipher description.  Assume anonymous */
  3096.         return(1);
  3097.     }
  3098. }
  3099.  
  3100. int
  3101. tls_is_krb5(int x)
  3102. {
  3103.     char buf[128];
  3104.     SSL_CIPHER * cipher;
  3105.     SSL * ssl = NULL;
  3106.  
  3107.     switch ( x ) {
  3108. #ifndef NOFTP
  3109. #ifndef SYSFTP
  3110.     case 1:     /* ftp command */
  3111.         if ( ssl_ftp_active_flag )
  3112.             ssl = ssl_ftp_con;
  3113.         else
  3114.             return(0);
  3115.         break;
  3116.     case 2:     /* ftp data */
  3117.         if ( ssl_ftp_data_active_flag )
  3118.             ssl = ssl_ftp_data_con;
  3119.         else
  3120.             return(0);
  3121.         break;
  3122. #endif /* SYSFTP */
  3123. #endif /* NOFTP */
  3124. #ifndef NOHTTP
  3125.     case 3:
  3126.         if ( tls_http_active_flag )
  3127.             ssl = tls_http_con;
  3128.         break;
  3129. #endif /* NOHTTP */
  3130.     default:
  3131.         if (tls_active_flag)
  3132.             ssl = tls_con;
  3133.         else if (ssl_active_flag)
  3134.             ssl = ssl_con;
  3135.         else
  3136.             return(0);
  3137.     }
  3138.  
  3139.     cipher = SSL_get_current_cipher(ssl);
  3140.     if (cipher && SSL_CIPHER_description(cipher,buf,sizeof(buf))) {
  3141.         if (ckindex("Au=KRB5",buf,0,0,0) != 0)
  3142.             return(1);                  /* krb5 */
  3143.     }
  3144.     return(0);                          /* not */
  3145. }
  3146.  
  3147. int
  3148. ssl_get_client_finished(char *buf, int count)
  3149. {
  3150. #ifdef NO_GET_FINISHED
  3151.     return(0);
  3152. #else
  3153.     if (sstelnet || tcp_incoming) {
  3154.         return(SSL_get_peer_finished(ssl_active_flag?ssl_con:tls_con,
  3155.                                       buf,count));
  3156.     } else {
  3157.         return(SSL_get_finished(ssl_active_flag?ssl_con:tls_con,
  3158.                                       buf,count));
  3159.     }
  3160. #endif /* NO_GET_FINISHED */
  3161. }
  3162.  
  3163. int
  3164. ssl_get_server_finished(char *buf, int count)
  3165. {
  3166. #ifdef NO_GET_FINISHED
  3167.     return(0);
  3168. #else
  3169.     if (sstelnet || tcp_incoming) {
  3170.         return(SSL_get_finished(ssl_active_flag?ssl_con:tls_con,
  3171.                                       buf,count));
  3172.     } else {
  3173.         return(SSL_get_peer_finished(ssl_active_flag?ssl_con:tls_con,
  3174.                                       buf,count));
  3175.     }
  3176. #endif /* NO_GET_FINISHED */
  3177. }
  3178.  
  3179.  
  3180. #ifdef CK_AUTHENTICATION
  3181. int
  3182. #ifdef CK_ANSIC
  3183. ssl_reply(int how, unsigned char *data, int cnt)
  3184. #else
  3185. ssl_reply(how,data,cnt) int how; unsigned char *data; int cnt;
  3186. #endif
  3187. {
  3188.     char * str=NULL;
  3189.  
  3190.     setverbosity();
  3191.     data += 4;                          /* Point to status byte */
  3192.     cnt  -= 4;
  3193.  
  3194.     if(cnt-- < 1) {
  3195.         auth_finished(AUTH_REJECT);
  3196.         return AUTH_FAILURE;
  3197.     }
  3198.  
  3199.     switch(*data++) {
  3200.     case SSL_ACCEPT:
  3201.         if (tn_deb || debses)
  3202.             tn_debug("[SSL - handshake starting]");
  3203.         else if ( verbosity )
  3204.             printf("[SSL - handshake starting]\r\n");
  3205.         debug(F110,"ssl_reply","[SSL - handshake starting]",0);
  3206.  
  3207.         /* right ... now we drop into the SSL library */
  3208.         if (!ssl_only_flag) {
  3209.             if (ssl_dummy_flag) {
  3210.                 if (tn_deb || debses)
  3211.                     tn_debug("[SSL - Dummy Connected]");
  3212.                 else if ( verbosity ) {
  3213.                     printf("[SSL - Dummy Connected]\r\n");
  3214.                 }
  3215.                 debug(F110,"ssl_reply","[SSL - Dummy Connected]",0);
  3216.                 auth_finished(AUTH_UNKNOWN);
  3217.                 accept_complete = 1;
  3218.                 return AUTH_SUCCESS;
  3219.             }
  3220.  
  3221.             if (SSL_connect(ssl_con) <= 0) {
  3222.                 int len;
  3223.                 if (tn_deb || debses) {
  3224.                     tn_debug("[SSL - FAILED]");
  3225.                     ERR_print_errors(bio_err);
  3226.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3227.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3228.                     printf(ssl_err);
  3229.                 } else if ( verbosity ) {
  3230.                     printf("[SSL - FAILED]\r\n");
  3231.                     ERR_print_errors(bio_err);
  3232.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3233.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3234.                     printf(ssl_err);
  3235.                 }
  3236.                 debug(F110,"ssl_reply","[SSL - FAILED]",0);
  3237.                 auth_finished(AUTH_REJECT);
  3238.                 ttclos(0);
  3239.                 return AUTH_FAILURE;
  3240.             } else {
  3241.                 if (tn_deb || debses)
  3242.                     tn_debug("[SSL - OK]");
  3243.                 else if ( verbosity ) {
  3244.                     printf("[SSL - OK]\r\n");
  3245.                 }
  3246.                 debug(F110,"ssl_reply","[SSL - OK]",0);
  3247.  
  3248.                 ssl_active_flag = 1;
  3249.                 ssl_display_connect_details(ssl_con,0,verbosity);
  3250.             }
  3251.         }
  3252.         auth_finished(AUTH_UNKNOWN);
  3253.         accept_complete = 1;
  3254.         break;
  3255.  
  3256.     case SSL_REJECT:
  3257.         if (tn_deb || debses) {
  3258.             tn_debug(
  3259.                  "[SSL - failed to switch on SSL - trying plaintext login]");
  3260.         } else if ( verbosity ) {
  3261.             printf("[SSL - failed to switch on SSL]\r\n");
  3262.             printf("Trying plaintext login:\r\n");
  3263.         }
  3264.         debug(F110,"ssl_reply","[SSL - failed to switch on SSL]",0);
  3265.         auth_finished(AUTH_REJECT);
  3266.         return AUTH_FAILURE;
  3267.  
  3268.     default:
  3269.         return AUTH_FAILURE;
  3270.     }
  3271.     return AUTH_SUCCESS;
  3272. }
  3273.  
  3274. int
  3275. #ifdef CK_ANSIC
  3276. ssl_is(unsigned char *data, int cnt)
  3277. #else
  3278. ssl_is(data,cnt) unsigned char *data; int cnt;
  3279. #endif
  3280. {
  3281.     if ((cnt -= 4) < 1)
  3282.         return AUTH_FAILURE;
  3283.  
  3284.     setverbosity();
  3285.     data += 4;
  3286.     switch(*data++) {
  3287.     case SSL_START:
  3288.         /* server starts the SSL stuff now ... */
  3289.         if (!ssl_only_flag) {
  3290.             if ( !tls_load_certs(ssl_ctx,ssl_con,1) ) {
  3291.                 auth_finished(AUTH_REJECT);
  3292.                 return AUTH_FAILURE;
  3293.             }
  3294.  
  3295.             if (tn_deb || debses)
  3296.                 tn_debug("[SSL - handshake starting]");
  3297.             else if ( verbosity )
  3298.                 printf("[SSL - handshake starting]\r\n");
  3299.             debug(F110,"ssl_is","[SSL - handshake starting]",0);
  3300.  
  3301.             SendSSLAuthSB(SSL_ACCEPT, (void *)0, 0);
  3302.  
  3303.             auth_ssl_valid = 1;
  3304.  
  3305.             if (ssl_dummy_flag) {
  3306.                 if (tn_deb || debses)
  3307.                     tn_debug("[SSL - Dummy Connected]");
  3308.                 else if ( verbosity ) {
  3309.                     printf("[SSL - Dummy Connected]\r\n");
  3310.                 }
  3311.                 debug(F110,"ssl_is","[SSL - Dummy Connected]",0);
  3312.                 accept_complete = 1;
  3313.                 auth_finished(AUTH_UNKNOWN);
  3314.                 return AUTH_SUCCESS;
  3315.             }
  3316.  
  3317.             if (SSL_accept(ssl_con) <= 0) {
  3318.                 char errbuf[1024];
  3319.  
  3320.                 sprintf(errbuf,"[SSL - SSL_accept error: %s",
  3321.                          ERR_error_string(ERR_get_error(),NULL));
  3322.  
  3323.                 if (tn_deb || debses)
  3324.                     tn_debug(errbuf);
  3325.                 else if ( ssl_debug_flag )
  3326.                     printf("%s\r\n",errbuf);
  3327.                 else if ( verbosity )
  3328.                     printf("[SSL - SSL_accept error]\r\n");
  3329.  
  3330.                 debug(F110,"ssl_is",errbuf,0);
  3331.  
  3332.                 auth_finished(AUTH_REJECT);
  3333.                 ttclos(0);
  3334.                 return AUTH_FAILURE;
  3335.             }
  3336.  
  3337.             if (tn_deb || debses)
  3338.                 tn_debug("[SSL - OK]");
  3339.             else if ( verbosity ) {
  3340.                 printf("[SSL - OK]\r\n");
  3341.             }
  3342.             debug(F110,"ssl_is","[SSL - OK]",0);
  3343.             ssl_active_flag = 1;
  3344.             ssl_display_connect_details(ssl_con,1,verbosity);
  3345.  
  3346.             /* now check to see that we got exactly what we
  3347.             * wanted from the caller ... if a certificate is
  3348.             * required then we make 100% sure that we were
  3349.             * given one during the handshake (as it is an optional
  3350.             * part of SSL)
  3351.             */
  3352.  
  3353. #ifdef SSL_KRB5
  3354.             if ( tls_is_krb5(0) ) {
  3355.                 if (ssl_con->kssl_ctx->client_princ)
  3356.                     debug(F110,"ssl_is KRB5",ssl_con->kssl_ctx->client_princ,0);
  3357.             } else
  3358. #endif /* SSL_KRB5 */
  3359.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  3360.                 X509 * peer = SSL_get_peer_certificate(ssl_con);
  3361.                 if (peer == NULL) {
  3362.                     if (tn_deb || debses)
  3363.                         tn_debug("[SSL - peer check failed]");
  3364.                     else if (ssl_debug_flag)
  3365.                         printf("[SSL - peer check failed]\r\n");
  3366.                     debug(F110,"ssl_is","[SSL - peer check failed]",0);
  3367.  
  3368.                     /* LOGGING REQUIRED HERE! */
  3369.                     auth_finished(AUTH_REJECT);
  3370.                     return AUTH_FAILURE;
  3371.                 }
  3372.             }
  3373.             auth_finished(AUTH_UNKNOWN);
  3374.             accept_complete = 1;
  3375.         }
  3376.         break;
  3377.  
  3378.     default:
  3379.         SendSSLAuthSB(SSL_REJECT, (void *) "Unknown option received", -1);
  3380.         if (tn_deb || debses)
  3381.             tn_debug("[SSL - Unknown option received]");
  3382.         else
  3383.             printf("Unknown SSL option %d\r\n", data[-1]);
  3384.         debug(F111,"ssl_is","[SSL - Unknown option received]",data[-1]);
  3385.         auth_ssl_valid = 0;
  3386.         auth_finished(AUTH_REJECT);
  3387.         return(AUTH_FAILURE);
  3388.     }
  3389.     return AUTH_SUCCESS;
  3390. }
  3391.  
  3392. #endif /* CK_AUTHENTICATION */
  3393.  
  3394. int
  3395. ck_tn_tls_negotiate(VOID)
  3396. {
  3397.     X509 * peer = NULL;
  3398.     char str[256], *uid=NULL;
  3399.     extern int sstelnet;
  3400.  
  3401.     if ( !ck_ssleay_is_installed() )
  3402.         return(-1);
  3403.  
  3404.     setverbosity();
  3405.     if (sstelnet) {
  3406.         /* server starts the TLS stuff now ... */
  3407.         if (!tls_only_flag) {
  3408.             if ( !tls_load_certs(tls_ctx,tls_con,1) ) {
  3409.                 auth_finished(AUTH_REJECT);
  3410.                 return -1;
  3411.             }
  3412.  
  3413.             if (tn_deb || debses)
  3414.                 tn_debug("[TLS - handshake starting]");
  3415.             else if ( verbosity )
  3416.                 printf("[TLS - handshake starting]\r\n");
  3417.             debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
  3418.  
  3419.             if (ssl_dummy_flag) {
  3420.                 if (tn_deb || debses)
  3421.                     tn_debug("[TLS - Dummy Connected]");
  3422.                 else if ( verbosity ) {
  3423.                     printf("[TLS - Dummy Connected]\r\n");
  3424.                 }
  3425.                 debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
  3426.                 accept_complete = 1;
  3427.                 auth_finished(AUTH_REJECT);
  3428.                 return 0;
  3429.             }
  3430.  
  3431.             if (SSL_accept(tls_con) <= 0) {
  3432.                 char errbuf[1024];
  3433.  
  3434.                 sprintf(errbuf,"[TLS - SSL_accept error: %s",
  3435.                          ERR_error_string(ERR_get_error(),NULL));
  3436.  
  3437.                 if (tn_deb || debses)
  3438.                     tn_debug(errbuf);
  3439.                 else if ( ssl_debug_flag )
  3440.                     printf("%s\r\n",errbuf);
  3441.                 else if ( verbosity )
  3442.                     printf("[TLS - SSL_accept error]\r\n");
  3443.  
  3444.                 debug(F110,"ck_tn_tls_negotiate",errbuf,0);
  3445.                 auth_finished(AUTH_REJECT);
  3446.                 return -1;
  3447.             }
  3448.  
  3449.             if (tn_deb || debses)
  3450.                 tn_debug("[TLS - OK]");
  3451.             else if ( verbosity ) {
  3452.                 printf("[TLS - OK]\r\n");
  3453.             }
  3454.  
  3455.             debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
  3456.             tls_active_flag = 1;
  3457.             ssl_display_connect_details(tls_con,1,verbosity);
  3458.  
  3459.  
  3460. #ifdef SSL_KRB5
  3461.             if ( tls_is_krb5(0) ) {
  3462.                 if (tls_con->kssl_ctx->client_princ) {
  3463.                     char *p;
  3464.                     ckstrncpy(szUserNameAuthenticated,
  3465.                                tls_con->kssl_ctx->client_princ,
  3466.                                UIDBUFLEN);
  3467.                     ckstrncpy(szUserNameRequested,
  3468.                                tls_con->kssl_ctx->client_princ,
  3469.                                UIDBUFLEN);
  3470.                     for ( p = szUserNameRequested; *p ; p++ ) {
  3471.                         if ( *p == '@' || *p == '/' ) {
  3472.                             *p = '\0';
  3473.                             break;
  3474.                         }
  3475.                     }
  3476.                 } else {
  3477.                     szUserNameRequested[0] = '\0';
  3478.                     szUserNameAuthenticated[0] = '\0';
  3479.                 }
  3480. #ifdef CK_LOGIN
  3481.                 if (zvuser(szUserNameRequested))
  3482.                     auth_finished(AUTH_VALID);
  3483.                 else
  3484. #endif /* CK_LOGIN */
  3485.                     auth_finished(AUTH_USER);
  3486.             } else
  3487. #endif /* SSL_KRB5 */
  3488.             {
  3489.             /* now check to see that we got exactly what we
  3490.             * wanted from the caller ... if a certificate is
  3491.             * required then we make 100% sure that we were
  3492.             * given one during the handshake (as it is an optional
  3493.             * part of TLS)
  3494.             */
  3495.             peer=SSL_get_peer_certificate(tls_con);
  3496.             if (peer == NULL) {
  3497.                 debug(F100,"SSL_get_peer_certificate() == NULL","",0);
  3498.                 auth_finished(AUTH_REJECT);
  3499.                 if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  3500.                     if (tn_deb || debses)
  3501.                         tn_debug("[TLS - peer check failed]");
  3502.                     else if (ssl_debug_flag) {
  3503.                         printf("[TLS - peer check failed]\r\n");
  3504.                     }
  3505.                     debug(F110,
  3506.                            "ck_tn_tls_negotiate",
  3507.                            "[TLS - peer check failed]",
  3508.                            0
  3509.                            );
  3510.                     /* LOGGING REQUIRED HERE! */
  3511.                     return -1;
  3512.                 }
  3513.             } else {
  3514.                 debug(F100,"SSL_get_peer_certificate() != NULL","",0);
  3515.                 X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3516.                                            NID_commonName,str,
  3517.                                            256
  3518.                                            );
  3519.                 if ( verbosity )
  3520.                     printf("[TLS - commonName=%s]\r\n",str);
  3521.  
  3522.                 X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3523. #ifndef NID_x500UniqueIdentifier
  3524.                                            NID_uniqueIdentifier,
  3525. #else
  3526.                                            NID_x500UniqueIdentifier,
  3527. #endif
  3528.                                            str,
  3529.                                            256
  3530.                                            );
  3531.                 if ( verbosity )
  3532.                     printf("[TLS - uniqueIdentifier=%s]\r\n",str);
  3533.  
  3534.                 /* Try to determine user name */
  3535.                 uid = tls_userid_from_client_cert(tls_con);
  3536.                 if ( uid ) {
  3537.                     /* This code is very questionable.
  3538.                      * How should it behave?
  3539.                      * The client has presented a certificate that
  3540.                      * contains a username.  We have validated the
  3541.                      * certificate but we do not automatically
  3542.                      * log the user in unless there is a .tlslogin
  3543.                      * file.
  3544.                      */
  3545.  
  3546.                     ckstrncpy(szUserNameRequested,uid,UIDBUFLEN);
  3547. #ifdef CK_LOGIN
  3548.                     if (zvuser(uid))
  3549.                         auth_finished(AUTH_VALID);
  3550.                     else
  3551. #endif /* CK_LOGIN */
  3552.                         auth_finished(AUTH_USER);
  3553.                 }
  3554.                 else {
  3555.                     szUserNameRequested[0] = '\0';
  3556.                     auth_finished(AUTH_REJECT);
  3557.                 }
  3558.             }
  3559.             }
  3560.         }
  3561.     } else {
  3562.         char * str=NULL;
  3563.  
  3564.         if (tn_deb || debses)
  3565.             tn_debug("[TLS - handshake starting]");
  3566.         else if ( verbosity )
  3567.             printf("[TLS - handshake starting]\r\n");
  3568.         debug(F110,"ck_tn_tls_negotiate","[TLS - handshake starting]",0);
  3569.  
  3570.         /* right ... now we drop into the SSL library */
  3571.         if (!tls_only_flag) {
  3572.             char *subject=NULL, *issuer=NULL, *commonName=NULL, *dNSName=NULL;
  3573.  
  3574.             if (ssl_dummy_flag) {
  3575.                 if (tn_deb || debses)
  3576.                     tn_debug("[TLS - Dummy Connected]");
  3577.                 else if ( verbosity ) {
  3578.                     printf("[TLS - Dummy Connected]\r\n");
  3579.                 }
  3580.                 debug(F110,"ck_tn_tls_negotiate","[TLS - Dummy Connected]",0);
  3581.                 auth_finished(AUTH_REJECT);
  3582.                 accept_complete = 1;
  3583.                 return 0;
  3584.             }
  3585.  
  3586. #ifndef USE_CERT_CB
  3587.             if (!tls_load_certs(tls_ctx,tls_con,0))
  3588.                 return(-1);
  3589. #endif /* USE_CERT_CB */
  3590.             if (SSL_connect(tls_con) <= 0) {
  3591.                 int len;
  3592.                 if (tn_deb || debses) {
  3593.                     tn_debug("[TLS - FAILED]");
  3594.                     ERR_print_errors(bio_err);
  3595.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3596.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3597.                     printf(ssl_err);
  3598.                 } else if ( verbosity ) {
  3599.                     printf("[TLS - FAILED]\r\n");
  3600.                     ERR_print_errors(bio_err);
  3601.                     len = BIO_read(bio_err,ssl_err,SSL_ERR_BFSZ);
  3602.                     ssl_err[len < SSL_ERR_BFSZ ? len : SSL_ERR_BFSZ] = '\0';
  3603.                     printf(ssl_err);
  3604.                 }
  3605.                 debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3606.                 auth_finished(AUTH_REJECT);
  3607.                 return -1;
  3608.             }
  3609.  
  3610.             tls_active_flag = 1;
  3611.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER)
  3612.                  && !tls_is_krb5(0)) {
  3613.                 char prmpt[1024];
  3614.                 subject = ssl_get_subject_name(tls_con);
  3615.  
  3616.                 if (!subject) {
  3617.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  3618.                     {
  3619.                         if (tn_deb || debses)
  3620.                             tn_debug("[TLS - FAILED]");
  3621.                         else if ( verbosity )
  3622.                             printf("[TLS - FAILED]\r\n");
  3623.                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3624.                         auth_finished(AUTH_REJECT);
  3625.                         return -1;
  3626.                     } else {
  3627.                         int ok;
  3628.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  3629.                                    "Continue? (Y/N)", 3, NULL, 0);
  3630.                         if (!ok) {
  3631.                             if (tn_deb || debses)
  3632.                                 tn_debug("[TLS - FAILED]");
  3633.                             else if ( verbosity )
  3634.                                 printf("[TLS - FAILED]\r\n");
  3635.                             debug(F110,
  3636.                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3637.                             auth_finished(AUTH_REJECT);
  3638.                             return -1;
  3639.                         }
  3640.                     }
  3641.                 } else if (ssl_check_server_name(tls_con, szHostName)) {
  3642.                     if (tn_deb || debses)
  3643.                         tn_debug("[TLS - FAILED]");
  3644.                     else if ( verbosity )
  3645.                         printf("[TLS - FAILED]\r\n");
  3646.                     debug(F110,
  3647.                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3648.                     auth_finished(AUTH_REJECT);
  3649.                     return -1;
  3650.                 }
  3651.             }
  3652.  
  3653.             if ( ssl_debug_flag && ssl_finished_messages) {
  3654.                 char msg[32];
  3655.                 int i, len=32;
  3656.                 extern char tn_msg[], hexbuf[];
  3657.  
  3658.                 tn_msg[0] = '\0';
  3659.                 len = ssl_get_client_finished(msg,len);
  3660.                 if ( len > 0 ) {
  3661.                     for ( i=0;i<len;i++ ) {
  3662.                         sprintf(hexbuf,"%02X ",msg[i]);
  3663.                         ckstrncat(tn_msg,hexbuf,TN_MSG_LEN);
  3664.                     }
  3665.                     printf("TLS client finished: %s\r\n",tn_msg);
  3666.                 }
  3667.                 tn_msg[0] = '\0';
  3668.                 len = ssl_get_server_finished(msg,len);
  3669.                 if ( len > 0 ) {
  3670.                     for ( i=0;i<len;i++ ) {
  3671.                         sprintf(hexbuf,"%02X ",msg[i]);
  3672.                         ckstrncat(tn_msg,hexbuf,TN_MSG_LEN);
  3673.                     }
  3674.                     printf("TLS server finished: %s\r\n",tn_msg);
  3675.                 }
  3676.             }
  3677.  
  3678.             if (tn_deb || debses)
  3679.                 tn_debug("[TLS - OK]");
  3680.             else if ( verbosity )
  3681.                 printf("[TLS - OK]\r\n");
  3682.             debug(F110,"ck_tn_tls_negotiate","[TLS - OK]",0);
  3683.  
  3684.             ssl_display_connect_details(tls_con,0,verbosity);
  3685.         }
  3686.         auth_finished(AUTH_REJECT);
  3687.     }
  3688.     accept_complete = 1;
  3689.     auth_ssl_valid = 1;
  3690.     return(0);
  3691. }
  3692.  
  3693. int
  3694. ck_ssl_incoming(fd) int fd;
  3695. {
  3696.     /* if we are not running in debug then any error
  3697.     * stuff from SSL debug *must* not go down
  3698.     * the socket (which 0,1,2 are all pointing to by
  3699.     * default)
  3700.     */
  3701.  
  3702.     int timo = 2000;
  3703.  
  3704.     setverbosity();
  3705.     if ( !ck_ssleay_is_installed() )
  3706.         return(-1);
  3707.  
  3708.     /* do the SSL stuff now ... before we play with pty's */
  3709.     SSL_set_fd(ssl_con,fd);
  3710.     SSL_set_fd(tls_con,fd);
  3711.  
  3712.     if (tls_only_flag) {
  3713.         if (tn_deb || debses)
  3714.             tn_debug("[TLS - handshake starting]");
  3715.         else if ( verbosity )
  3716.             printf("[TLS - handshake starting]\r\n");
  3717.         debug(F110,"ck_ssl_incoming","[TLS - handshake starting]",0);
  3718.  
  3719.         /* hmm ... only when running talking to things like
  3720.         * https servers should we hit this code and then
  3721.         * we really don't care *who* we talk to :-)
  3722.         */
  3723.         if (SSL_accept(tls_con) <= 0) {
  3724.             char errbuf[1024];
  3725.  
  3726.             sprintf(errbuf,"[TLS - SSL_accept error: %s",
  3727.                      ERR_error_string(ERR_get_error(),NULL));
  3728.  
  3729.             if (tn_deb || debses)
  3730.                 tn_debug(errbuf);
  3731.             else if ( ssl_debug_flag )
  3732.                 printf("%s\r\n",errbuf);
  3733.             else if ( verbosity )
  3734.                 printf("[TLS - SSL_accept error]\r\n");
  3735.  
  3736.             debug(F110,"ck_ssl_incoming",errbuf,0);
  3737.             return(-1);
  3738.         } else {
  3739.             if (tn_deb || debses)
  3740.                 tn_debug("[TLS - OK]");
  3741.             else if ( verbosity )
  3742.                 printf("[TLS - OK]\r\n");
  3743.             debug(F110,"ck_ssl_incoming","[TLS - OK]",0);
  3744.             tls_active_flag = 1;
  3745.         }
  3746.     } else if (ssl_only_flag) {
  3747.         if (tn_deb || debses)
  3748.             tn_debug("[SSL - handshake starting]");
  3749.         else if ( verbosity )
  3750.             printf("[SSL - handshake starting]\r\n");
  3751.         debug(F110,"ck_ssl_incoming","[SSL - handshake starting]",0);
  3752.  
  3753.         /* hmm ... only when running talking to things like
  3754.          * https servers should we hit this code and then
  3755.          * we really don't care *who* we talk to :-)
  3756.          */
  3757.         if (SSL_accept(ssl_con) <= 0) {
  3758.             char errbuf[1024];
  3759.  
  3760.             sprintf(errbuf,"[SSL - SSL_accept error: %s",
  3761.                      ERR_error_string(ERR_get_error(),NULL));
  3762.  
  3763.             if (tn_deb || debses)
  3764.                 tn_debug(errbuf);
  3765.             else if ( ssl_debug_flag )
  3766.                 printf("%s\r\n",errbuf);
  3767.             else if ( verbosity )
  3768.                 printf("[SSL - SSL_accept error]\r\n");
  3769.  
  3770.             debug(F110,"ck_ssl_incoming",errbuf,0);
  3771.             return(-1);
  3772.         } else {
  3773.             if (tn_deb || debses)
  3774.                 tn_debug("[SSL - OK]");
  3775.             else if ( verbosity )
  3776.             printf("[SSL - OK]\r\n");
  3777.             debug(F110,"ssl_is","[SSL - OK]",0);
  3778.             ssl_active_flag = 1;
  3779.         }
  3780.     }
  3781.     if (ssl_active_flag || tls_active_flag) {
  3782.         X509 *peer;
  3783.         char str[256], *uid=NULL;
  3784.  
  3785.         /* now check to see that we got exactly what we
  3786.          * wanted from the caller ... if a certificate is
  3787.          * required then we make 100% sure that we were
  3788.          * given on during the handshake (as it is an optional
  3789.          * part of SSL and TLS)
  3790.          */
  3791.  
  3792.         if ( tls_active_flag ) {
  3793.             peer=SSL_get_peer_certificate(tls_con);
  3794.         } else if ( ssl_active_flag ) {
  3795.             peer=SSL_get_peer_certificate(ssl_con);
  3796.         }
  3797.  
  3798.         if (peer == NULL) {
  3799.             debug(F100,"SSL_get_peer_certificate() == NULL","",0);
  3800.             auth_finished(AUTH_REJECT);
  3801.  
  3802.             if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
  3803.                 if (tn_deb || debses)
  3804.                     tn_debug("[SSL/TLS - peer check failed]");
  3805.                 else if (ssl_debug_flag) {
  3806.                     printf("[SSL/TLS - peer check failed]\r\n");
  3807.                 }
  3808.                 debug(F110,
  3809.                        "ck_tn_tls_negotiate",
  3810.                        "[SSL/TLS - peer check failed]",
  3811.                        0
  3812.                        );
  3813.                 /* LOGGING REQUIRED HERE! */
  3814.                 return -1;
  3815.             }
  3816.  
  3817.         } else {
  3818.             debug(F100,"SSL_get_peer_certificate() != NULL","",0);
  3819.             X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3820.                                        NID_commonName,str,
  3821.                                        256
  3822.                                        );
  3823.             printf("[TLS - commonName=%s]\r\n",str);
  3824.  
  3825.             X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
  3826. #ifndef NID_x500UniqueIdentifier
  3827.                                        NID_uniqueIdentifier,
  3828. #else   
  3829.                                        NID_x500UniqueIdentifier,
  3830. #endif
  3831.                                        str,256
  3832.                                        );
  3833.             printf("[TLS - uniqueIdentifier=%s]\r\n",str);
  3834.  
  3835.             /* Try to determine user name */
  3836.             uid = tls_userid_from_client_cert(tls_con);
  3837.             if ( uid ) {
  3838.                 /* This code is very questionable.
  3839.                 * How should it behave?
  3840.                 * The client has presented a certificate that
  3841.                 * contains a username.  We have validated the
  3842.                 * certificate but we do not automatically
  3843.                 * log the user in unless there is a .tlslogin
  3844.                 * file.
  3845.                 */
  3846.  
  3847.                 ckstrncpy(szUserNameRequested,uid,UIDBUFLEN);
  3848. #ifdef CK_LOGIN
  3849.                 if (zvuser(uid))
  3850.                     auth_finished(AUTH_VALID);
  3851.                 else
  3852. #endif /* CK_LOGIN */
  3853.                     auth_finished(AUTH_USER);
  3854.             }
  3855.             else {
  3856.                 szUserNameRequested[0] = '\0';
  3857.                 auth_finished(AUTH_REJECT);
  3858.             }
  3859.         }
  3860.     }
  3861.     return(0);  /* success */
  3862. }
  3863.  
  3864. int
  3865. ck_ssl_outgoing(fd) int fd;
  3866. {
  3867.     int timo = 2000;
  3868.  
  3869.     setverbosity();
  3870.     if ( !ck_ssleay_is_installed() )
  3871.         return(-1);
  3872.  
  3873.     /* bind in the network descriptor */
  3874.     SSL_set_fd(ssl_con,fd);
  3875.     SSL_set_fd(tls_con,fd);
  3876.  
  3877.     /* If we are doing raw TLS then start it now ... */
  3878.     if (tls_only_flag) {
  3879. #ifndef USE_CERT_CB
  3880.         if (!tls_load_certs(tls_ctx,tls_con,0)) {
  3881.             debug(F110,"ck_ssl_outgoing","tls_load_certs() failed",0);
  3882.             return(-1);
  3883.         }
  3884. #endif /* USE_CERT_CB */
  3885.         if (tn_deb || debses)
  3886.             tn_debug("[TLS - handshake starting]");
  3887.         else if (verbosity)
  3888.             printf("[TLS - handshake starting]\r\n");
  3889.         debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
  3890.         if (SSL_connect(tls_con) <= 0) {
  3891.             char errbuf[1024];
  3892.  
  3893.             sprintf(errbuf,"[TLS - SSL_connect error: %s",
  3894.                      ERR_error_string(ERR_get_error(),NULL));
  3895.  
  3896.             if (tn_deb || debses)
  3897.                 tn_debug(errbuf);
  3898.             else if ( ssl_debug_flag )
  3899.                 printf("%s\r\n",errbuf);
  3900.  
  3901.             if (tn_deb || debses)
  3902.                 tn_debug("[TLS - FAILED]");
  3903.             else if ( verbosity )
  3904.                 printf("[TLS - FAILED]\r\n");
  3905.             debug(F110,"ck_ssl_outgoing","[TLS - FAILED]",0);
  3906.             netclos();
  3907.             return(-1);
  3908.         } else {
  3909.             tls_active_flag = 1;
  3910.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) && 
  3911.                  !tls_is_krb5(0) ) {
  3912.                 char *subject = ssl_get_subject_name(tls_con);
  3913.  
  3914.                 if (!subject) {
  3915.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  3916.                     {
  3917.                         if (tn_deb || debses)
  3918.                             tn_debug("[TLS - FAILED]");
  3919.                         else if ( verbosity )
  3920.                             printf("[TLS - FAILED]\r\n");
  3921.                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3922.  
  3923.                         auth_finished(AUTH_REJECT);
  3924.                         return -1;
  3925.                     } else {
  3926.                         char prmpt[1024];
  3927.                         int ok;
  3928.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  3929.                                    "Continue? (Y/N)", 3, NULL, 0);
  3930.                         if (!ok) {
  3931.                             if (tn_deb || debses)
  3932.                                 tn_debug("[TLS - FAILED]");
  3933.                             else if ( verbosity )
  3934.                                 printf("[TLS - FAILED]\r\n");
  3935.                             debug(F110,
  3936.                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3937.                             auth_finished(AUTH_REJECT);
  3938.                             return -1;
  3939.                         }
  3940.                     }
  3941.                 } else if (ssl_check_server_name(tls_con, szHostName)) {
  3942.                     if (tn_deb || debses)
  3943.                         tn_debug("[TLS - FAILED]");
  3944.                     else if ( verbosity )
  3945.                         printf("[TLS - FAILED]\r\n");
  3946.                     debug(F110,
  3947.                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  3948.                     auth_finished(AUTH_REJECT);
  3949.                     return -1;
  3950.                 }
  3951.             }
  3952.             if (tn_deb || debses)
  3953.                 tn_debug("[TLS - OK]");
  3954.             else if (!quiet)
  3955.         printf("[TLS - OK]\r\n");
  3956.             debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
  3957.             ssl_display_connect_details(tls_con,0,verbosity);
  3958.         }
  3959.     }
  3960.     /* if we are doing raw SSL then start it now ... */
  3961.     else if (ssl_only_flag) {
  3962. #ifndef USE_CERT_CB
  3963.         if (!tls_load_certs(ssl_ctx,ssl_con,0))
  3964.             return(-1);
  3965. #endif /* USE_CERT_CB */
  3966.         if (tn_deb || debses)
  3967.             tn_debug("[SSL - handshake starting]");
  3968.         else if ( verbosity )
  3969.             printf("[SSL - handshake starting]\r\n");
  3970.         debug(F110,"ck_ssl_outgoing","[SSL - handshake starting]",0);
  3971.         if (SSL_connect(ssl_con) <= 0) {
  3972.             if ( ssl_debug_flag ) {
  3973.                 char errbuf[1024];
  3974.  
  3975.                 sprintf(errbuf,"[SSL - SSL_connect error: %s",
  3976.                          ERR_error_string(ERR_get_error(),NULL));
  3977.                 printf("%s\r\n",errbuf);
  3978.             }
  3979.             if (tn_deb || debses)
  3980.                 tn_debug("[SSL - FAILED]");
  3981.             else if ( verbosity )
  3982.                 printf("[SSL - FAILED]\r\n");
  3983.             debug(F110,"ck_ssl_outgoing","[SSL - FAILED]",0);
  3984.             return(-1);
  3985.         } else {
  3986.             ssl_active_flag = 1;
  3987.  
  3988.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) &&
  3989.                  !tls_is_krb5(0)) {
  3990.                 char *subject = ssl_get_subject_name(ssl_con);
  3991.  
  3992.                 if (!subject) {
  3993.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  3994.                     {
  3995.                         if (tn_deb || debses)
  3996.                             tn_debug("[SSL - FAILED]");
  3997.                         else if ( verbosity )
  3998.                             printf("[SSL - FAILED]\r\n");
  3999.                         debug(F110,"ck_tn_tls_negotiate","[SSL - FAILED]",0);
  4000.  
  4001.                         auth_finished(AUTH_REJECT);
  4002.                         return -1;
  4003.                     } else {
  4004.                         char prmpt[1024];
  4005.                         int ok;
  4006.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  4007.                                    "Continue? (Y/N)", 3, NULL, 0);
  4008.                         if (!ok) {
  4009.                             if (tn_deb || debses)
  4010.                                 tn_debug("[SSL - FAILED]");
  4011.                             else if ( verbosity )
  4012.                                 printf("[SSL - FAILED]\r\n");
  4013.                             debug(F110,
  4014.                                    "ck_tn_tls_negotiate","[SSL - FAILED]",0);
  4015.                             auth_finished(AUTH_REJECT);
  4016.                             return -1;
  4017.                         }
  4018.                     }
  4019.                 } else if (ssl_check_server_name(ssl_con, szHostName)) {
  4020.                     if (tn_deb || debses)
  4021.                         tn_debug("[SSL - FAILED]");
  4022.                     else if ( verbosity )
  4023.                         printf("[SSL - FAILED]\r\n");
  4024.                     debug(F110, "ck_tn_tls_negotiate","[SSL - FAILED]",0);
  4025.                     auth_finished(AUTH_REJECT);
  4026.                     return -1;
  4027.                 }
  4028.             }
  4029.             if (tn_deb || debses)
  4030.                 tn_debug("[SSL - OK]");
  4031.         else if (!quiet)
  4032.             printf("[SSL - OK]\r\n");
  4033.             debug(F110,"ck_ssl_outgoing","[SSL - OK]",0);
  4034.             ssl_display_connect_details(ssl_con,0,verbosity);
  4035.         }
  4036.     }
  4037.     return(0);  /* success */
  4038. }
  4039.  
  4040. #ifndef NOHTTP
  4041. int
  4042. ck_ssl_http_client(fd, hostname) int fd; char * hostname;
  4043. {
  4044.     int timo = 2000;
  4045.  
  4046.     if ( !ck_ssleay_is_installed() )
  4047.         return(-1);
  4048.  
  4049.     setverbosity();
  4050.  
  4051.     /* bind in the network descriptor */
  4052.     SSL_set_fd(tls_http_con,fd);
  4053.  
  4054.     /* If we are doing raw TLS then start it now ... */
  4055.     if (1) {
  4056. #ifndef USE_CERT_CB
  4057.         if (!tls_load_certs(tls_http_ctx,tls_http_con,0)) {
  4058.             debug(F110,"ck_ssl_http_client","tls_load_certs() failed",0);
  4059.             return(-1);
  4060.         }
  4061. #endif /* USE_CERT_CB */
  4062.         if (tn_deb || debses)
  4063.             tn_debug("[TLS - handshake starting]");
  4064.         else if (verbosity)
  4065.             printf("[TLS - handshake starting]\r\n");
  4066.         debug(F110,"ck_ssl_outgoing","[TLS - handshake starting]",0);
  4067.         if (SSL_connect(tls_http_con) <= 0) {
  4068.             char errbuf[1024];
  4069.  
  4070.             sprintf(errbuf,"[TLS - SSL_connect error: %s",
  4071.                      ERR_error_string(ERR_get_error(),NULL));
  4072.  
  4073.             if (tn_deb || debses)
  4074.                 tn_debug(errbuf);
  4075.             else if ( ssl_debug_flag )
  4076.                 printf("%s\r\n",errbuf);
  4077.  
  4078.             if (tn_deb || debses)
  4079.                 tn_debug("[TLS - FAILED]");
  4080.             else if ( verbosity )
  4081.                 printf("[TLS - FAILED]\r\n");
  4082.             debug(F110,"ck_ssl_http_client","[TLS - FAILED]",0);
  4083.             http_close();
  4084.             return(-1);
  4085.         } else {
  4086.             tls_http_active_flag = 1;
  4087.             if ( !ssl_certsok_flag && (ssl_verify_flag & SSL_VERIFY_PEER) &&
  4088.                  !tls_is_krb5(3) ) {
  4089.                 char *subject = ssl_get_subject_name(tls_http_con);
  4090.  
  4091.                 if (!subject) {
  4092.                     if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
  4093.                     {
  4094.                         if (tn_deb || debses)
  4095.                             tn_debug("[TLS - FAILED]");
  4096.                         else if ( verbosity )
  4097.                             printf("[TLS - FAILED]\r\n");
  4098.                         debug(F110,"ck_tn_tls_negotiate","[TLS - FAILED]",0);
  4099.                         return -1;
  4100.                     } else {
  4101.                         char prmpt[1024];
  4102.                         int ok;
  4103.                         ok = uq_ok("Warning: Server didn't provide a certificate",
  4104.                                    "Continue? (Y/N)", 3, NULL, 0);
  4105.                         if (!ok) {
  4106.                             if (tn_deb || debses)
  4107.                                 tn_debug("[TLS - FAILED]");
  4108.                             else if ( verbosity )
  4109.                                 printf("[TLS - FAILED]\r\n");
  4110.                             debug(F110,
  4111.                                    "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  4112.                             return -1;
  4113.                         }
  4114.                     }
  4115.                 } else if (ssl_check_server_name(tls_http_con, hostname)) {
  4116.                     if (tn_deb || debses)
  4117.                         tn_debug("[TLS - FAILED]");
  4118.                     else if ( verbosity )
  4119.                         printf("[TLS - FAILED]\r\n");
  4120.                     debug(F110,
  4121.                            "ck_tn_tls_negotiate","[TLS - FAILED]",0);
  4122.                     return -1;
  4123.                 }
  4124.             }
  4125.  
  4126.             printf("[TLS - OK]\r\n");
  4127.             if (tn_deb || debses)
  4128.                 tn_debug("[TLS - OK]");
  4129.             debug(F110,"ck_ssl_outgoing","[TLS - OK]",0);
  4130.             ssl_display_connect_details(tls_http_con,0,verbosity);
  4131.         }
  4132.     }
  4133.     return(0);  /* success */
  4134. }
  4135. #endif /* NOHTTP */
  4136. int
  4137. ck_ssl_renegotiate_ciphers()
  4138. {
  4139.  
  4140.     if ( !ck_ssleay_is_installed() )
  4141.         return(0);
  4142.  
  4143.     if ( !sstelnet )
  4144.         return(0);
  4145.  
  4146.     if ( ssl_active_flag )
  4147.         return SSL_renegotiate(ssl_con);
  4148.     else if ( tls_active_flag )
  4149.         return SSL_renegotiate(tls_con);
  4150.     return(0);
  4151. }
  4152.  
  4153. #ifdef NT
  4154. int 
  4155. ck_X509_save_cert_to_user_store(X509 *cert)
  4156. {
  4157. #ifdef X509V3_EXT_DUMP_UNKNOWN
  4158.     char path[CKMAXPATH];
  4159.     char hash[16];
  4160.     char * GetAppData(int);
  4161.     BIO * out=NULL;
  4162.  
  4163.     if ( cert == NULL )
  4164.         return(0);
  4165.  
  4166.     sprintf(hash,"%08lx",X509_subject_name_hash(cert));
  4167.     ckmakmsg(path,CKMAXPATH,GetAppData(0),"kermit 95/certs/",
  4168.              hash,".0");
  4169.  
  4170.     
  4171.     out=BIO_new(BIO_s_file());
  4172.     if (out == NULL)
  4173.     {
  4174.         ERR_print_errors(bio_err);
  4175.         return(0);
  4176.     }
  4177.     if (BIO_write_filename(out,path) <= 0) {
  4178.         perror(path);
  4179.         return(0);
  4180.     }
  4181.  
  4182.     X509_print_ex(out, cert, XN_FLAG_SEP_MULTILINE, X509V3_EXT_DUMP_UNKNOWN);
  4183.     if (!PEM_write_bio_X509(out,cert)) {
  4184.         BIO_printf(bio_err,"unable to write certificate\n");
  4185.         ERR_print_errors(bio_err);
  4186.         BIO_free_all(out);
  4187.         return(0);
  4188.     }
  4189.     BIO_free_all(out);
  4190.     return(1);
  4191. #else /* X509V3_EXT_DUMP_UNKNOWN */
  4192.     return(0);
  4193. #endif /* X509V3_EXT_DUMP_UNKNOWN */
  4194. }
  4195. #endif /* NT */
  4196.  
  4197. #ifndef OS2
  4198. /* The following function should be replaced by institution specific */
  4199. /* code that will convert an X509 cert structure to a userid for the */
  4200. /* purposes of client to host login.  The example code included      */
  4201. /* simply returns the UID field of the Subject if it exists.         */
  4202.  
  4203. /* X509_to_user() returns 0 if valid userid in 'userid', else -1 */
  4204. int
  4205. X509_to_user(X509 *peer_cert, char *userid, int len)
  4206. {
  4207. #ifdef X509_UID_TO_USER
  4208.     /* BEGIN EXAMPLE */
  4209.     int err;
  4210.  
  4211.     if (!(peer_cert && userid) || len <= 0)
  4212.         return -1;
  4213.  
  4214.     userid[0] = '\0';
  4215.     debug(F110,"X509_to_user() subject",
  4216.            X509_NAME_oneline(X509_get_subject_name(peer_cert),NULL,0),0);
  4217.  
  4218.     /* userid is in cert subject /UID */
  4219.     err = X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
  4220. #ifndef NID_x500UniqueIdentifier
  4221.                                      NID_uniqueIdentifier,
  4222. #else
  4223.                                      NID_x500UniqueIdentifier,
  4224. #endif
  4225.                                      userid, len);
  4226.  
  4227.     debug(F111,"X509_to_user() userid",userid,err);
  4228.     if (err > 0)
  4229.         return 0;
  4230.  
  4231.     /* END EXAMPLE */
  4232. #else /* X509_UID_TO_USER */
  4233. #ifdef X509_SUBJECT_ALT_NAME_TO_USER
  4234.     /* BEGIN EXAMPLE */
  4235.     int i;
  4236.     X509_EXTENSION *ext = NULL;
  4237.     STACK_OF(GENERAL_NAME) *ialt = NULL;
  4238.     GENERAL_NAME *gen = NULL;
  4239.     char email[256];
  4240.  
  4241.     if (!(peer_cert && userid) || len <= 0)
  4242.         return -1;
  4243.  
  4244.     userid[0] = '\0';
  4245.     email[0] = '\0';
  4246.     debug(F110,"X509_to_user() subject",
  4247.            X509_NAME_oneline(X509_get_subject_name(peer_cert),NULL,0),0);
  4248.  
  4249.     if ((i = X509_get_ext_by_NID(peer_cert, NID_subject_alt_name, -1))<0)
  4250.         return -1;
  4251.     if (!(ext = X509_get_ext(peer_cert, i)))
  4252.         return -1;
  4253.     X509V3_add_standard_extensions();
  4254.     if (!(ialt = X509V3_EXT_d2i(ext)))
  4255.         return -1;
  4256.     for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
  4257.         gen = sk_GENERAL_NAME_value(ialt, i);
  4258.         if (gen->type == GEN_DNS) {
  4259.             if (!gen->d.ia5 || !gen->d.ia5->length)
  4260.           break;
  4261.             if (strlen(gen->d.ia5->data) != gen->d.ia5->length) {
  4262.                 /* Ignoring IA5String containing null character */
  4263.                 continue;
  4264.             }
  4265.             if ( gen->d.ia5->length + 1 > sizeof(email) ) {
  4266.                 goto cleanup;
  4267.             }
  4268.             memcpy(email, gen->d.ia5->data, gen->d.ia5->length);
  4269.             email[gen->d.ia5->length] = 0;
  4270.             break;
  4271.         }
  4272.     }
  4273.   cleanup:
  4274.     X509V3_EXT_cleanup();
  4275.     if (ialt)
  4276.         sk_GENERAL_NAME_free(ialt);
  4277.  
  4278.     debug(F110,"X509_to_user() email",email,0);
  4279.  
  4280.     if ( email[0] ) {
  4281.         char * domain = NULL;
  4282.  
  4283.         /* Find domain */
  4284.         for ( i=0 ; email[i] ; i++ ) {
  4285.             if ( email[i] == '@' ) {
  4286.                 email[i] = '\0';
  4287.                 domain = &email[i+1];
  4288.                 break;
  4289.             }
  4290.         }
  4291.  
  4292.         if ( domain ) {
  4293.             /* XXX - Put code to Verify domain here */
  4294.  
  4295.             if ( /* domain is okay */ 1 )
  4296.                 ckstrncpy(userid,email,len);
  4297.         }
  4298.     }
  4299.  
  4300.     return(userid[0] ? 0 : -1);
  4301.     /* END EXAMPLE */
  4302. #endif /* X509_SUBJECT_ALT_NAME_TO_USER */
  4303. #endif /* X509_UID_TO_USER */
  4304.     return -1;
  4305. }
  4306.  
  4307. /* The following function should be replaced by institution specific */
  4308. /* code that will determine whether or not the combination of the    */
  4309. /* provided X509 certificate and username is valid for automatic     */
  4310. /* login.   Whereas X509_to_user() is used to provide authentication */
  4311. /* of the user, the X509_userok() function is used to provide        */
  4312. /* authorization.  The certificate passed into X509_userok() does    */
  4313. /* need to map to a userid; nor would the userid it would map to     */
  4314. /* need to match the userid provided to the function.  There are     */
  4315. /* numerous circumstances in which it is beneficial to have the ability */
  4316. /* for multiple users to gain access to a common account such as     */
  4317. /* 'root' on Unix; or a class account on a web server.  In Unix we   */
  4318. /* implement this capability with the ~userid/.tlslogin file which   */
  4319. /* a list of X509 certificates which may be used to access the       */
  4320. /* account 'userid'.                                                 */
  4321.  
  4322. /* X509_to_user() returns 0 if access is denied; 1 is access is permitted */
  4323. int
  4324. X509_userok(X509 * peer_cert, const char * userid)
  4325. {
  4326. #ifndef VMS
  4327.     /* check if clients cert is in "user"'s ~/.tlslogin file */
  4328.     char buf[512];
  4329.     int r = 0;
  4330.     FILE *fp;
  4331.     struct passwd *pwd;
  4332.     X509 *file_cert;
  4333.  
  4334.     if ( peer_cert == NULL )
  4335.         return(0);
  4336.  
  4337.     if (!(pwd = getpwnam(userid)))
  4338.        return 0;
  4339.     if (strlen(pwd->pw_dir) > 500)
  4340.        return(0);
  4341.     sprintf(buf, "%s/.tlslogin", pwd->pw_dir);
  4342.  
  4343.     if (!(fp = fopen(buf, "r")))
  4344.         return 0;
  4345.     while (!r && (file_cert = PEM_read_X509(fp, NULL, NULL, NULL))) {
  4346.         if (!ASN1_STRING_cmp(peer_cert->signature, file_cert->signature))
  4347.             r = 1;
  4348.         X509_free(file_cert);
  4349.     }
  4350.     fclose(fp);
  4351.     return(r);
  4352. #else /* VMS */
  4353.     /* Need to implement an appropriate function for VMS */
  4354.     return(0);
  4355. #endif /* VMS */
  4356. }
  4357. #endif /* OS2 */
  4358. #endif /* CK_SSL */
  4359.