]> code.citadel.org Git - citadel.git/blobdiff - webcit/crypto.c
* Corrected overly-escaped reply-to addresses in "reply" button
[citadel.git] / webcit / crypto.c
index 66b21cf20ac5b5f0b544ca7056b9275d5d59e2f2..07c4d405e50f85262b765a1670519e8ebc5d7e3b 100644 (file)
@@ -36,43 +36,6 @@ static unsigned long id_callback(void)
        return (unsigned long) pthread_self();
 }
 
- /*
-  * Set up the cert things on the server side. We do need both the
-  * private key (in key_file) and the cert (in cert_file).
-  * Both files may be identical.
-  *
-  * This function is taken from OpenSSL apps/s_cb.c
-  */
-
-static int ctdl_install_certificate(SSL_CTX * ctx,
-                         const char *cert_file, const char *key_file)
-{
-       if (cert_file != NULL) {
-               if (SSL_CTX_use_certificate_file(ctx, cert_file,
-                                                SSL_FILETYPE_PEM) <= 0) {
-                       lprintf(3, "unable to get certificate from '%s'",
-                               cert_file);
-                       return (0);
-               }
-               if (key_file == NULL)
-                       key_file = cert_file;
-               if (SSL_CTX_use_PrivateKey_file(ctx, key_file,
-                                               SSL_FILETYPE_PEM) <= 0) {
-                       lprintf(3, "unable to get private key from '%s'",
-                               key_file);
-                       return (0);
-               }
-               /* Now we know that a key and cert have been set against
-                * the SSL context */
-               if (!SSL_CTX_check_private_key(ctx)) {
-                       lprintf(3,
-                               "Private key does not match the certificate public key");
-                       return (0);
-               }
-       }
-       return (1);
-}
-
 
 void init_ssl(void)
 {
@@ -85,6 +48,7 @@ void init_ssl(void)
        EVP_PKEY *req_pkey = NULL;
        X509_NAME *name = NULL;
        FILE *fp;
+       char buf[SIZ];
 
        if (!access("/var/run/egd-pool", F_OK))
                RAND_egd("/var/run/egd-pool");
@@ -119,7 +83,7 @@ void init_ssl(void)
         * Initialize SSL transport layer
         */
        SSL_library_init();
-       OpenSSL_add_all_algorithms();
+       /* OpenSSL_add_all_algorithms(); */
        SSL_load_error_strings();
        ssl_method = SSLv2_server_method();
        if (!(ssl_ctx = SSL_CTX_new(ssl_method))) {
@@ -164,7 +128,24 @@ void init_ssl(void)
        mkdir(CTDL_CRYPTO_DIR, 0700);
 
        /*
-        * Generate a key pair if we don't have one.
+        * Before attempting to generate keys/certificates, first try
+        * link to them from the Citadel server if it's on the same host.
+        * We ignore any error return because it either meant that there
+        * was nothing in Citadel to link from (in which case we just
+        * generate new files) or the target files already exist (which
+        * is not fatal either).
+        */
+       if (!strcasecmp(ctdlhost, "uds")) {
+               sprintf(buf, "%s/keys/citadel.key", ctdlport);
+               symlink(buf, CTDL_KEY_PATH);
+               sprintf(buf, "%s/keys/citadel.csr", ctdlport);
+               symlink(buf, CTDL_CSR_PATH);
+               sprintf(buf, "%s/keys/citadel.cer", ctdlport);
+               symlink(buf, CTDL_CER_PATH);
+       }
+
+       /*
+        * If we still don't have a private key, generate one.
         */
        if (access(CTDL_KEY_PATH, R_OK) != 0) {
                lprintf(5, "Generating RSA key pair.\n");
@@ -314,10 +295,12 @@ void init_ssl(void)
                        if (req) {
                                if (cer = X509_new(), cer != NULL) {
 
+                                       ASN1_INTEGER_set(X509_get_serialNumber(cer), 0);
                                        X509_set_issuer_name(cer, req->req_info->subject);
                                        X509_set_subject_name(cer, req->req_info->subject);
-                                       X509_gmtime_adj(X509_get_notBefore(cer),0);
+                                       X509_gmtime_adj(X509_get_notBefore(cer), 0);
                                        X509_gmtime_adj(X509_get_notAfter(cer),(long)60*60*24*SIGN_DAYS);
+
                                        req_pkey = X509_REQ_get_pubkey(req);
                                        X509_set_pubkey(cer, req_pkey);
                                        EVP_PKEY_free(req_pkey);
@@ -347,14 +330,13 @@ void init_ssl(void)
        /*
         * Now try to bind to the key and certificate.
         */
-       if (ctdl_install_certificate(ssl_ctx,
-                       CTDL_CER_PATH,
-                       CTDL_KEY_PATH) != 1)
-       {
+       SSL_CTX_use_certificate_file(ssl_ctx, CTDL_CER_PATH, SSL_FILETYPE_PEM);
+       SSL_CTX_use_PrivateKey_file(ssl_ctx, CTDL_KEY_PATH, SSL_FILETYPE_PEM);
+       if ( !SSL_CTX_check_private_key(ssl_ctx) ) {
                lprintf(3, "Cannot install certificate: %s\n",
                                ERR_reason_error_string(ERR_get_error()));
        }
-
+       
 }
 
 
@@ -470,7 +452,6 @@ void client_write_ssl(char *buf, int nbytes)
                        if (retval == -1)
                                lprintf(9, "errno is %d\n", errno);
                        endtls();
-                       client_write(&buf[nbytes - nremain], nremain);
                        return;
                }
                nremain -= retval;
@@ -529,8 +510,7 @@ int client_read_ssl(char *buf, int bytes, int timeout)
                        }
                        lprintf(9, "SSL_read got error %ld\n", errval);
                        endtls();
-                       return (client_read_to
-                               (WC->http_sock, &buf[len], bytes - len, timeout));
+                       return (0);
                }
                len += rlen;
        }