]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
stable certificates part1
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 16 Feb 2012 20:00:16 +0000 (22:00 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Thu, 16 Feb 2012 20:00:16 +0000 (22:00 +0200)
Changes to make fake certificates "stable" and "unique".

This patch modify bump-server-first branch to:

- use configured trusted CA private key for generating all fake certificates,
 including trusted, untrusted, and self-signed fake certificates.

- use untrusted CA certificate which be deterministically derived from
 the trusted CA certificate to both reduce configuration effort (compared to
 a configuration option) and to generate identical untrusted CA certificates
 given identical Squid configurations.

src/ProtoPort.h
src/cache_cf.cc
src/client_side.cc
src/ssl/gadgets.cc
src/ssl/support.cc
src/ssl/support.h

index d80fa0089168df2863f103cea80867e2044d43ad..c83fa9f95b9ef487bcaf44c736a90b942ada046a 100644 (file)
@@ -73,6 +73,8 @@ struct http_port_list {
     Ssl::X509_Pointer signingCert; ///< x509 certificate for signing generated certificates
     Ssl::EVP_PKEY_Pointer signPkey; ///< private key for sighing generated certificates
     Ssl::X509_STACK_Pointer certsToChain; ///<  x509 certificates to send with the generated cert
+    Ssl::X509_Pointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates
+    Ssl::EVP_PKEY_Pointer untrustedSignPkey; ///< private key for signing untrusted generated certificates
 #endif
 
     CBDATA_CLASS2(http_port_list);
index 1d610b042ce4264507cad5a4e7306b1b00fe8138..ea38819c28b349cd36e6a03d854b430d51f061dd 100644 (file)
@@ -922,6 +922,12 @@ configDoConfigure(void)
                                        s->sslContextSessionId));
 
             Ssl::readCertChainAndPrivateKeyFromFiles(s->signingCert, s->signPkey, s->certsToChain, s->cert, s->key);
+
+            if (!s->signPkey)
+                debugs(3, DBG_IMPORTANT, "No SSL private key configured for  http_port " << s->http.s);
+
+            Ssl::generateUntrustedCert(s->untrustedSigningCert, s->untrustedSignPkey,
+                                       s->signingCert, s->signPkey);
         }
     }
 
@@ -938,8 +944,14 @@ configDoConfigure(void)
                                        s->cafile, s->capath, s->crlfile, s->dhfile,
                                        s->sslContextSessionId));
 
-            if (s->cert && s->sslBump)
+            if (s->cert && s->sslBump) {
                 Ssl::readCertChainAndPrivateKeyFromFiles(s->signingCert, s->signPkey, s->certsToChain, s->cert, s->key);
+                if (!s->signPkey)
+                    debugs(3, DBG_IMPORTANT, "No SSL private key configured for  https_port " << s->http.s);
+
+                Ssl::generateUntrustedCert(s->untrustedSigningCert, s->untrustedSignPkey,
+                                           s->signingCert, s->signPkey);
+            }
         }
     }
 
index b50330fac1c6aa32296a3c9c65c50cca0cfb27f7..20837434ce8899fdab890cdd0fee777fdcf0adb6 100644 (file)
@@ -3710,9 +3710,8 @@ void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &cer
     assert(certProperties.signAlgorithm != Ssl::algSignEnd);
 
     if (certProperties.signAlgorithm == Ssl::algSignUntrusted) {
-        assert(Ssl::SquidCaCert.get() && Ssl::SquidCaCertKey.get());
-        certProperties.signWithX509.resetAndLock(Ssl::SquidCaCert.get());
-        certProperties.signWithPkey.resetAndLock(Ssl::SquidCaCertKey.get());
+        certProperties.signWithX509.resetAndLock(port->untrustedSigningCert.get());
+        certProperties.signWithPkey.resetAndLock(port->untrustedSignPkey.get());
     }
     else {
         if (port->signingCert.get())
index 62895d291492baf562cefc08b0032b7da80c97d5..7be9cb07025930ce55c600c4cd15a0da0b75b9f3 100644 (file)
@@ -292,7 +292,12 @@ static bool buildCertificate(Ssl::X509_Pointer & cert, Ssl::CertificatePropertie
 bool Ssl::generateSslCertificate(Ssl::X509_Pointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties)
 {
     Ssl::EVP_PKEY_Pointer pkey;
-    pkey.reset(createSslPrivateKey());
+    // Use signing certificates private key as generated certificate private key
+    if (properties.signWithPkey.get())
+        pkey.resetAndLock(properties.signWithPkey.get());
+    else // if not exist generate one
+        pkey.reset(createSslPrivateKey());
+
     if (!pkey)
         return false;
 
index d28cb373097e3253256d0fad2206368459b0c2dd..32f78038aeae836fcc3e77b2ad2cab05f4da5dac 100644 (file)
@@ -46,9 +46,6 @@
 #include "ssl/support.h"
 #include "ssl/gadgets.h"
 
-Ssl::X509_Pointer Ssl::SquidCaCert;
-Ssl::EVP_PKEY_Pointer Ssl::SquidCaCertKey;
-
 /**
  \defgroup ServerProtocolSSLInternal Server-Side SSL Internals
  \ingroup ServerProtocolSSLAPI
@@ -652,13 +649,6 @@ ssl_initialize(void)
 
     }
 
-    // Generate the self-signed Ssl::SquidCaCert, using the "SquidLocalCa" as CN
-    Ssl::CertificateProperties certProperties;
-    certProperties.commonName = "Squid CA for Untrusted Certificates";
-    certProperties.signAlgorithm = Ssl::algSignSelf;
-    bool ret = Ssl::generateSslCertificate(Ssl::SquidCaCert, Ssl::SquidCaCertKey, certProperties);
-    assert(ret);
-
     ssl_ex_index_server = SSL_get_ex_new_index(0, (void *) "server", NULL, NULL, NULL);
     ssl_ctx_ex_index_dont_verify_domain = SSL_CTX_get_ex_new_index(0, (void *) "dont_verify_domain", NULL, NULL, NULL);
     ssl_ex_index_cert_error_check = SSL_get_ex_new_index(0, (void *) "cert_error_check", NULL, &ssl_dupAclChecklist, &ssl_freeAclChecklist);
@@ -1391,21 +1381,57 @@ void Ssl::readCertChainAndPrivateKeyFromFiles(X509_Pointer & cert, EVP_PKEY_Poin
     }
 }
 
-const char *Ssl::CommonHostName(X509 *x509)
+static const char *getSubjectEntry(X509 *x509, int nid)
 {
-    static char name[256] = ""; // stores common name (CN)
+    static char name[1024] = ""; // stores common name (CN)
 
     if (!x509)
         return NULL;
 
-    // TODO: What if CN is a UTF8String? See X509_NAME_get_index_by_NID(3ssl).
+    // TODO: What if the entry is a UTF8String? See X509_NAME_get_index_by_NID(3ssl).
     const int nameLen = X509_NAME_get_text_by_NID(
         X509_get_subject_name(x509),
-        NID_commonName,  name, sizeof(name));
+        nid,  name, sizeof(name));
 
     if (nameLen > 0)
         return name;
 
     return NULL;
 }
+
+const char *Ssl::CommonHostName(X509 *x509)
+{
+    return getSubjectEntry(x509, NID_commonName);
+}
+
+static const char *getOrganization(X509 *x509)
+{
+    return getSubjectEntry(x509, NID_organizationName);
+}
+
+bool Ssl::generateUntrustedCert(X509_Pointer &untrustedCert, EVP_PKEY_Pointer &untrustedPkey, X509_Pointer const  &cert, EVP_PKEY_Pointer const & pkey)
+{
+    // Generate the self-signed certificate, using a hard-coded subject prefix
+    Ssl::CertificateProperties certProperties;
+    if (const char *cn = CommonHostName(cert.get())) {
+        certProperties.commonName = "Not trusted by \"";
+        certProperties.commonName += cn;
+        certProperties.commonName += "\"";
+    }
+    else if (const char *org = getOrganization(cert.get())) {
+        certProperties.commonName =  "Not trusted by \"";
+        certProperties.commonName += org;
+        certProperties.commonName += "\"";
+    }
+    else
+        certProperties.commonName =  "Not trusted";
+    certProperties.setCommonName = true;
+    // O, OU, and other CA subject fields will be mimicked
+    // Expiration date and other common properties will be mimicked
+    certProperties.signAlgorithm = Ssl::algSignSelf;
+    certProperties.signWithPkey.resetAndLock(pkey.get());
+    certProperties.mimicCert.resetAndLock(cert.get());
+    return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties);
+}
+
 #endif /* USE_SSL */
index a4f571e1405d42743ca14462e1d0a5735c757104..5584a74bdc342f404020a1201ac5be6b307ce804 100644 (file)
@@ -109,19 +109,11 @@ const char *sslGetUserCertificateChainPEM(SSL *ssl);
 
 namespace Ssl
 {
-
-/**
-  \ingroup ServerProtocolSSLAPI
-  * A temporary self-signed certificate generated on squid start up, to be
-  * used to sign the generated untrusted certificates.
-*/
-extern X509_Pointer SquidCaCert;
-
 /**
   \ingroup ServerProtocolSSLAPI
-  * The key of the SquidCaCert certificate.
+  * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
 */
-extern EVP_PKEY_Pointer SquidCaCertKey;
+bool generateUntrustedCert(X509_Pointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, X509_Pointer const & cert, EVP_PKEY_Pointer const & pkey);
 
 /**
   \ingroup ServerProtocolSSLAPI