void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties)
{
    certProperties.commonName = sslCommonName_.isEmpty() ? tlsConnectHostOrIp.c_str() : sslCommonName_.c_str();

    const bool connectedOk = sslServerBump && sslServerBump->connectedOk();
    if (connectedOk) {
        if (X509 *mimicCert = sslServerBump->serverCert.get())
            certProperties.mimicCert.resetAndLock(mimicCert);

        ACLFilledChecklist checklist(NULL, sslServerBump->request.getRaw(),
                                     clientConnection != NULL ? clientConnection->rfc931 : dash_str);
        checklist.sslErrors = cbdataReference(sslServerBump->sslErrors());

        for (sslproxy_cert_adapt *ca = Config.ssl_client.cert_adapt; ca != NULL; ca = ca->next) {
            // If the algorithm already set, then ignore it.
            if ((ca->alg == Ssl::algSetCommonName && certProperties.setCommonName) ||
                    (ca->alg == Ssl::algSetValidAfter && certProperties.setValidAfter) ||
                    (ca->alg == Ssl::algSetValidBefore && certProperties.setValidBefore) )
                continue;

            if (ca->aclList && checklist.fastCheck(ca->aclList).allowed()) {
                const char *alg = Ssl::CertAdaptAlgorithmStr[ca->alg];
                const char *param = ca->param;

                // For parameterless CN adaptation, use hostname from the
                // CONNECT request.
                if (ca->alg == Ssl::algSetCommonName) {
                    if (!param)
                        param = tlsConnectHostOrIp.c_str();
                    certProperties.commonName = param;
                    certProperties.setCommonName = true;
                } else if (ca->alg == Ssl::algSetValidAfter)
                    certProperties.setValidAfter = true;
                else if (ca->alg == Ssl::algSetValidBefore)
                    certProperties.setValidBefore = true;

                debugs(33, 5, HERE << "Matches certificate adaptation aglorithm: " <<
                       alg << " param: " << (param ? 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).allowed()) {
                certProperties.signAlgorithm = (Ssl::CertSignAlgorithm)sg->alg;
                break;
            }
        }
    } else {// did not try to connect (e.g. client-first) or failed to connect
        // In case of an error while connecting to the secure server, use a
        // trusted certificate, with no mimicked fields and no adaptation
        // algorithms. There is nothing we can mimic, so we want to minimize the
        // number of warnings the user will have to see to get to the error page.
        // We will close the connection, so that the trust is not extended to
        // non-Squid content.
        certProperties.signAlgorithm = Ssl::algSignTrusted;
    }

    assert(certProperties.signAlgorithm != Ssl::algSignEnd);

    if (certProperties.signAlgorithm == Ssl::algSignUntrusted) {
        assert(port->secure.untrustedSigningCa.cert);
        certProperties.signWithX509.resetAndLock(port->secure.untrustedSigningCa.cert.get());
        certProperties.signWithPkey.resetAndLock(port->secure.untrustedSigningCa.pkey.get());
    } else {
        assert(port->secure.signingCa.cert.get());
        certProperties.signWithX509.resetAndLock(port->secure.signingCa.cert.get());

        if (port->secure.signingCa.pkey)
            certProperties.signWithPkey.resetAndLock(port->secure.signingCa.pkey.get());
    }
    signAlgorithm = certProperties.signAlgorithm;

    certProperties.signHash = Ssl::DefaultSignHash;
}