This patch add support for mimicking TLS Authority Key Identifier
certificate extension in Squid generated TLS certificates: If the origin
server certificate has that extension, the generated certificate (via
the ssl_crtd daemon or internally) should have the same extension, with
the same set of fields if possible.
This is a Measurement Factory project
TLS Authority Key Identifier certificate extension
This patch add support for mimicking TLS Authority Key Identifier certificate
extension in Squid generated TLS certificates: If the origin server certificate
has that extension, the generated certificate (via the ssl_crtd daemon or
internally) should have the same extension, with the same set of fields if
possible.
This is a Measurement Factory project
=== modified file 'src/ssl/gadgets.cc'
--- src/ssl/gadgets.cc 2016-02-13 16:10:26 +
+++ src/ssl/gadgets.cc 2016-06-07 14:21:42 +
@@ -247,47 +247,129 @@
certKey.append("+SetValidBefore=on", 18);
if (setCommonName) {
certKey.append("+SetCommonName=", 15);
certKey.append(commonName);
}
if (signAlgorithm != Ssl::algSignEnd) {
certKey.append("+Sign=", 6);
certKey.append(certSignAlgorithm(signAlgorithm));
}
if (signHash != NULL) {
certKey.append("+SignHash=", 10);
certKey.append(EVP_MD_name(signHash));
}
return certKey;
}
+/// Check if mimicCert certificate has the Authority Key Identifier extension
+/// and if yes add the extrension to cert certificate with the same fields if
+/// possible. If the issuerCert certificate does not have the Subject Key
+/// Identifier extension (required to build the keyIdentifier field of
+/// AuthorityKeyIdentifier) then the authorityCertIssuer and
+/// authorityCertSerialNumber fields added.
+static bool
+mimicAuthorityKeyId(Security::CertPointer &cert, Security::CertPointer const &mimicCert, Security::CertPointer const &issuerCert)
+{
+if (!mimicCert.get() || !issuerCert.get())
+return false;
+
+Ssl::AUTHORITY_KEYID_Pointer akid((AUTHORITY_KEYID *)X509_get_ext_d2i(mimicCert.get(), NID_authority_key_identifier, nullptr, nullptr));
+
+bool addKeyId = false, addIssuer = false;
+if (akid.get()) {
+addKeyId = (akid.get()->keyid != nullptr);
+addIssuer = (akid.get()->issuer && akid.get()->serial);
+}
+
+if (!addKeyId && !addIssuer)
+return false; // No need to add AuthorityKeyIdentifier
+
+Ssl::ASN1_OCTET_STRING_Pointer issuerKeyId;
+if (addKeyId) {
+X509_EXTENSION *ext;
+// Check if the issuer has the Subject Key Identifier extension
+const int indx = X509_get_ext_by_NID(issuerCert.get(), NID_subject_key_identifier, -1);
+if (indx >= 0 && (ext = X509_get_ext(issuerCert.get(), indx))) {
+issuerKeyId.reset((ASN1_OCTET_STRING *)X509V3_EXT_d2i(ext));
+}
+}
+
+Ssl::X509_NAME_Pointer issuerName;
+Ssl::ASN1_INT_Pointer issuerSerial;
+if (issuerKeyId.get() == nullptr || addIssuer) {
+issuerName.reset(X509_NAME_dup(X509_get_issuer_name(issuerCert.get(;
+issuerSerial.reset(M_ASN1_INTEGER_dup(X509_get_serialNumber(issuerCert.get(;
+}
+
+Ssl::AUTHORITY_KEYID_Pointer theAuthKeyId(AUTHORITY_KEYID_new());
+if (!theAuthKeyId.get())
+return false;
+theAuthKeyId.get()->keyid = issuerKeyId.release();
+if (issuerName && issuerSerial) {
+Ssl::GENERAL_NAME_STACK_Pointer genNames(sk_GENERAL_NAME_new_null());
+if (genNames.get()) {
+if (GENERAL_NAME *aname = GENERAL_NAME_new()) {
+sk_GENERAL_NAME_push(genNames.get(), aname);
+aname->type = GEN_DIRNAME;
+aname->d.dirn = issuerName.release();
+theAuthKeyId.get()->issuer = genNames.release();
+theAuthKeyId.get()->serial = issuerSerial.release();
+}
+}
+}
+
+// The Authority Key Identifier extension should include KeyId or/and both
+/// issuer name and issuer serial
+if (!theAuthKeyId.get()->keyid && (!theAuthKeyId.get()->issuer || !theAuthKeyId.get()->serial))
+return false;
+
+const X509V3_EXT_METHOD *method = X509V3_EXT_get_nid(NID_authority_key_identifier);
+if (!method)
+return false;
+
+unsigned char *ext_der = NULL;
+int ext_len = ASN1_item_i2d((ASN1_VALUE *)theAuthKeyId.get(), &ext_der, ASN1_ITEM_ptr(method->it));
+Ssl::ASN1_OCTET_STRING_Pointer extOct(M_ASN1_OCTET_STRING_new());
+extOct.get()->data = ext_der;
+extOct.get()->length = ext_len;
+Ssl::X509_EXTENSION_Pointer extAuthKeyId(X509_EXTENSION_create_by_NID(NULL, NID_authority_key_identifier, 0, extOct.get()));
+if (!extAuthKeyId.get())
+return false;
+
+extOct.release();
+if (!X509_add_ext(cert.get(), extAuthKeyId.get(), -1))
+return false;
+
+return true;
+}
+
/// Copy certificate extensions from cert to mimicCert.
///