/[cvs]/eggdrop1.8/src/tls.c
ViewVC logotype

Diff of /eggdrop1.8/src/tls.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.2.2.3 by pseudo, Sat Apr 19 17:41:59 2014 UTC revision 1.6 by pseudo, Thu Feb 3 15:44:11 2011 UTC
# Line 126  int ssl_init() Line 126  int ssl_init()
126    SSL_library_init();    SSL_library_init();
127    
128    if (ssl_seed()) {    if (ssl_seed()) {
129      putlog(LOG_MISC, "*", _("TLS: unable to seed PRNG. Disabling SSL"));      putlog(LOG_MISC, "*", "TLS: unable to seed PRNG. Disabling SSL");
130      ERR_free_strings();      ERR_free_strings();
131      return -2;      return -2;
132    }    }
# Line 134  int ssl_init() Line 134  int ssl_init()
134       supported protocols (SSLv2, SSLv3, and TLSv1) */       supported protocols (SSLv2, SSLv3, and TLSv1) */
135    if (!(ssl_ctx = SSL_CTX_new(SSLv23_method()))) {    if (!(ssl_ctx = SSL_CTX_new(SSLv23_method()))) {
136      debug0(ERR_error_string(ERR_get_error(), NULL));      debug0(ERR_error_string(ERR_get_error(), NULL));
137      putlog(LOG_MISC, "*", _("TLS: unable to create context. Disabling SSL."));      putlog(LOG_MISC, "*", "TLS: unable to create context. Disabling SSL.");
138      ERR_free_strings();      ERR_free_strings();
139      return -1;      return -1;
140    }    }
141    /* Load our own certificate and private key. Mandatory for acting as    /* Load our own certificate and private key. Mandatory for acting as
142       server, because we don't support anonymous ciphers by default. */       server, because we don't support anonymous ciphers by default. */
143    if (SSL_CTX_use_certificate_chain_file(ssl_ctx, tls_certfile) != 1)    if (SSL_CTX_use_certificate_chain_file(ssl_ctx, tls_certfile) != 1)
144      debug1(_("TLS: unable to load own certificate: %s"),      debug1("TLS: unable to load own certificate: %s",
145             ERR_error_string(ERR_get_error(), NULL));             ERR_error_string(ERR_get_error(), NULL));
146    if (SSL_CTX_use_PrivateKey_file(ssl_ctx, tls_keyfile,    if (SSL_CTX_use_PrivateKey_file(ssl_ctx, tls_keyfile,
147        SSL_FILETYPE_PEM) != 1)        SSL_FILETYPE_PEM) != 1)
148      debug1(_("TLS: unable to load private key: %s"),      debug1("TLS: unable to load private key: %s",
149             ERR_error_string(ERR_get_error(), NULL));             ERR_error_string(ERR_get_error(), NULL));
150    if ((tls_capath[0] || tls_cafile[0]) &&    if ((tls_capath[0] || tls_cafile[0]) &&
151        !SSL_CTX_load_verify_locations(ssl_ctx, tls_cafile[0] ? tls_cafile : NULL,        !SSL_CTX_load_verify_locations(ssl_ctx, tls_cafile[0] ? tls_cafile : NULL,
152        tls_capath[0] ? tls_capath : NULL))        tls_capath[0] ? tls_capath : NULL))
153      debug1(_("TLS: unable to set CA certificates location: %s"),      debug1("TLS: unable to set CA certificates location: %s",
154             ERR_error_string(ERR_get_error(), NULL));             ERR_error_string(ERR_get_error(), NULL));
155    /* Let advanced users specify the list of allowed ssl ciphers */    /* Let advanced users specify the list of allowed ssl ciphers */
156    if (tls_ciphers[0])    if (tls_ciphers[0])
157      if (!SSL_CTX_set_cipher_list(ssl_ctx, tls_ciphers)) {      if (!SSL_CTX_set_cipher_list(ssl_ctx, tls_ciphers)) {
158        /* this replaces any preset ciphers so an invalid list is fatal */        /* this replaces any preset ciphers so an invalid list is fatal */
159        putlog(LOG_MISC, "*", _("TLS: no valid ciphers found. Disabling SSL."));        putlog(LOG_MISC, "*", "TLS: no valid ciphers found. Disabling SSL.");
160        ERR_free_strings();        ERR_free_strings();
161        SSL_CTX_free(ssl_ctx);        SSL_CTX_free(ssl_ctx);
162        ssl_ctx = NULL;        ssl_ctx = NULL;
# Line 352  static int ssl_verifycn(X509 *cert, ssl_ Line 352  static int ssl_verifycn(X509 *cert, ssl_
352      /* the following is just for information */      /* the following is just for information */
353      switch (crit) {      switch (crit) {
354        case 0:        case 0:
355          debug0(_("TLS: X509 subjectAltName cannot be decoded"));          debug0("TLS: X509 subjectAltName cannot be decoded");
356          break;          break;
357        case -1:        case -1:
358          debug0(_("TLS: X509 has no subjectAltName extension"));          debug0("TLS: X509 has no subjectAltName extension");
359          break;          break;
360        case -2:        case -2:
361          debug0(_("TLS: X509 has multiple subjectAltName extensions"));          debug0("TLS: X509 has multiple subjectAltName extensions");
362      }      }
363      /* no subject name either? A completely broken certificate :) */      /* no subject name either? A completely broken certificate :) */
364      if (!(subj = X509_get_subject_name(cert))) {      if (!(subj = X509_get_subject_name(cert))) {
365        putlog(data->loglevel, "*", _("TLS: peer certificate has no subject: %s"),        putlog(data->loglevel, "*", "TLS: peer certificate has no subject: %s",
366               data->host);               data->host);
367        match = 0;        match = 0;
368      } else { /* we have a subject name, look at it */      } else { /* we have a subject name, look at it */
# Line 372  static int ssl_verifycn(X509 *cert, ssl_ Line 372  static int ssl_verifycn(X509 *cert, ssl_
372        /* Look for commonName attributes in the subject name */        /* Look for commonName attributes in the subject name */
373        pos = X509_NAME_get_index_by_NID(subj, NID_commonName, pos);        pos = X509_NAME_get_index_by_NID(subj, NID_commonName, pos);
374        if (pos == -1) /* sorry */        if (pos == -1) /* sorry */
375          putlog(data->loglevel, "*", _("TLS: Peer has no common names and "          putlog(data->loglevel, "*", "TLS: Peer has no common names and "
376                "no subjectAltName extension. Verification failed."));                "no subjectAltName extension. Verification failed.");
377        /* Loop through all common names which may be present in the subject        /* Loop through all common names which may be present in the subject
378           name until we find a match. */           name until we find a match. */
379        while (!match && pos != -1) {        while (!match && pos != -1) {
380          name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, pos));          name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, pos));
381          cn = (char *) ASN1_STRING_data(name);          cn = (char *) ASN1_STRING_data(name);
382          if (ip)          if (ip)
383            match = a2i_IPADDRESS(cn) ? (ASN1_STRING_cmp(ip, a2i_IPADDRESS(cn)) ?            match = a2i_IPADDRESS(cn) ? (ASN1_STRING_cmp(ip, a2i_IPADDRESS(cn)) ? 0 : 1) : 0;
                                                        0 : 1) : 0;  
384          else          else
385            match = ssl_hostmatch(cn, data->host);            match = ssl_hostmatch(cn, data->host);
386          pos = X509_NAME_get_index_by_NID(subj, NID_commonName, pos);          pos = X509_NAME_get_index_by_NID(subj, NID_commonName, pos);
# Line 471  static void ssl_showcert(X509 *cert, int Line 470  static void ssl_showcert(X509 *cert, int
470    /* Subject and issuer names */    /* Subject and issuer names */
471    if ((name = X509_get_subject_name(cert))) {    if ((name = X509_get_subject_name(cert))) {
472      buf = ssl_printname(name);      buf = ssl_printname(name);
473      putlog(loglev, "*", _("TLS: certificate subject: %s"), buf);      putlog(loglev, "*", "TLS: certificate subject: %s", buf);
474      nfree(buf);      nfree(buf);
475    } else    } else
476      putlog(loglev, "*", _("TLS: cannot get subject name from certificate!"));      putlog(loglev, "*", "TLS: cannot get subject name from certificate!");
477    if ((name = X509_get_issuer_name(cert))) {    if ((name = X509_get_issuer_name(cert))) {
478      buf = ssl_printname(name);      buf = ssl_printname(name);
479      putlog(loglev, "*", _("TLS: certificate issuer: %s"), buf);      putlog(loglev, "*", "TLS: certificate issuer: %s", buf);
480      nfree(buf);      nfree(buf);
481    } else    } else
482      putlog(loglev, "*", _("TLS: cannot get issuer name from certificate!"));      putlog(loglev, "*", "TLS: cannot get issuer name from certificate!");
483        
484    /* Fingerprints */    /* Fingerprints */
485    X509_digest(cert, EVP_md5(), md, &len); /* MD5 hash */    X509_digest(cert, EVP_md5(), md, &len); /* MD5 hash */
486    if (len <= sizeof(md)) {    if (len <= sizeof(md)) {
487      buf = hex_to_string(md, len);      buf = hex_to_string(md, len);
488      putlog(loglev, "*", _("TLS: certificate MD5 Fingerprint: %s"), buf);      putlog(loglev, "*", "TLS: certificate MD5 Fingerprint: %s", buf);
489      OPENSSL_free(buf);      OPENSSL_free(buf);
490    }    }
491    X509_digest(cert, EVP_sha1(), md, &len); /* SHA-1 hash */    X509_digest(cert, EVP_sha1(), md, &len); /* SHA-1 hash */
492    if (len <= sizeof(md)) {    if (len <= sizeof(md)) {
493      buf = hex_to_string(md, len);      buf = hex_to_string(md, len);
494      putlog(loglev, "*", _("TLS: certificate SHA1 Fingerprint: %s"), buf);      putlog(loglev, "*", "TLS: certificate SHA1 Fingerprint: %s", buf);
495      OPENSSL_free(buf);      OPENSSL_free(buf);
496    }    }
497    
498    /* Validity time */    /* Validity time */
499    from = ssl_printtime(X509_get_notBefore(cert));    from = ssl_printtime(X509_get_notBefore(cert));
500    to = ssl_printtime(X509_get_notAfter(cert));    to = ssl_printtime(X509_get_notAfter(cert));
501    putlog(loglev, "*", _("TLS: certificate valid from %s to %s"), from, to);    putlog(loglev, "*", "TLS: certificate valid from %s to %s", from, to);
502    nfree(from);    nfree(from);
503    nfree(to);        nfree(to);    
504  }  }
# Line 547  int ssl_verify(int ok, X509_STORE_CTX *c Line 546  int ssl_verify(int ok, X509_STORE_CTX *c
546       */       */
547      if (!(data->flags & TLS_DEPTH0) && !ssl_verifycn(cert, data) &&      if (!(data->flags & TLS_DEPTH0) && !ssl_verifycn(cert, data) &&
548          (data->verify & TLS_VERIFYCN)) {          (data->verify & TLS_VERIFYCN)) {
549          putlog(data->loglevel, "*", _("TLS: certificate validation failed. "          putlog(data->loglevel, "*", "TLS: certificate validation failed. "
550                 "Certificate subject does not match peer."));                 "Certificate subject does not match peer.");
551          return 0;          return 0;
552      }      }
553      data->flags |= TLS_DEPTH0;      data->flags |= TLS_DEPTH0;
# Line 565  int ssl_verify(int ok, X509_STORE_CTX *c Line 564  int ssl_verify(int ok, X509_STORE_CTX *c
564            (data->verify & TLS_VERIFYFROM)) ||            (data->verify & TLS_VERIFYFROM)) ||
565            ((err == X509_V_ERR_CERT_HAS_EXPIRED) &&            ((err == X509_V_ERR_CERT_HAS_EXPIRED) &&
566            (data->verify & TLS_VERIFYTO))) {            (data->verify & TLS_VERIFYTO))) {
567          debug1(_("TLS: peer certificate warning: %s"),          debug1("TLS: peer certificate warning: %s",
568                 X509_verify_cert_error_string(err));                 X509_verify_cert_error_string(err));
569          ok = 1;          ok = 1;
570        }        }
# Line 573  int ssl_verify(int ok, X509_STORE_CTX *c Line 572  int ssl_verify(int ok, X509_STORE_CTX *c
572    if (ok || !data->verify)    if (ok || !data->verify)
573      return 1;      return 1;
574    putlog(data->loglevel, "*",    putlog(data->loglevel, "*",
575           _("TLS: certificate validation failed at depth %d: %s"),           "TLS: certificate validation failed at depth %d: %s",
576           depth, X509_verify_cert_error_string(err));           depth, X509_verify_cert_error_string(err));
577    return 0;    return 0;
578  }  }
# Line 588  void ssl_info(SSL *ssl, int where, int r Line 587  void ssl_info(SSL *ssl, int where, int r
587    X509 *cert;    X509 *cert;
588    char buf[256];    char buf[256];
589    ssl_appdata *data;    ssl_appdata *data;
590    const SSL_CIPHER *cipher;    SSL_CIPHER *cipher;
591    int secret, processed;    int secret, processed;
592        
593    /* We're doing non-blocking IO, so we check here if the handshake has    /* We're doing non-blocking IO, so we check here if the handshake has
# Line 606  void ssl_info(SSL *ssl, int where, int r Line 605  void ssl_info(SSL *ssl, int where, int r
605      if (check_tcl_tls(sock))      if (check_tcl_tls(sock))
606        return;        return;
607    
608      putlog(data->loglevel, "*", _("TLS: handshake successful. "      putlog(data->loglevel, "*", "TLS: handshake successful. Secure connection "
609             "Secure connection established."));             "established.");
610    
611      if ((cert = SSL_get_peer_certificate(ssl)))      if ((cert = SSL_get_peer_certificate(ssl)))
612        ssl_showcert(cert, data->loglevel);        ssl_showcert(cert, data->loglevel);
613      else      else
614        putlog(data->loglevel, "*", _("TLS: peer did not present a certificate"));        putlog(data->loglevel, "*", "TLS: peer did not present a certificate");
615    
616      /* Display cipher information */      /* Display cipher information */
617      cipher = SSL_get_current_cipher(ssl);      cipher = SSL_get_current_cipher(ssl);
618      processed = SSL_CIPHER_get_bits(cipher, &secret);      processed = SSL_CIPHER_get_bits(cipher, &secret);
619      putlog(data->loglevel, "*", _("TLS: cipher used: %s %s; "      putlog(data->loglevel, "*", "TLS: cipher used: %s %s; %d bits (%d secret)",
620             "%d bits (%d secret)"), SSL_CIPHER_get_name(cipher),             SSL_CIPHER_get_name(cipher), SSL_CIPHER_get_version(cipher),
621             SSL_CIPHER_get_version(cipher), processed, secret);             processed, secret);
622      /* secret are the actually secret bits. If processed and secret differ,      /* secret are the actually secret bits. If processed and secret differ,
623         the rest of the bits are fixed, i.e. for limited export ciphers */         the rest of the bits are fixed, i.e. for limited export ciphers */
624    
625      /* More verbose information, for debugging only */      /* More verbose information, for debugging only */
626      SSL_CIPHER_description(cipher, buf, sizeof buf);      SSL_CIPHER_description(cipher, buf, sizeof buf);
627      debug1(_("TLS: cipher details: %s"), buf);      debug1("TLS: cipher details: %s", buf);
628    }    }
629    
630    /* Display the state of the engine for debugging purposes */    /* Display the state of the engine for debugging purposes */
# Line 656  int ssl_handshake(int sock, int flags, i Line 655  int ssl_handshake(int sock, int flags, i
655    ssl_appdata *data;    ssl_appdata *data;
656    struct threaddata *td = threaddata();    struct threaddata *td = threaddata();
657    
658    debug0(_("TLS: attempting SSL negotiation..."));    debug0("TLS: attempting SSL negotiation...");
659    if (!ssl_ctx && ssl_init()) {    if (!ssl_ctx && ssl_init()) {
660      debug0(_("TLS: Failed. OpenSSL not initialized properly."));      debug0("TLS: Failed. OpenSSL not initialized properly.");
661      return -1;      return -1;
662    }    }
663    /* find the socket in the list */    /* find the socket in the list */
664    i = findsock(sock);    i = findsock(sock);
665    if (i == -1) {    if (i == -1) {
666      debug0(_("TLS: socket not in socklist"));      debug0("TLS: socket not in socklist");
667      return -2;      return -2;
668    }    }
669    if (td->socklist[i].ssl) {    if (td->socklist[i].ssl) {
670      debug0(_("TLS: handshake not required - SSL session already established"));      debug0("TLS: handshake not required - SSL session already established");
671      return 0;      return 0;
672    }    }
673    td->socklist[i].ssl = SSL_new(ssl_ctx);    td->socklist[i].ssl = SSL_new(ssl_ctx);
674    if (!td->socklist[i].ssl ||    if (!td->socklist[i].ssl ||
675        !SSL_set_fd(td->socklist[i].ssl, td->socklist[i].sock)) {        !SSL_set_fd(td->socklist[i].ssl, td->socklist[i].sock)) {
676      debug1(_("TLS: cannot initiate SSL session - %s"),      debug1("TLS: cannot initiate SSL session - %s",
677             ERR_error_string(ERR_get_error(), 0));             ERR_error_string(ERR_get_error(), 0));
678      return -3;      return -3;
679    }    }
# Line 702  int ssl_handshake(int sock, int flags, i Line 701  int ssl_handshake(int sock, int flags, i
701      SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);      SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);
702      ret = SSL_connect(td->socklist[i].ssl);      ret = SSL_connect(td->socklist[i].ssl);
703      if (!ret)      if (!ret)
704        debug0(_("TLS: connect handshake failed."));        debug0("TLS: connect handshake failed.");
705    } else {    } else {
706      if (data->flags & TLS_VERIFYPEER)      if (data->flags & TLS_VERIFYPEER)
707        SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER |        SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER |
# Line 711  int ssl_handshake(int sock, int flags, i Line 710  int ssl_handshake(int sock, int flags, i
710        SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);        SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify);
711      ret = SSL_accept(td->socklist[i].ssl);      ret = SSL_accept(td->socklist[i].ssl);
712      if (!ret)      if (!ret)
713        debug0(_("TLS: accept handshake failed"));        debug0("TLS: accept handshake failed");
714    }    }
715    
716    err = SSL_get_error(td->socklist[i].ssl, ret);    err = SSL_get_error(td->socklist[i].ssl, ret);
717    /* Normal condition for async I/O, similar to EAGAIN */    /* Normal condition for async I/O, similar to EAGAIN */
718    if (ret > 0 || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {    if (ret > 0 || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
719      debug0(_("TLS: handshake in progress"));      debug0("TLS: handshake in progress");
720      return 0;      return 0;
721    }    }
722    if (ERR_peek_error())    if (ERR_peek_error())
723      debug0(_("TLS: handshake failed due to the following errors: "));      debug0("TLS: handshake failed due to the following errors: ");
724    while ((err = ERR_get_error()))    while ((err = ERR_get_error()))
725      debug1(_("TLS: %s"), ERR_error_string(err, NULL));      debug1("TLS: %s", ERR_error_string(err, NULL));
726    
727    /* Attempt failed, cleanup and abort */    /* Attempt failed, cleanup and abort */
728    SSL_shutdown(td->socklist[i].ssl);    SSL_shutdown(td->socklist[i].ssl);
# Line 793  static int tcl_tlsstatus STDVAR Line 792  static int tcl_tlsstatus STDVAR
792    char *p;    char *p;
793    int i, j;    int i, j;
794    X509 *cert;    X509 *cert;
795    const SSL_CIPHER *cipher;    SSL_CIPHER *cipher;
796    struct threaddata *td = threaddata();    struct threaddata *td = threaddata();
797    Tcl_DString ds;    Tcl_DString ds;
798    

Legend:
Removed from v.1.2.2.3  
changed lines
  Added in v.1.6

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23