diff options
author | Roxie Linden <roxie@lindenlab.com> | 2009-12-08 00:00:51 -0800 |
---|---|---|
committer | Roxie Linden <roxie@lindenlab.com> | 2009-12-08 00:00:51 -0800 |
commit | c70d0f0ee280f5b417426154290a752489cded13 (patch) | |
tree | be66693e60be14da2ad2522a331330d5dfa90402 /indra/newview/llsechandler_basic.cpp | |
parent | 1147cb1afbc21e1251614895844e95bca9b6b5bc (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/llsechandler_basic.cpp')
-rw-r--r-- | indra/newview/llsechandler_basic.cpp | 75 |
1 files changed, 74 insertions, 1 deletions
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()) |