summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorRoxie Linden <roxie@lindenlab.com>2009-12-08 00:00:51 -0800
committerRoxie Linden <roxie@lindenlab.com>2009-12-08 00:00:51 -0800
commitc70d0f0ee280f5b417426154290a752489cded13 (patch)
treebe66693e60be14da2ad2522a331330d5dfa90402 /indra/newview
parent1147cb1afbc21e1251614895844e95bca9b6b5bc (diff)
DEV-42996 GIAB: configuring via CLI tools corrupts viewer certs
Added authority key identifier/subject key identifier checking. Whenever a new cert was created, a new private key was also created. Typically you get a new key identifier with that private key which is written to the child cert. The child cert can then find the appropriate parent cert for validation via subject key identifier.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llsecapi.h6
-rw-r--r--indra/newview/llsechandler_basic.cpp75
2 files changed, 80 insertions, 1 deletions
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index b11563ef62..5211dc2699 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -78,6 +78,12 @@
#define CERT_EXTENDED_KEY_USAGE "extendedKeyUsage"
#define CERT_EKU_SERVER_AUTH SN_server_auth
+#define CERT_SUBJECT_KEY_IDENTFIER "subjectKeyIdentifier"
+#define CERT_AUTHORITY_KEY_IDENTIFIER "authorityKeyIdentifier"
+#define CERT_AUTHORITY_KEY_IDENTIFIER_ID "authorityKeyIdentifierId"
+#define CERT_AUTHORITY_KEY_IDENTIFIER_NAME "authorityKeyIdentifierName"
+#define CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL "authorityKeyIdentifierSerial"
+
// validate the current time lies within
// the validation period of the cert
#define VALIDATION_POLICY_TIME 1
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index be5c7b3c61..d41ec96ab6 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -59,10 +59,13 @@ LLS * By copying, modifying or distributing this software, you acknowledge
#define STORE_SALT_SIZE 16
#define BUFFER_READ_SIZE 256
std::string cert_string_from_asn1_string(ASN1_STRING* value);
+std::string cert_string_from_octet_string(ASN1_OCTET_STRING* value);
+
LLSD _basic_constraints_ext(X509* cert);
LLSD _key_usage_ext(X509* cert);
LLSD _ext_key_usage_ext(X509* cert);
-
+LLSD _subject_key_identifier_ext(X509 *cert);
+LLSD _authority_key_identifier_ext(X509* cert);
LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert)
{
@@ -175,6 +178,8 @@ LLSD& LLBasicCertificate::_initLLSD()
mLLSDInfo[CERT_BASIC_CONSTRAINTS] = _basic_constraints_ext(mCert);
mLLSDInfo[CERT_KEY_USAGE] = _key_usage_ext(mCert);
mLLSDInfo[CERT_EXTENDED_KEY_USAGE] = _ext_key_usage_ext(mCert);
+ mLLSDInfo[CERT_SUBJECT_KEY_IDENTFIER] = _subject_key_identifier_ext(mCert);
+ mLLSDInfo[CERT_AUTHORITY_KEY_IDENTIFIER] = _authority_key_identifier_ext(mCert);
return mLLSDInfo;
}
@@ -269,6 +274,43 @@ LLSD _ext_key_usage_ext(X509* cert)
return result;
}
+// retrieve the subject key identifier of the cert
+LLSD _subject_key_identifier_ext(X509 *cert)
+{
+ LLSD result;
+ ASN1_OCTET_STRING *skeyid = (ASN1_OCTET_STRING *)X509_get_ext_d2i(cert, NID_subject_key_identifier, NULL, NULL);
+ if(skeyid)
+ {
+ result = cert_string_from_octet_string(skeyid);
+ }
+ return result;
+}
+
+// retrieve the authority key identifier of the cert
+LLSD _authority_key_identifier_ext(X509* cert)
+{
+ LLSD result;
+ AUTHORITY_KEYID *akeyid = (AUTHORITY_KEYID *)X509_get_ext_d2i(cert, NID_authority_key_identifier, NULL, NULL);
+ if(akeyid)
+ {
+ result = LLSD::emptyMap();
+ if(akeyid->keyid)
+ {
+ result[CERT_AUTHORITY_KEY_IDENTIFIER_ID] = cert_string_from_octet_string(akeyid->keyid);
+ }
+ if(akeyid->serial)
+ {
+ result[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL] = cert_string_from_asn1_integer(akeyid->serial);
+ }
+ }
+
+ // we ignore the issuer name in the authority key identifier, we check the issue name via
+ // the the issuer name entry in the cert.
+
+
+ return result;
+}
+
// retrieve an openssl x509 object,
// which must be freed by X509_free
X509* LLBasicCertificate::getOpenSSLX509() const
@@ -337,6 +379,25 @@ std::string cert_string_from_asn1_integer(ASN1_INTEGER* value)
return result;
}
+// Generate a string from an OCTET string.
+// we retrieve as a
+
+std::string cert_string_from_octet_string(ASN1_OCTET_STRING* value)
+{
+
+ std::stringstream result;
+ result << std::hex << std::setprecision(2);
+ for (unsigned int i=0; i < value->length; i++)
+ {
+ if (i != 0)
+ {
+ result << ":";
+ }
+ result << std::setfill('0') << std::setw(2) << (int)value->data[i];
+ }
+ return result.str();
+}
+
// Generate a string from an ASN1 integer. ASN1 Integers are
// bignums, so they can be 'infinitely' long, therefore we
// cannot simply use a conversion to U64 or something.
@@ -983,6 +1044,18 @@ void LLBasicCertificateChain::validate(int validation_policy,
cert_search_params = LLSD::emptyMap();
cert_search_params[CERT_SUBJECT_NAME_STRING] = cert_llsd[CERT_ISSUER_NAME_STRING];
+ if (cert_llsd.has(CERT_AUTHORITY_KEY_IDENTIFIER))
+ {
+ LLSD cert_aki = cert_llsd[CERT_AUTHORITY_KEY_IDENTIFIER];
+ if(cert_aki.has(CERT_AUTHORITY_KEY_IDENTIFIER_ID))
+ {
+ cert_search_params[CERT_SUBJECT_KEY_IDENTFIER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_ID];
+ }
+ if(cert_aki.has(CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL))
+ {
+ cert_search_params[CERT_SERIAL_NUMBER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL];
+ }
+ }
found_store_cert = ca_store->find(cert_search_params);
if(found_store_cert != ca_store->end())