]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
sslproxy_cert_sign squid.conf option
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 27 Jan 2012 15:53:38 +0000 (17:53 +0200)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 27 Jan 2012 15:53:38 +0000 (17:53 +0200)
This option control how generated fake SSL certificates are signed.

Syntax:
  sslproxy_cert_sign <signing algorithm> acl ...

where <signing algorithm> can be one of the signTrusted, signUntrusted or
signSelf

Default signing algorithm if the sslproxy_cert_sign is not configured is
signSelf, if the server certificate is self signed, signUntrusted if the server
certificate is untrusted (ERR_INVALID_CA, ERR_SELF_SIGNED_CERT_IN_CHAIN,
ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, ERR_UNABLE_TO_GET_ISSUER_CERT,
ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY and ERR_CERT_UNTRUSTED errors) and
signTrusted if the server certificate is trusted.

Notes:
  - The signing algorithm passed as parameter to the ssl_crtd daemon

  - A self signed certificate generated on squid startup to be used as
    signing certificate for untrusted certificates, with CN =
    "Squid CA for Untrusted Certificates"

  - The configured certificates with http(s)_port squid.conf option chained to
    the client SSL connection only when signTrusted signing algorithm selected.
    When the signing algorithm is signSelf or signUntrusted no other certificate
    send to the client browser.

  - A small bug fixed which did not allow the sslproxy_cert_adapt option
    to be enabled in squid if the icap client is not enabled

14 files changed:
src/cache_cf.cc
src/cf.data.depend
src/cf.data.pre
src/client_side.cc
src/client_side.h
src/ssl/crtd_message.cc
src/ssl/crtd_message.h
src/ssl/gadgets.cc
src/ssl/gadgets.h
src/ssl/ssl_crtd.cc
src/ssl/support.cc
src/ssl/support.h
src/structs.h
src/typedefs.h

index 5f325270cc60f1f58f944a7afaabca88c3aa1577..c523792e7780b330a3eee175568e7db6bfeb97e1 100644 (file)
@@ -197,6 +197,9 @@ static void free_http_port_list(http_port_list **);
 static void parse_https_port_list(https_port_list **);
 static void dump_https_port_list(StoreEntry *, const char *, const https_port_list *);
 static void free_https_port_list(https_port_list **);
+static void parse_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign);
+static void dump_sslproxy_cert_sign(StoreEntry *entry, const char *name, sslproxy_cert_sign *cert_sign);
+static void free_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign);
 static void parse_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt);
 static void dump_sslproxy_cert_adapt(StoreEntry *entry, const char *name, sslproxy_cert_adapt *cert_adapt);
 static void free_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt);
@@ -4523,6 +4526,7 @@ static void free_icap_service_failure_limit(Adaptation::Icap::Config *cfg)
     cfg->oldest_service_failure = 0;
     cfg->service_failure_limit = 0;
 }
+#endif
 
 #if USE_SSL
 static void parse_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt)
@@ -4600,6 +4604,59 @@ static void free_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt)
         safe_free(ca);
     }
 }
-#endif
+
+static void parse_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign)
+{
+    char *al;
+    sslproxy_cert_sign *cs = (sslproxy_cert_sign *) xcalloc(1, sizeof(sslproxy_cert_sign));
+    if ((al = strtok(NULL, w_space)) == NULL) {
+        self_destruct();
+        return;
+    }
+
+    if (strcmp(al, Ssl::CertSignAlgorithmStr[Ssl::algSignTrusted]) == 0)
+        cs->alg = Ssl::algSignTrusted;
+    else if (strcmp(al, Ssl::CertSignAlgorithmStr[Ssl::algSignUntrusted]) == 0)
+        cs->alg = Ssl::algSignUntrusted;
+    else if (strcmp(al, Ssl::CertSignAlgorithmStr[Ssl::algSignSelf]) == 0)
+        cs->alg = Ssl::algSignSelf;
+    else {
+        debugs(3, DBG_CRITICAL, "FATAL: sslproxy_cert_sign: unknown cert signing algorithm: " << al);
+        self_destruct();
+        return;
+    }
+
+    aclParseAclList(LegacyParser, &cs->aclList);
+
+    while(*cert_sign)
+        cert_sign = &(*cert_sign)->next;
+
+    *cert_sign = cs;
+}
+
+static void dump_sslproxy_cert_sign(StoreEntry *entry, const char *name, sslproxy_cert_sign *cert_sign)
+{
+    sslproxy_cert_sign *cs;
+    for (cs = cert_sign; cs != NULL; cs = cs->next) {
+        storeAppendPrintf(entry, "%s ", name);
+        storeAppendPrintf(entry, "%s ", Ssl::certSignAlgorithm(cs->alg));
+        if (cs->aclList)
+            dump_acl_list(entry, cs->aclList);
+        storeAppendPrintf(entry, "\n");
+    }
+}
+
+static void free_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign)
+{
+    while(*cert_sign) {
+        sslproxy_cert_sign *cs = *cert_sign;
+        *cert_sign = cs->next;
+
+        if (cs->aclList)
+            aclDestroyAclList(&cs->aclList);
+
+        safe_free(cs);
+    }
+}
 
 #endif
index 478390aef9f88d6d46ce747c621e71082fa11191..6250d0bf6e62885825aab0da34361530b0124834 100644 (file)
@@ -69,4 +69,5 @@ wccp2_amethod
 wccp2_service
 wccp2_service_info
 wordlist
+sslproxy_cert_sign    acl
 sslproxy_cert_adapt    acl
index 0b45881252f8d2c57a2ddabc3e00b60cbfd7c616..0b1a2c4a4ab65564ff746c98f80426ee07335a10 100644 (file)
@@ -2052,6 +2052,30 @@ DOC_START
        Default setting:  sslproxy_cert_error deny all
 DOC_END
 
+NAME: sslproxy_cert_sign
+IFDEF: USE_SSL
+DEFAULT: none
+TYPE: sslproxy_cert_sign
+LOC: Config.ssl_client.cert_sign
+DOC_START
+
+        sslproxy_cert_sign <adaptation algorithm> acl ...
+
+        The following certificate signing algorithms supported:
+          signTrusted
+               the current signing algorithm using a configured CA certificate
+               that is usually placed in and trusted by end-user browsers
+          signUntrusted
+               sign to guarantee an X509_V_ERR_CERT_UNTRUSTED browser error
+          signSelf
+               sign using a self-signed certificate with the right CN to
+               generate a X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT error in the
+               browser.
+
+        When the acl(s) match, the corresponding signing algorithm is used to
+        generate the certificate. Otherwise, the default signing algorithm used
+DOC_END
+
 NAME: sslproxy_cert_adapt 
 IFDEF: USE_SSL
 DEFAULT: none
index 99355d28c7602b3b7aa23ecfb23bbe91ae19cb01..afaf08c1d6cfa50cc3cecca74c4c2f55d0039130 100644 (file)
@@ -3632,15 +3632,19 @@ ConnStateData::sslCrtdHandleReply(const char * reply)
     getSslContextDone(NULL);
 }
 
-void ConnStateData::buildSslCertAdaptParams(Ssl::CrtdMessage::BodyParams &certAdaptParams)
+void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties, Ssl::CrtdMessage::BodyParams &certAdaptParams)
 {
     // Build a key to use for storing/retrieving certificates to cache
     sslBumpCertKey = sslCommonName.defined() ? sslCommonName : sslConnectHostOrIp;
+    certProperties.commonName = sslBumpCertKey.termedBuf();
 
     // fake certificate adaptation requires bump-server-first mode
     if (!bumpServerFirstErrorEntry())
         return;
 
+    if (X509 *mimicCert = bumpServerCert.get())
+        certProperties.mimicCert.resetAndLock(mimicCert);
+
     HttpRequest *fakeRequest =  new HttpRequest();
     fakeRequest->SetHost(sslConnectHostOrIp.termedBuf());
     fakeRequest->port = clientConnection->local.GetPort();
@@ -3664,8 +3668,16 @@ void ConnStateData::buildSslCertAdaptParams(Ssl::CrtdMessage::BodyParams &certAd
 
             // if not param defined for Common Name adaptation use hostname from 
             // the CONNECT request
-            if (!param && ca->alg == Ssl::algSetCommonName)
-                param = sslConnectHostOrIp.termedBuf();
+            if (ca->alg == Ssl::algSetCommonName) {
+                if (!param)
+                    param = sslConnectHostOrIp.termedBuf();
+                certProperties.commonName = param;
+                certProperties.setCommonName = true;
+            }
+            else if(ca->alg == Ssl::algSetValidAfter)
+                certProperties.setValidAfter = true;
+            else if(ca->alg == Ssl::algSetValidBefore)
+                certProperties.setValidBefore = true;
 
             assert(alg && param);
             debugs(33, 5, HERE << "Matches certificate adaptation aglorithm: " << 
@@ -3680,7 +3692,71 @@ void ConnStateData::buildSslCertAdaptParams(Ssl::CrtdMessage::BodyParams &certAd
             sslBumpCertKey.append("=");
             sslBumpCertKey.append(param);
         }
-    }    
+    }
+
+    certProperties.signAlgorithm = Ssl::algSignEnd;
+    for (sslproxy_cert_sign *sg = Config.ssl_client.cert_sign; sg != NULL; sg = sg->next) {
+        if (sg->aclList && checklist.fastCheck(sg->aclList) == ACCESS_ALLOWED) {
+            const char *sgAlg = Ssl::CertSignAlgorithmStr[sg->alg];
+            certProperties.signAlgorithm = (Ssl::CertSignAlgorithm)sg->alg;
+            certAdaptParams.insert( std::make_pair(Ssl::CrtdMessage::param_Sign, sgAlg));
+            sslBumpCertKey.append("+Sign=");
+            sslBumpCertKey.append(sgAlg);
+            break;
+        }
+    }
+
+    if (certProperties.signAlgorithm == Ssl::algSignEnd) {
+        // Use the default algorithm
+        //Temporary code....
+        // TODO: implement the following using acls:
+        Ssl::ssl_error_t selfSignErrors[] = {X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, 0};
+        Ssl::ssl_error_t unTrustedErrors[] = {X509_V_ERR_INVALID_CA, 
+                                              X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, 
+                                              X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,
+                                              X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
+                                              X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+                                              X509_V_ERR_CERT_UNTRUSTED,0};
+        for (int i = 0; selfSignErrors[i] != 0; i++) {
+            if (bumpSslErrorNoList->find(selfSignErrors[i])) {
+                certProperties.signAlgorithm = Ssl::algSignSelf;
+                const char *sgAlg = Ssl::CertSignAlgorithmStr[Ssl::algSignSelf];
+                sslBumpCertKey.append("+Sign=");
+                sslBumpCertKey.append(sgAlg);
+                certAdaptParams.insert( std::make_pair(Ssl::CrtdMessage::param_Sign, sgAlg));
+                break;
+            }  
+        }
+        if (certProperties.signAlgorithm == Ssl::algSignEnd) {
+            for (int i = 0; unTrustedErrors[i] != 0; i++) {
+                if (bumpSslErrorNoList->find(selfSignErrors[i])) {
+                    certProperties.signAlgorithm = Ssl::algSignUntrusted;
+                    const char *sgAlg = Ssl::CertSignAlgorithmStr[Ssl::algSignUntrusted];
+                    sslBumpCertKey.append("+Sign=");
+                    sslBumpCertKey.append(sgAlg);
+                    certAdaptParams.insert( std::make_pair(Ssl::CrtdMessage::param_Sign, sgAlg));
+                    break;
+                }  
+            }
+        }
+        if (certProperties.signAlgorithm == Ssl::algSignEnd)
+            certProperties.signAlgorithm = Ssl::algSignTrusted;
+        //End of Temporary code....
+    }
+
+    if (certProperties.signAlgorithm == Ssl::algSignUntrusted) {
+        assert(Ssl::SquidCaCert.get() && Ssl::SquidCaCertKey.get());
+        certProperties.signWithX509.resetAndLock(Ssl::SquidCaCert.get());
+        certProperties.signWithPkey.resetAndLock(Ssl::SquidCaCertKey.get());
+    }
+    else {
+        if (port->signingCert.get())
+            certProperties.signWithX509.resetAndLock(port->signingCert.get());
+
+        if (port->signPkey.get())
+            certProperties.signWithPkey.resetAndLock(port->signPkey.get());
+    }
+    signAlgorithm = certProperties.signAlgorithm;
 }
 
 void
@@ -3688,10 +3764,11 @@ ConnStateData::getSslContextStart()
 {
     if (port->generateHostCertificates) {
         Ssl::CrtdMessage::BodyParams certAdaptParams;
-        buildSslCertAdaptParams(certAdaptParams);
+        Ssl::CertificateProperties certProperties;
+        buildSslCertGenerationParams(certProperties, certAdaptParams);
         assert(sslBumpCertKey.defined() && sslBumpCertKey[0] != '\0');
 
-            debugs(33, 5, HERE << "Finding SSL certificate for " << sslBumpCertKey << " in cache");
+        debugs(33, 5, HERE << "Finding SSL certificate for " << sslBumpCertKey << " in cache");
         Ssl::LocalContextStorage & ssl_ctx_cache(Ssl::TheGlobalContextStorage.getLocalStorage(port->s));
         SSL_CTX * dynCtx = ssl_ctx_cache.find(sslBumpCertKey.termedBuf());
         if (dynCtx) {
@@ -3708,19 +3785,18 @@ ConnStateData::getSslContextStart()
             debugs(33, 5, HERE << "SSL certificate for " << sslBumpCertKey << " haven't found in cache");
         }
 
-        char const * host = sslCommonName.defined() ? sslCommonName.termedBuf() : sslConnectHostOrIp.termedBuf();
 #if USE_SSL_CRTD
-        debugs(33, 5, HERE << "Generating SSL certificate for " << host << " using ssl_crtd.");
+        debugs(33, 5, HERE << "Generating SSL certificate for " << certProperties.commonName << " using ssl_crtd.");
         Ssl::CrtdMessage request_message;
         request_message.setCode(Ssl::CrtdMessage::code_new_certificate);
         Ssl::CrtdMessage::BodyParams map;
-        map.insert(std::make_pair(Ssl::CrtdMessage::param_host, host));
+        map.insert(std::make_pair(Ssl::CrtdMessage::param_host, certProperties.commonName));
         /*Append parameters for cert adaptation*/
         map.insert(certAdaptParams.begin(), certAdaptParams.end());
         std::string bufferToWrite;
-        Ssl::writeCertAndPrivateKeyToMemory(port->signingCert, port->signPkey, bufferToWrite);
-        if (bumpServerCert.get()) {
-            Ssl::appendCertToMemory(bumpServerCert, bufferToWrite);
+        Ssl::writeCertAndPrivateKeyToMemory(certProperties.signWithX509, certProperties.signWithPkey, bufferToWrite);
+        if (certProperties.mimicCert.get()) {
+            Ssl::appendCertToMemory(certProperties.mimicCert, bufferToWrite);
             debugs(33, 5, HERE << "Append Mimic Certificate to body request: " << bufferToWrite);
         }
         request_message.composeBody(map, bufferToWrite);
@@ -3728,8 +3804,8 @@ ConnStateData::getSslContextStart()
         Ssl::Helper::GetInstance()->sslSubmit(request_message, sslCrtdHandleReplyWrapper, this);
         return;
 #else
-        debugs(33, 5, HERE << "Generating SSL certificate for " << host);
-        dynCtx = Ssl::generateSslContext(host, bumpServerCert, port->signingCert, port->signPkey, certAdaptParams);
+        debugs(33, 5, HERE << "Generating SSL certificate for " << certProperties.commonName);
+        dynCtx = Ssl::generateSslContext(certProperties);
         getSslContextDone(dynCtx, true);
         return;
 #endif //USE_SSL_CRTD
@@ -3743,7 +3819,9 @@ ConnStateData::getSslContextDone(SSL_CTX * sslContext, bool isNew)
     // Try to add generated ssl context to storage.
     if (port->generateHostCertificates && isNew) {
 
-        Ssl::addChainToSslContext(sslContext, port->certsToChain.get());
+        if (signAlgorithm == Ssl::algSignTrusted)
+            Ssl::addChainToSslContext(sslContext, port->certsToChain.get());
+        //else it is self-signed or untrusted do not attrach any certificate
 
         Ssl::LocalContextStorage & ssl_ctx_cache(Ssl::TheGlobalContextStorage.getLocalStorage(port->s));
         assert(sslBumpCertKey.defined() && sslBumpCertKey[0] != '\0');
index 589d818a0bf970740eeea78e798141bc55b34ea2..65c4b1b2a626255b0e0a5dfda796e140461ef9cc 100644 (file)
@@ -338,7 +338,7 @@ public:
     void setBumpSslErrorList(Ssl::Errors *errNoList) {bumpSslErrorNoList = cbdataReference(errNoList);}
     /// Fill the certAdaptParams with the required data for certificate adaptation
     /// and create the key for storing/retrieve the certificate to/from the cache
-    void buildSslCertAdaptParams(Ssl::CrtdMessage::BodyParams &certAdaptParams);
+    void buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties, Ssl::CrtdMessage::BodyParams &certAdaptParams);
     bool serveDelayedError(ClientSocketContext *context);
 #else
     bool switchedToHttps() const { return false; }
@@ -374,6 +374,7 @@ private:
     StoreEntry *bumpErrorEntry;
     Ssl::X509_Pointer bumpServerCert;
     Ssl::Errors *bumpSslErrorNoList; ///< The list of SSL certificate errors which ignored
+    Ssl::CertSignAlgorithm signAlgorithm; ///< The signing algorithm to use
 #endif
 
     AsyncCall::Pointer reader; ///< set when we are reading
index f23c1aa2bb24b28689a5baec3d4ac563bb2d813f..6d870336c8274067bb8ab5e1d845e80853fcc87b 100644 (file)
@@ -179,3 +179,4 @@ const std::string Ssl::CrtdMessage::param_host("host");
 const std::string Ssl::CrtdMessage::param_SetValidAfter(Ssl::CertAdaptAlgorithmStr[algSetValidAfter]);
 const std::string Ssl::CrtdMessage::param_SetValidBefore(Ssl::CertAdaptAlgorithmStr[algSetValidBefore]);
 const std::string Ssl::CrtdMessage::param_SetCommonName(Ssl::CertAdaptAlgorithmStr[algSetCommonName]);
+const std::string Ssl::CrtdMessage::param_Sign("Sign");
index 5891c3f207c829d481bee07541e120e6d6b5babd..86489b53d085ec8ed5ae2afd1f4feaaccdd9b8ba 100644 (file)
@@ -71,6 +71,8 @@ public:
     static const std::string param_SetValidBefore;
     /// Parameter name for passing SetCommonName cert adaptation variable
     static const std::string param_SetCommonName;
+    /// Parameter name for passing signing algorithm
+    static const std::string param_Sign;
 private:
     enum ParseState {
         BEFORE_CODE,
index bed17c327be09ddc6114b2e169bbfb0a53c16b8f..bbfd252311802cbfb0f69577abb1415578c65f53 100644 (file)
@@ -8,44 +8,6 @@
 #include <openssl/x509v3.h>
 #endif
 
-/**
- \ingroup ServerProtocolSSLInternal
- * Add CN to subject in request.
- */
-static bool addCnToRequest(Ssl::X509_REQ_Pointer & request, char const * cn)
-{
-    // not an Ssl::X509_NAME_Pointer because X509_REQ_get_subject_name()
-    // returns a pointer to the existing subject name. Nothing to clean here.
-    X509_NAME *name = X509_REQ_get_subject_name(request.get());
-    if (!name)
-        return false;
-
-    // The second argument of the X509_NAME_add_entry_by_txt declared as
-    // "char *" on some OS. Use cn_name to avoid compile warnings.
-    static char cn_name[3] = "CN";
-    if (!X509_NAME_add_entry_by_txt(name, cn_name, MBSTRING_ASC, (unsigned char *)cn, -1, -1, 0))
-        return false;
-
-    return true;
-}
-
-/**
- \ingroup ServerProtocolSSLInternal
- * Make request on sign using private key and hostname.
- */
-static bool makeRequest(Ssl::X509_REQ_Pointer & request, Ssl::EVP_PKEY_Pointer const & pkey, char const * host)
-{
-    if (!X509_REQ_set_version(request.get(), 0L))
-        return false;
-
-    if (!addCnToRequest(request, host))
-        return false;
-
-    if (!X509_REQ_set_pubkey(request.get(), pkey.get()))
-        return false;
-    return true;
-}
-
 EVP_PKEY * Ssl::createSslPrivateKey()
 {
     Ssl::EVP_PKEY_Pointer pkey(EVP_PKEY_new());
@@ -65,18 +27,6 @@ EVP_PKEY * Ssl::createSslPrivateKey()
     return pkey.release();
 }
 
-X509_REQ * Ssl::createNewX509Request(Ssl::EVP_PKEY_Pointer const & pkey, const char * hostname)
-{
-    Ssl::X509_REQ_Pointer request(X509_REQ_new());
-
-    if (!request)
-        return NULL;
-
-    if (!makeRequest(request, pkey, hostname))
-        return NULL;
-    return request.release();
-}
-
 /**
  \ingroup ServerProtocolSSLInternal
  * Set serial random serial number or set random serial number.
@@ -101,41 +51,6 @@ static bool setSerialNumber(ASN1_INTEGER *ai, BIGNUM const* serial)
     return true;
 }
 
-X509 * Ssl::signRequest(Ssl::X509_REQ_Pointer const & request, Ssl::X509_Pointer const & x509, Ssl::EVP_PKEY_Pointer const & pkey, ASN1_TIME * timeNotAfter, BIGNUM const * serial)
-{
-    Ssl::X509_Pointer cert(X509_new());
-    if (!cert)
-        return NULL;
-
-    if (!setSerialNumber(X509_get_serialNumber(cert.get()), serial))
-        return NULL;
-
-    if (!X509_set_issuer_name(cert.get(), x509.get() ? X509_get_subject_name(x509.get()) : X509_REQ_get_subject_name(request.get())))
-        return NULL;
-
-    if (!X509_gmtime_adj(X509_get_notBefore(cert.get()), (-2)*24*60*60))
-        return NULL;
-
-    if (timeNotAfter) {
-        if (!X509_set_notAfter(cert.get(), timeNotAfter))
-            return NULL;
-    } else if (!X509_gmtime_adj(X509_get_notAfter(cert.get()), 60*60*24*356*3))
-        return NULL;
-
-    if (!X509_set_subject_name(cert.get(), X509_REQ_get_subject_name(request.get())))
-        return NULL;
-
-    Ssl::EVP_PKEY_Pointer tmppkey(X509_REQ_get_pubkey(request.get()));
-
-    if (!tmppkey || !X509_set_pubkey(cert.get(), tmppkey.get()))
-        return NULL;
-
-    if (!X509_sign(cert.get(), pkey.get(), EVP_sha1()))
-        return NULL;
-
-    return cert.release();
-}
-
 bool Ssl::writeCertAndPrivateKeyToMemory(Ssl::X509_Pointer const & cert, Ssl::EVP_PKEY_Pointer const & pkey, std::string & bufferToWrite)
 {
     bufferToWrite.clear();
@@ -235,27 +150,6 @@ bool Ssl::readCertFromMemory(X509_Pointer & cert, char const * bufferToRead)
     return true;
 }
 
-bool Ssl::generateSslCertificateAndPrivateKey(char const *host, Ssl::X509_Pointer const & signedX509, Ssl::EVP_PKEY_Pointer const & signedPkey, Ssl::X509_Pointer & cert, Ssl::EVP_PKEY_Pointer & pkey, BIGNUM const * serial)
-{
-    pkey.reset(createSslPrivateKey());
-    if (!pkey)
-        return false;
-
-    Ssl::X509_REQ_Pointer request(createNewX509Request(pkey, host));
-    if (!request)
-        return false;
-
-    if (signedX509.get() && signedPkey.get())
-        cert.reset(signRequest(request, signedX509, signedPkey, X509_get_notAfter(signedX509.get()), serial));
-    else
-        cert.reset(signRequest(request, signedX509, pkey, NULL, serial));
-
-    if (!cert)
-        return false;
-
-    return true;
-}
-
 // Replace certs common name with the given
 static bool replaceCommonName(Ssl::X509_Pointer & cert, const char *cn)
 {
@@ -264,15 +158,24 @@ static bool replaceCommonName(Ssl::X509_Pointer & cert, const char *cn)
         return false;
     // Remove the CN part:
     int loc = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
-    X509_NAME_ENTRY *tmp = X509_NAME_get_entry(name, loc);
-    X509_NAME_delete_entry(name, loc);
-    X509_NAME_ENTRY_free(tmp);
+    if (loc >=0) {
+        X509_NAME_ENTRY *tmp = X509_NAME_get_entry(name, loc);
+        X509_NAME_delete_entry(name, loc);
+        X509_NAME_ENTRY_free(tmp);
+    }
 
     // Add a new CN
     return X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_ASC,
                                       (unsigned char *)cn, -1, -1, 0);
 }
 
+const char *Ssl::CertSignAlgorithmStr[] = {
+    "signTrusted",
+    "signUntrusted", 
+    "signSelf",
+    NULL
+};
+
 const char *Ssl::CertAdaptAlgorithmStr[] = {
     "setValidAfter",
     "setValidBefore",
@@ -280,23 +183,28 @@ const char *Ssl::CertAdaptAlgorithmStr[] = {
     NULL
 };
 
-static bool mimicCertificate(Ssl::X509_Pointer & cert, Ssl::X509_Pointer const & caCert, Ssl::X509_Pointer const &certToMimic,  Ssl::CrtdMessage::BodyParams const &exceptions)
+Ssl::CertificateProperties::CertificateProperties(): serial(NULL),
+                                                     setValidAfter(false),
+                                                     setValidBefore(false),
+                                                     setCommonName(false),
+                                                     signAlgorithm(Ssl::algSignEnd)
+{}
+
+static bool buildCertificate(Ssl::X509_Pointer & cert, Ssl::CertificateProperties const &properties)
 { 
     // not an Ssl::X509_NAME_Pointer because X509_REQ_get_subject_name()
     // returns a pointer to the existing subject name. Nothing to clean here.
-    X509_NAME *name = X509_get_subject_name(certToMimic.get());
-    if (!name)
-        return false;
-    // X509_set_subject_name will call X509_dup for name 
-    X509_set_subject_name(cert.get(), name);
+    if (properties.mimicCert.get()) {
+        X509_NAME *name = X509_get_subject_name(properties.mimicCert.get());
+        if (!name)
+            return false;
+        // X509_set_subject_name will call X509_dup for name 
+        X509_set_subject_name(cert.get(), name);
+    }
 
-    Ssl::CrtdMessage::BodyParams::const_iterator it;
-    it = exceptions.find(sslCertAdaptAlgoritm(Ssl::algSetCommonName));
-    if (it != exceptions.end()) {
-        // In this case the CN of the certificate given by the exceptions 
-        // and should be replaced
-        const char *cn = it->second.c_str();
-        if (cn && !replaceCommonName(cert, cn))
+    if (properties.setCommonName || !properties.mimicCert.get()) {
+        // In this case the CN of the certificate given by the user
+        if (!replaceCommonName(cert, properties.commonName.c_str()))
             return false;
     }
 
@@ -306,11 +214,10 @@ static bool mimicCertificate(Ssl::X509_Pointer & cert, Ssl::X509_Pointer const &
     // Currently there is not any way in openssl tollkit to compare two ASN1_TIME 
     // objects.
     ASN1_TIME *aTime = NULL;
-    it = exceptions.find(sslCertAdaptAlgoritm(Ssl::algSetValidBefore));
-    if (it == exceptions.end() || strcasecmp(it->second.c_str(), "on") != 0)
-        aTime = X509_get_notBefore(certToMimic.get());
-    if (!aTime)
-        aTime = X509_get_notBefore(caCert.get());
+    if (!properties.setValidBefore && properties.mimicCert.get())
+        aTime = X509_get_notBefore(properties.mimicCert.get());
+    if (!aTime && properties.signWithX509.get())
+        aTime = X509_get_notBefore(properties.signWithX509.get());
 
     if (aTime) {
         if (!X509_set_notBefore(cert.get(), aTime))
@@ -320,37 +227,37 @@ static bool mimicCertificate(Ssl::X509_Pointer & cert, Ssl::X509_Pointer const &
         return false;
 
     aTime = NULL;
-     it = exceptions.find(sslCertAdaptAlgoritm(Ssl::algSetValidAfter));
-    if (it == exceptions.end() || strcasecmp(it->second.c_str(), "on") != 0)
-        aTime = X509_get_notAfter(certToMimic.get());
-    if (!aTime)
-        aTime = X509_get_notAfter(caCert.get());
+    if (!properties.setValidAfter && properties.mimicCert.get())
+        aTime = X509_get_notAfter(properties.mimicCert.get());
+    if (!aTime && properties.signWithX509.get())
+        aTime = X509_get_notAfter(properties.signWithX509.get());
     if (aTime) {
         if (!X509_set_notAfter(cert.get(), aTime))
             return NULL;
     } else if (!X509_gmtime_adj(X509_get_notAfter(cert.get()), 60*60*24*356*3))
         return NULL;
-    unsigned char *alStr;
-    int alLen;
-    alStr = X509_alias_get0(certToMimic.get(), &alLen);
-    if (alStr) {
-        X509_alias_set1(cert.get(), alStr, alLen);
-    }
 
-    // Add subjectAltName extension used to support multiple hostnames with one certificate
-    int pos=X509_get_ext_by_NID (certToMimic.get(), OBJ_sn2nid("subjectAltName"), -1);
-    X509_EXTENSION *ext=X509_get_ext(certToMimic.get(), pos); 
-    if (ext)
-        X509_add_ext(cert.get(), ext, -1);
+    if (properties.mimicCert.get()) {
+        unsigned char *alStr;
+        int alLen;
+        alStr = X509_alias_get0(properties.mimicCert.get(), &alLen);
+        if (alStr) {
+            X509_alias_set1(cert.get(), alStr, alLen);
+        }
+
+        // Add subjectAltName extension used to support multiple hostnames with one certificate
+        int pos=X509_get_ext_by_NID (properties.mimicCert.get(), OBJ_sn2nid("subjectAltName"), -1);
+        X509_EXTENSION *ext=X509_get_ext(properties.mimicCert.get(), pos); 
+        if (ext)
+            X509_add_ext(cert.get(), ext, -1);
+    }
 
     return true;
 }
 
-bool Ssl::generateSslCertificate(Ssl::X509_Pointer const &certToMimic, Ssl::X509_Pointer const & signedX509, Ssl::EVP_PKEY_Pointer const & signedPkey, Ssl::X509_Pointer & certToStore, Ssl::EVP_PKEY_Pointer & pkey, BIGNUM const * serial, Ssl::CrtdMessage::BodyParams const &mimicExceptions)
+bool Ssl::generateSslCertificate(Ssl::X509_Pointer & certToStore, Ssl::EVP_PKEY_Pointer & pkeyToStore, Ssl::CertificateProperties const &properties)
 {
-    if (!certToMimic.get())
-        return false;
-
+    Ssl::EVP_PKEY_Pointer pkey;
     pkey.reset(createSslPrivateKey());
     if (!pkey)
         return false;
@@ -362,21 +269,25 @@ bool Ssl::generateSslCertificate(Ssl::X509_Pointer const &certToMimic, Ssl::X509
     // Set pub key and serial given by the caller
     if (!X509_set_pubkey(cert.get(), pkey.get()))
         return false;
-    if (!setSerialNumber(X509_get_serialNumber(cert.get()), serial))
+    if (!setSerialNumber(X509_get_serialNumber(cert.get()), properties.serial.get()))
         return false;
 
-    // inherit properties from certToMimic
-    if (!mimicCertificate(cert, signedX509, certToMimic, mimicExceptions))
+    // Fill the certificate with the required properties
+    if (!buildCertificate(cert, properties))
         return false;
 
+    int ret = 0;
     // Set issuer name, from CA or our subject name for self signed cert
-    if (!X509_set_issuer_name(cert.get(), signedX509.get() ? X509_get_subject_name(signedX509.get()) : X509_get_subject_name(cert.get())))
+    if (properties.signAlgorithm != Ssl::algSignSelf && properties.signWithX509.get())
+        ret = X509_set_issuer_name(cert.get(), X509_get_subject_name(properties.signWithX509.get()));
+    else // Self signed certificate, set issuer to self
+        ret = X509_set_issuer_name(cert.get(), X509_get_subject_name(cert.get()));
+    if (!ret)
         return false;
 
     /*Now sign the request */
-    int ret = 0;
-    if (signedPkey.get())
-        ret = X509_sign(cert.get(), signedPkey.get(), EVP_sha1());
+    if (properties.signAlgorithm != Ssl::algSignSelf && properties.signWithPkey.get())
+        ret = X509_sign(cert.get(), properties.signWithPkey.get(), EVP_sha1());
     else //else sign with self key (self signed request)
         ret = X509_sign(cert.get(), pkey.get(), EVP_sha1());
 
@@ -384,6 +295,7 @@ bool Ssl::generateSslCertificate(Ssl::X509_Pointer const &certToMimic, Ssl::X509
         return false;
 
     certToStore.reset(cert.release());
+    pkeyToStore.reset(pkey.release());
     return true;
 }
 
index e8cf163fe7353e72a8babd59c65bd55251bab928..10d46188e03ef9c879596a9e818f2b76641bd834 100644 (file)
@@ -26,6 +26,28 @@ namespace Ssl
  because they are used by ssl_crtd.
  */
 
+/**
+   \ingroup SslCrtdSslAPI
+  * Add SSL locking (a.k.a. reference counting) to TidyPointer
+  */
+template <typename T, void (*DeAllocator)(T *t), int lock>
+class LockingPointer: public TidyPointer<T, DeAllocator>
+{
+public:
+    typedef TidyPointer<T, DeAllocator> Parent;
+
+    LockingPointer(T *t = NULL): Parent(t) {
+    }
+
+    void resetAndLock(T *t) {
+        if (t != this->get()) {
+            reset(t);
+            if (t)
+                CRYPTO_add(&t->references, 1, lock);
+        }
+    }
+};
+
 // Macro to be used to define the C++ equivalent function of an extern "C"
 // function. The C++ function suffixed with the _cpp extension
 #define CtoCpp1(function, argument) \
@@ -38,13 +60,13 @@ namespace Ssl
  * TidyPointer typedefs for  common SSL objects
  */
 CtoCpp1(X509_free, X509 *)
-typedef TidyPointer<X509, X509_free_cpp> X509_Pointer;
+typedef LockingPointer<X509, X509_free_cpp, CRYPTO_LOCK_X509> X509_Pointer;
 
 CtoCpp1(sk_X509_free, STACK_OF(X509) *)
 typedef TidyPointer<STACK_OF(X509), sk_X509_free_cpp> X509_STACK_Pointer;
 
 CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
-typedef TidyPointer<EVP_PKEY, EVP_PKEY_free_cpp> EVP_PKEY_Pointer;
+typedef LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, CRYPTO_LOCK_EVP_PKEY> EVP_PKEY_Pointer;
 
 CtoCpp1(BN_free, BIGNUM *)
 typedef TidyPointer<BIGNUM, BN_free_cpp> BIGNUM_Pointer;
@@ -80,12 +102,6 @@ typedef TidyPointer<SSL, SSL_free_cpp> SSL_Pointer;
  */
 EVP_PKEY * createSslPrivateKey();
 
-/**
- \ingroup SslCrtdSslAPI
- * Create request on certificate for a host.
- */
-X509_REQ * createNewX509Request(EVP_PKEY_Pointer const & pkey, const char * hostname);
-
 /**
  \ingroup SslCrtdSslAPI
  * Write private key and SSL certificate to memory.
@@ -116,27 +132,49 @@ bool readCertAndPrivateKeyFromMemory(X509_Pointer & cert, EVP_PKEY_Pointer & pke
  */
 bool readCertFromMemory(X509_Pointer & cert, char const * bufferToRead);
 
+/**
+  \ingroup SslCrtdSslAPI
+ * Supported certificate signing algorithms
+ */
+enum CertSignAlgorithm {algSignTrusted = 0, algSignUntrusted, algSignSelf, algSignEnd};
+
 /**
  \ingroup SslCrtdSslAPI
- * Sign SSL request.
- * \param x509 if this param equals NULL, returning certificate will be selfsigned.
- * \return X509 Signed certificate.
+ * Short names for certificate signing algorithms
  */
-X509 * signRequest(X509_REQ_Pointer const & request, X509_Pointer const & x509, EVP_PKEY_Pointer const & pkey, ASN1_TIME * timeNotAfter, BIGNUM const * serial);
+
+extern const char *CertSignAlgorithmStr[];
 
 /**
  \ingroup SslCrtdSslAPI
- * Decide on the kind of certificate and generate a CA- or self-signed one.
- * Return generated certificate and private key in resultX509 and resultPkey
- * variables.
+ * Return the short name of the signing algorithm "sg"
+ */
+inline const char *certSignAlgorithm(int sg)
+{
+    if (sg >=0 && sg < Ssl::algSignEnd)
+        return Ssl::CertSignAlgorithmStr[sg];
+
+    return NULL;
+}
+
+/**
+ \ingroup SslCrtdSslAPI
+ * Return the id of the signing algorithm "sg"
  */
-bool generateSslCertificateAndPrivateKey(char const *host, X509_Pointer const & signedX509, EVP_PKEY_Pointer const & signedPkey, X509_Pointer & cert, EVP_PKEY_Pointer & pkey, BIGNUM const* serial);
+inline CertSignAlgorithm certSignAlgorithmId(const char *sg)
+{
+    for (int i = 0; i < algSignEnd && Ssl::CertSignAlgorithmStr[i] != NULL; i++)
+        if (strcmp(Ssl::CertSignAlgorithmStr[i], sg) == 0)
+            return (CertSignAlgorithm)i;
+
+    return algSignEnd;
+}
 
 /**
  \ingroup SslCrtdSslAPI
  * Supported certificate adaptation algorithms
  */
-enum CertAdaptAlgorithm {algSetValidAfter = 0, algSetValidBefore, algSetCommonName, algEnd};
+enum CertAdaptAlgorithm {algSetValidAfter = 0, algSetValidBefore, algSetCommonName, algSetEnd};
 
 /**
  \ingroup SslCrtdSslAPI
@@ -150,12 +188,33 @@ extern const char *CertAdaptAlgorithmStr[];
  */
 inline const char *sslCertAdaptAlgoritm(int alg)
 {
-    if (alg >=0 && alg < Ssl::algEnd)
+    if (alg >=0 && alg < Ssl::algSetEnd)
         return Ssl::CertAdaptAlgorithmStr[alg];
 
     return NULL;
 }
 
+/**
+ \ingroup SslCrtdSslAPI
+ * Simple struct to pass certificate generation parameters to generateSslCertificate function.
+ */
+class CertificateProperties {
+public:
+    CertificateProperties();
+    X509_Pointer mimicCert; ///< Certificate to mimic
+    X509_Pointer signWithX509; ///< Certificate to sign the generated request
+    EVP_PKEY_Pointer signWithPkey; ///< The key of the signing certificate
+    BIGNUM_Pointer serial; ///< Use this serial for generated certificate
+    bool setValidAfter; ///< Do not mimic "Not Valid After" field 
+    bool setValidBefore; ///< Do not mimic "Not Valid Before" field
+    bool setCommonName; ///< Replace the CN field of the mimicing subject with the given
+    std::string commonName; ///< A CN to use for the generated certificate
+    CertSignAlgorithm signAlgorithm; ///< The signing algorithm to use
+private:
+    CertificateProperties(CertificateProperties &);
+    CertificateProperties &operator =(CertificateProperties const &);
+};
+
 /**
  \ingroup SslCrtdSslAPI
  * Decide on the kind of certificate and generate a CA- or self-signed one.
@@ -163,7 +222,7 @@ inline const char *sslCertAdaptAlgoritm(int alg)
  * Return generated certificate and private key in resultX509 and resultPkey
  * variables.
  */
-bool generateSslCertificate(X509_Pointer const &certToMimic, X509_Pointer const & signedX509, EVP_PKEY_Pointer const & signedPkey, X509_Pointer & cert, EVP_PKEY_Pointer & pkey, BIGNUM const * serial, CrtdMessage::BodyParams const & mimicExceptions);
+bool generateSslCertificate(X509_Pointer & cert, EVP_PKEY_Pointer & pkey, CertificateProperties const &properties);
 
 /**
  \ingroup SslCrtdSslAPI
index 6ba0194448c9cfd335daac8fadf57e78cfe64884..2c3ae0c2a54a5a2d589ff89f638782c06118754b 100644 (file)
@@ -213,54 +213,72 @@ static void usage()
 static bool proccessNewRequest(Ssl::CrtdMessage const & request_message, std::string const & db_path, size_t max_db_size, size_t fs_block_size)
 {
     Ssl::CrtdMessage::BodyParams map;
+    Ssl::CertificateProperties certProperties;
     std::string body_part;
     request_message.parseBody(map, body_part);
 
     Ssl::CrtdMessage::BodyParams::iterator i = map.find(Ssl::CrtdMessage::param_host);
     if (i == map.end())
         throw std::runtime_error("Cannot find \"" + Ssl::CrtdMessage::param_host + "\" parameter in request message.");
-    std::string host = i->second;
+    certProperties.commonName = i->second;
 
     Ssl::CertificateDb db(db_path, max_db_size, fs_block_size);
 
     Ssl::X509_Pointer cert;
     Ssl::EVP_PKEY_Pointer pkey;
-    Ssl::X509_Pointer certToMimic;
     
     const char *s;
     std::string cert_subject;
     if ((s = strstr(body_part.c_str(), CERT_BEGIN_STR))) {
         s += strlen(CERT_BEGIN_STR);
         if ((s = strstr(s, CERT_BEGIN_STR))) {
-            Ssl::readCertFromMemory(certToMimic, s);
-            if (certToMimic.get()) {
+            Ssl::readCertFromMemory(certProperties.mimicCert, s);
+            if (certProperties.mimicCert.get()) {
                 char buf[1024];
-                cert_subject = X509_NAME_oneline(X509_get_subject_name(certToMimic.get()), buf, sizeof(buf));
+                cert_subject = X509_NAME_oneline(X509_get_subject_name(certProperties.mimicCert.get()), buf, sizeof(buf));
             }
         }
     }
 
     if (cert_subject.empty())
-        cert_subject = "/CN=" + host;
+        cert_subject = "/CN=" + certProperties.commonName;
 
     i = map.find(Ssl::CrtdMessage::param_SetValidAfter);
-    if (i != map.end() && strcasecmp(i->second.c_str(), "on") == 0)
+    if (i != map.end() && strcasecmp(i->second.c_str(), "on") == 0) {
         cert_subject.append("+SetValidAfter=on");
+        certProperties.setValidAfter = true;
+    }
     
     i = map.find(Ssl::CrtdMessage::param_SetValidBefore);
-    if (i != map.end() && strcasecmp(i->second.c_str(), "on") == 0)
+    if (i != map.end() && strcasecmp(i->second.c_str(), "on") == 0) {
         cert_subject.append("+SetValidBefore=on");
+        certProperties.setValidBefore = true;
+    }
 
     i = map.find(Ssl::CrtdMessage::param_SetCommonName);
     if (i != map.end()) {
         cert_subject.append("+SetCommonName=");
         cert_subject.append(i->second);
+        // use this as Common Name  instead of the hostname 
+        // defined with host or Common Name from mimic cert
+        certProperties.commonName = i->second;
+        certProperties.setCommonName = true;
     }
 
+    i = map.find(Ssl::CrtdMessage::param_Sign);
+    if (i != map.end()) {
+        cert_subject.append("+Sign=");
+        cert_subject.append(i->second);
+        if ((certProperties.signAlgorithm = Ssl::certSignAlgorithmId(i->second.c_str())) == Ssl::algSignEnd)
+            throw std::runtime_error("Wrong signing algoritm:" + i->second);
+    }
+    else
+        certProperties.signAlgorithm = Ssl::algSignTrusted;
+
     db.find(cert_subject, cert, pkey);
 
-    if (cert.get() && certToMimic.get()) {
-        if (!Ssl::ssl_match_certificates(cert.get(), certToMimic.get())) {
+    if (cert.get() && certProperties.mimicCert.get()) {
+        if (!Ssl::ssl_match_certificates(cert.get(), certProperties.mimicCert.get())) {
             // The certificate changed (renewed or other reason).
             // Generete a new one with the updated fields.
             cert.reset(NULL);
@@ -269,18 +287,15 @@ static bool proccessNewRequest(Ssl::CrtdMessage const & request_message, std::st
     }
 
     if (!cert || !pkey) {
-        Ssl::X509_Pointer certToSign;
-        Ssl::EVP_PKEY_Pointer pkeyToSign;
-        Ssl::readCertAndPrivateKeyFromMemory(certToSign, pkeyToSign, body_part.c_str());
-
-        Ssl::BIGNUM_Pointer serial(db.getCurrentSerialNumber());
-
-        if (certToMimic.get()) {
-            Ssl::generateSslCertificate(certToMimic, certToSign, pkeyToSign, cert, pkey, serial.get(), map);
-        }
-        else 
-            if (!Ssl::generateSslCertificateAndPrivateKey(host.c_str(), certToSign, pkeyToSign, cert, pkey, serial.get()))
-                throw std::runtime_error("Cannot create ssl certificate or private key.");
+        if (certProperties.signAlgorithm != Ssl::algSignSelf) {
+            if (!Ssl::readCertAndPrivateKeyFromMemory(certProperties.signWithX509, certProperties.signWithPkey, body_part.c_str()))
+                throw std::runtime_error("Broken signing certificate!");
+        } /*else Squid did not send certificate to sign the generated certificate*/
+        
+        certProperties.serial.reset(db.getCurrentSerialNumber());
+
+        if (!Ssl::generateSslCertificate(cert, pkey, certProperties))
+            throw std::runtime_error("Cannot create ssl certificate or private key.");
 
         if (!db.addCertAndPrivateKey(cert, pkey, cert_subject) && db.IsEnabledDiskStore())
             throw std::runtime_error("Cannot add certificate to db.");
index c6e7f8d58996a6c0ce19b0f58f912c65cc6d2b55..a41615bff40f1e28cb5839f208e64eafb0367149 100644 (file)
@@ -46,6 +46,9 @@
 #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
@@ -649,6 +652,13 @@ 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);
@@ -1260,17 +1270,12 @@ SSL_CTX * Ssl::generateSslContextUsingPkeyAndCertFromMemory(const char * data)
     return createSSLContext(cert, pkey);
 }
 
-SSL_CTX * Ssl::generateSslContext(char const *host, Ssl::X509_Pointer const & mimicCert, Ssl::X509_Pointer const & signedX509, Ssl::EVP_PKEY_Pointer const & signedPkey, Ssl::CrtdMessage::BodyParams const &mimicExceptions)
+SSL_CTX * Ssl::generateSslContext(CertificateProperties const &properties)
 {
     Ssl::X509_Pointer cert;
     Ssl::EVP_PKEY_Pointer pkey;
-    if (mimicCert .get()) {
-        if (!generateSslCertificate(mimicCert, signedX509, signedPkey, cert, pkey, NULL, mimicExceptions))
-            return NULL;
-    }
-    else if (!generateSslCertificateAndPrivateKey(host, signedX509, signedPkey, cert, pkey, NULL)) {
+    if (!generateSslCertificate(cert, pkey, properties))
         return NULL;
-    }
 
     if (!cert)
         return NULL;
index 0ba49c13765bcba14f705197bd985a8f73f6efc2..a4f571e1405d42743ca14462e1d0a5735c757104 100644 (file)
@@ -109,11 +109,25 @@ 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.
+*/
+extern EVP_PKEY_Pointer SquidCaCertKey;
+
 /**
   \ingroup ServerProtocolSSLAPI
   * Decide on the kind of certificate and generate a CA- or self-signed one
 */
-    SSL_CTX *generateSslContext(char const *host, Ssl::X509_Pointer const & mimicCert, Ssl::X509_Pointer const & signedX509, Ssl::EVP_PKEY_Pointer const & signedPkey, CrtdMessage::BodyParams const & mimicExceptions);
+SSL_CTX * generateSslContext(CertificateProperties const &properties);
 
 /**
   \ingroup ServerProtocolSSLAPI
index 5e7525fc28f116c5433be4f67feb39769f6d96d3..6aaadf29b2e4ca5fd51290b8743b03704727c688 100644 (file)
@@ -629,6 +629,7 @@ struct SquidConfig {
         char *flags;
         acl_access *cert_error;
         SSL_CTX *sslContext;
+        sslproxy_cert_sign *cert_sign;
         sslproxy_cert_adapt *cert_adapt;
     } ssl_client;
 #endif
@@ -1303,6 +1304,12 @@ struct _store_rebuild_data {
 };
 
 #if USE_SSL
+struct _sslproxy_cert_sign {
+    int alg;
+    ACLList *aclList;
+    sslproxy_cert_sign *next;
+};
+
 struct _sslproxy_cert_adapt {
     int alg;
     char *param;
index ac61115715137a1fa604a010e61efaee99a1b9d6..0129207d7754f056a01533d2812517bfa21175a8 100644 (file)
@@ -115,6 +115,8 @@ typedef struct _link_list link_list;
 typedef struct _customlog customlog;
 
 #if USE_SSL
+typedef struct _sslproxy_cert_sign sslproxy_cert_sign;
+
 typedef struct _sslproxy_cert_adapt sslproxy_cert_adapt;
 #endif