2004-08-19
2004-08-19 14:19:37 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
85fbbcfee34f8fe391339347fc9b5b5bc8ff35e8
(303 lines)
(+191/-112)
[
Show
| Annotate
]
Branch: 5.2
Fixed changing of SSL protocol settings.
Rev: server/base_server/global_variables.pike:1.94
Rev: server/base_server/roxen.pike:1.879
6:
// Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.
// ABS and suicide systems contributed freely by Francesco Chemolli
- constant cvs_version="$Id: roxen.pike,v 1.878 2004/08/18 17:01:31 mast Exp $";
+ constant cvs_version="$Id: roxen.pike,v 1.879 2004/08/19 14:19:27 grubba Exp $";
//! @appears roxen
//!
1613: Inside #if constant(SSL.sslfile)
inherit Protocol;
// SSL context
- SSL.context ctx;
+ SSL.context ctx = SSL.context();
- RoxenSSLFile accept()
+ void certificates_changed(Variable|void ignored)
{
- Stdio.File q = ::accept();
- if (q)
- return RoxenSSLFile (q, ctx);
- return 0;
- }
+ string raw_keydata;
+ array(string) certificates = ({});
+ Variable Certificates = getvar("ssl_cert_file");
- void create(int pn, string i)
+ object privs = Privs("Reading cert file");
+
+ foreach(map(Certificates->query(), String.trim_whites), string cert_file) {
+ string raw_cert;
+ if( catch{ raw_cert = lopen(cert_file, "r")->read(); } )
{
- ctx = SSL.context();
- set_up_ssl_variables( this_object() );
- port = pn;
- ip = i;
+ Certificates->add_warning(sprintf(LOC_M(8,"SSL3: Reading cert-file '%s' failed!"),
+ cert_file));
+ continue;
+ }
- restore();
+ object msg = Tools.PEM.pem_msg()->init( raw_cert );
+ object part = msg->parts["CERTIFICATE"] ||
+ msg->parts["X509 CERTIFICATE"];
+ string cert;
- object privs = Privs("Reading cert file");
- int key_matches;
- string f, f2;
- ctx->certificates = ({});
+ if (msg->parts["RSA PRIVATE KEY"] ||
+ msg->parts["DSA PRIVATE KEY"]) {
+ raw_keydata = raw_cert;
+ }
- foreach( map(query_option("ssl_cert_file"), String.trim_whites),
- string cert_file )
+ if (!part || !(cert = part->decoded_body()))
{
- if( catch{ f = lopen(cert_file, "r")->read(); } )
- {
- report_error(LOC_M(8,"SSL3: Reading cert-file '%s' failed!")+"\n",
- cert_file);
- return;
+ Certificates->add_warning(LOC_M(10, "SSL3: No certificate found.")+"\n");
+ continue;
}
-
+ certificates += ({ cert });
+ }
- if( strlen(query_option("ssl_key_file")) &&
- catch{ f2 = lopen(query_option("ssl_key_file"),"r")->read(); } )
+ Variable KeyFile = getvar("ssl_key_file");
+
+ if( strlen(KeyFile->query()) &&
+ catch{ raw_keydata = lopen(KeyFile->query(), "r")->read(); } )
{
- report_error(LOC_M(9, "SSL3: Reading key-file '%s' failed!")+"\n",
- query_option("ssl_key_file"));
+ KeyFile->add_warning(sprintf(LOC_M(9, "SSL3: Reading key-file '%s' failed!")+"\n",
+ query_option("ssl_key_file")));
return;
}
- object msg = Tools.PEM.pem_msg()->init( f );
- object part = msg->parts["CERTIFICATE"] || msg->parts["X509 CERTIFICATE"];
- string cert;
+ privs = 0;
- if (!part || !(cert = part->decoded_body()))
- {
- report_error(LOC_M(10, "SSL3: No certificate found.")+"\n");
+ if (!raw_keydata) {
+ Certificates->add_warning(LOC_M(17,"SSL3: No private key found."));
return;
}
- if( f2 )
- msg = Tools.PEM.pem_msg()->init( f2 );
+ if (!sizeof(certificates)) return;
- function r = Crypto.randomness.reasonably_random()->read;
+ object msg = Tools.PEM.pem_msg()->init( raw_keydata );
SSL3_WERR(sprintf("key file contains: %O", indices(msg->parts)));
-
+ object part;
if (part = msg->parts["RSA PRIVATE KEY"])
{
string key;
if (!(key = part->decoded_body()))
{
- report_error(LOC_M(11,"SSL3: Private rsa key not valid")+" (PEM).\n");
+ KeyFile->add_warning(LOC_M(11,"SSL3: Private rsa key not valid")+" (PEM).\n");
return;
}
object rsa = Standards.PKCS.RSA.parse_private_key(key);
if (!rsa)
{
- report_error(LOC_M(11, "SSL3: Private rsa key not valid")+" (DER).\n");
+ KeyFile->add_warning(LOC_M(11, "SSL3: Private rsa key not valid")+" (DER).\n");
return;
}
1696: Inside #if constant(SSL.sslfile)
if (rsa->rsa_size() > 512)
{
/* Too large for export */
- ctx->short_rsa = Crypto.rsa()->generate_key(512, r);
+ #if constant(Crypto.RSA)
+ ctx->short_rsa = Crypto.RSA()->generate_key(512, ctx->random);
+ #else
+ ctx->short_rsa = Crypto.rsa()->generate_key(512, ctx->random);
+ #endif
- // ctx->long_rsa = Crypto.rsa()->generate_key(rsa->rsa_size(), r);
+ // ctx->long_rsa = Crypto.rsa()->generate_key(rsa->rsa_size(), ctx->random);
}
ctx->rsa_mode();
-
+ array(int) key_matches =
+ map(certificates,
+ lambda(string cert, Variable Certificates) {
// FIXME: Support PKCS7
object tbs = Tools.X509.decode_certificate (cert);
if (!tbs)
{
- report_error(LOC_M(13,"SSL3: Certificate not valid (DER).")+"\n");
- return;
+ Certificates->add_warning(LOC_M(13,"SSL3: Certificate not valid (DER)."));
+ return 0;
}
- if (tbs->public_key->rsa->public_key_equal (rsa)) {
- key_matches++;
- // DWIM: Make sure the main cert comes first in the cert list.
- ctx->certificates = ({ cert }) + ctx->certificates;
- } else {
- ctx->certificates += ({ cert });
- continue;
+ return tbs->public_key->rsa->public_key_equal (rsa);
+ }, Certificates);
+
+ int num_key_matches;
+ // DWIM: Make sure the main cert comes first.
+ array(string) new_certificates = allocate(sizeof(certificates));
+ int i,j;
+ for (i=0; i < sizeof(certificates); i++) {
+ if (key_matches[i]) {
+ new_certificates[j++] = certificates[i];
+ num_key_matches++;
}
}
-
+ for (i=0; i < sizeof(certificates); i++) {
+ if (!key_matches[i]) {
+ new_certificates[j++] = certificates[i];
+ }
+ }
+ if( !num_key_matches )
+ {
+ KeyFile->add_warning(LOC_M(14, "SSL3: Certificate and private key "
+ "do not match."));
+ return;
+ }
+ ctx->certificates = new_certificates;
+ }
else if (part = msg->parts["DSA PRIVATE KEY"])
{
string key;
1737: Inside #if constant(SSL.sslfile)
SSL3_WERR(sprintf("Using DSA key."));
- dsa->use_random(r);
+ //dsa->use_random(ctx->random);
ctx->dsa = dsa;
/* Use default DH parameters */
#if constant(SSL.Cipher)
1750:
// FIXME: Add cert <-> private key check.
- ctx->certificates = ({ cert }) + ctx->certificates;
+ ctx->certificates = certificates;
}
else
{
- report_error(LOC_M(17,"SSL3: No private key found.")+"\n");
+ KeyFile->add_warning(LOC_M(17,"SSL3: No private key found."));
return;
}
- ctx->random = r;
+ #if EXPORT
+ ctx->export_mode();
+ #endif
}
- if( !key_matches )
+
+ class CertificateListVariable
{
- report_error(LOC_M(14, "SSL3: Certificate and private key do not "
- "match.")+"\n");
- return;
+ inherit Variable.FileList;
+
+ string doc()
+ {
+ return sprintf(::doc() + "\n",
+ combine_path(getcwd(), "../local"),
+ getcwd());
}
- #if EXPORT
- ctx->export_mode();
+
+ static void create(mixed default_value, void|int flags,
+ void|LocaleString std_name, void|LocaleString std_doc)
+ {
+ ::create(default_value, flags, std_name, std_doc);
+ set_changed_callback(certificates_changed);
+ }
+ }
+
+ class KeyFileVariable
+ {
+ inherit Variable.String;
+
+ string doc()
+ {
+ return sprintf(::doc() + "\n",
+ combine_path(getcwd(), "../local"),
+ getcwd());
+ }
+
+ static void create(mixed default_value, void|int flags,
+ void|LocaleString std_name, void|LocaleString std_doc)
+ {
+ ::create(default_value, flags, std_name, std_doc);
+ set_changed_callback(certificates_changed);
+ }
+ }
+
+ RoxenSSLFile accept()
+ {
+ Stdio.File q = ::accept();
+ if (q)
+ return RoxenSSLFile (q, ctx);
+ return 0;
+ }
+
+ void create(int pn, string i)
+ {
+ #if constant(Crypto.Random.random_string)
+ ctx->random = Crypto.Random.random_string;
+ #else
+ ctx->random = Crypto.randomness.reasonably_random()->read;
#endif
-
+
+ set_up_ssl_variables( this_object() );
+
::create(pn, i);
-
+
+ certificates_changed();
}
string _sprintf( )