SHARE
TWEET

Untitled

a guest Feb 27th, 2016 170 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.   void certificates_changed(Variable.Variable|void ignored,
  2.                 void|int ignore_eaddrinuse)
  3.   {
  4.     int old_cert_failure = cert_failure;
  5.  
  6.     string raw_keydata;
  7.     array(string) certificates = ({});
  8.     array(object) decoded_certs = ({});
  9.     Variable.Variable Certificates = getvar("ssl_cert_file");
  10.  
  11.     object privs = Privs("Reading cert file");
  12.  
  13.     foreach(map(Certificates->query(), String.trim_whites), string cert_file) {
  14.       string raw_cert;
  15.       SSL3_WERR (sprintf ("Reading cert file %O", cert_file));
  16.       if( catch{ raw_cert = lopen(cert_file, "r")->read(); } )
  17.       {
  18.     CERT_WARNING (Certificates,
  19.               LOC_M(8, "Reading certificate file %O failed: %s\n"),
  20.               cert_file, strerror (errno()));
  21.     continue;
  22.       }
  23.  
  24.       object msg = Tools.PEM.pem_msg()->init( raw_cert );
  25.       object part = msg->parts["CERTIFICATE"] ||
  26.     msg->parts["X509 CERTIFICATE"];
  27.       string cert;
  28.  
  29.       if (msg->parts["RSA PRIVATE KEY"] ||
  30.       msg->parts["DSA PRIVATE KEY"]) {
  31.     raw_keydata = raw_cert;
  32.       }
  33.  
  34.       if (!part || !(cert = part->decoded_body()))
  35.       {
  36.     CERT_WARNING (Certificates,
  37.               LOC_M(10, "No certificate found in %O.\n"),
  38.               cert_file);
  39.     continue;
  40.       }
  41.       certificates += ({ cert });
  42.  
  43.       // FIXME: Support PKCS7
  44.       object tbs = Tools.X509.decode_certificate (cert);
  45.       if (!tbs) {
  46.     CERT_WARNING (Certificates,
  47.               LOC_M(13, "Certificate not valid (DER).\n"));
  48.     continue;
  49.       }
  50.       decoded_certs += ({tbs});
  51.     }
  52.  
  53.     if (!sizeof(decoded_certs)) {
  54.       report_error ("TLS port %s: %s", get_url(),
  55.             LOC_M(63,"No certificates found.\n"));
  56.       cert_err_unbind();
  57.       cert_failure = 1;
  58.       return;
  59.     }
  60.  
  61.     Variable.Variable KeyFile = getvar("ssl_key_file");
  62.  
  63.     if( strlen(KeyFile->query())) {
  64.       SSL3_WERR (sprintf ("Reading key file %O", KeyFile->query()));
  65.       if (catch{ raw_keydata = lopen(KeyFile->query(), "r")->read(); } )
  66.     CERT_ERROR (KeyFile,
  67.             LOC_M(9, "Reading key file %O failed: %s\n"),
  68.             KeyFile->query(), strerror (errno()));
  69.     }
  70.     else
  71.       KeyFile = Certificates;
  72.  
  73.     privs = 0;
  74.  
  75.     if (!raw_keydata)
  76.       CERT_ERROR (KeyFile, LOC_M (17,"No private key found.\n"));
  77.  
  78.     object msg = Tools.PEM.pem_msg()->init( raw_keydata );
  79.  
  80.     SSL3_WERR(sprintf("key file contains: %O", indices(msg->parts)));
  81.  
  82.     object part;
  83.     if (part = msg->parts["RSA PRIVATE KEY"])
  84.     {
  85.       string key;
  86.  
  87.       if (!(key = part->decoded_body()))
  88.     CERT_ERROR (KeyFile,
  89.             LOC_M(11,"Private rsa key not valid")+" (PEM).\n");
  90.  
  91.       object rsa = Standards.PKCS.RSA.parse_private_key(key);
  92.       if (!rsa)
  93.     CERT_ERROR (KeyFile,
  94.             LOC_M(11,"Private rsa key not valid")+" (DER).\n");
  95.  
  96.       ctx->rsa = rsa;
  97.  
  98.       SSL3_WERR(sprintf("RSA key size: %d bits", rsa->rsa_size()));
  99.  
  100.       if (rsa->rsa_size() > 512)
  101.       {
  102.     /* Too large for export */
  103.     ctx->short_rsa = Crypto.RSA()->generate_key(512, ctx->random);
  104.  
  105.     // ctx->long_rsa = Crypto.RSA()->generate_key(rsa->rsa_size(), ctx->random);
  106.       }
  107.       ctx->rsa_mode();
  108.       filter_preferred_suites();
  109.  
  110.       array(int) key_matches =
  111.     map(decoded_certs,
  112.         lambda (object tbs) {
  113.           return tbs->public_key->rsa->public_key_equal (rsa);
  114.         });
  115.      
  116.       int num_key_matches;
  117.       // DWIM: Make sure the main cert comes first.
  118.       array(string) new_certificates = allocate(sizeof(certificates));
  119.       int i,j;
  120.       for (i=0; i < sizeof(certificates); i++) {
  121.     if (key_matches[i]) {
  122.       new_certificates[j++] = certificates[i];
  123.       num_key_matches++;
  124.     }
  125.       }
  126.       for (i=0; i < sizeof(certificates); i++) {
  127.     if (!key_matches[i]) {
  128.       new_certificates[j++] = certificates[i];
  129.     }
  130.       }
  131.       if( !num_key_matches )
  132.     CERT_ERROR (KeyFile,
  133.             LOC_M(14, "Certificate and private key do not match.\n"));
  134.       ctx->certificates = new_certificates;
  135.     }
  136.     else if (part = msg->parts["DSA PRIVATE KEY"])
  137.     {
  138.       string key;
  139.  
  140.       if (!(key = part->decoded_body()))
  141.     CERT_ERROR (KeyFile,
  142.             LOC_M(15,"Private dsa key not valid")+" (PEM).\n");
  143.  
  144.       object dsa = Standards.PKCS.DSA.parse_private_key(key);
  145.       if (!dsa)
  146.     CERT_ERROR (KeyFile,
  147.             LOC_M(15,"Private dsa key not valid")+" (DER).\n");
  148.  
  149.       SSL3_WERR(sprintf("Using DSA key."));
  150.  
  151.       //dsa->use_random(ctx->random);
  152.       ctx->dsa = dsa;
  153.       /* Use default DH parameters */
  154. #if constant(SSL.Cipher)
  155.       ctx->dh_params = SSL.Cipher.DHParameters();
  156. #else
  157.       ctx->dh_params = SSL.cipher()->dh_parameters();
  158. #endif
  159.  
  160.       ctx->dhe_dss_mode();
  161.       filter_preferred_suites();
  162.  
  163.       // FIXME: Add cert <-> private key check.
  164.  
  165.       ctx->certificates = certificates;
  166.     }
  167.     else
  168.       CERT_ERROR (KeyFile, LOC_M(17,"No private key found.\n"));
  169.  
  170. #if EXPORT
  171.     ctx->export_mode();
  172. #endif
  173.  
  174.     if (!bound) {
  175.       bind (ignore_eaddrinuse);
  176.       if (old_cert_failure && bound)
  177.     report_notice (LOC_M(64, "TLS port %s opened.\n"), get_url());
  178.     }
  179.   }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top