Chromium Code Reviews| Index: net/base/x509_certificate_openssl.cc |
| diff --git a/net/base/x509_certificate_openssl.cc b/net/base/x509_certificate_openssl.cc |
| index 55c11acf8b3ef77f6966463c1782802e6dfd1046..989c48c5c186ac236309ec2a96ba35a26d311ffe 100644 |
| --- a/net/base/x509_certificate_openssl.cc |
| +++ b/net/base/x509_certificate_openssl.cc |
| @@ -233,6 +233,18 @@ bool GetDERAndCacheIfNeeded(X509Certificate::OSCertHandle cert, |
| return true; |
| } |
| +// Used to free a list of X509_NAMEs without touching its objts. |
| +// sk_X509_NAME_free is a macro and can't be used as function |
| +// template parameter. |
| +void sk_X509_NAME_free_list(STACK_OF(X509_NAME)* sk) { |
| + sk_X509_NAME_free(sk); |
| +} |
| + |
| +// Used to free a list of X509_NAMEs and the objects it points to. |
| +void sk_X509_NAME_free_all(STACK_OF(X509_NAME)* sk) { |
| + sk_X509_NAME_pop_free(sk, X509_NAME_free); |
| +} |
| + |
| } // namespace |
| // static |
| @@ -471,4 +483,63 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, |
| } |
| } |
| +bool X509Certificate::IsIssuedByEncoded( |
| + const std::vector<std::string>& valid_issuers) { |
| + if (valid_issuers.empty()) |
| + return false; |
| + |
| + // Convert to a temporary list of X509_NAME objects. |
| + // It will own the objects it points to. |
| + crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_all> |
| + issuer_names(sk_X509_NAME_new_null()); |
| + if (!issuer_names.get()) |
| + return false; |
| + |
| + for (std::vector<std::string>::const_iterator it = valid_issuers.begin(); |
| + it != valid_issuers.end(); ++it) { |
| + const unsigned char* p = |
| + reinterpret_cast<const unsigned char*>(it->data()); |
| + long len = static_cast<long>(it->length()); |
| + X509_NAME* ca_name = d2i_X509_NAME(NULL, &p, len); |
| + if (ca_name == NULL) |
| + return false; |
| + sk_X509_NAME_push(issuer_names.get(), ca_name); |
| + } |
| + |
| + // Create a temporary list of X509_NAME objects corresponding |
| + // to the certificate chain. It doesn't own the object it points to. |
| + crypto::ScopedOpenSSL<STACK_OF(X509_NAME), sk_X509_NAME_free_list> |
| + cert_names(sk_X509_NAME_new_null()); |
| + if (!cert_names.get()) |
| + return false; |
| + |
| + X509_NAME* issuer = X509_get_issuer_name(cert_handle_); |
| + if (issuer == NULL) |
| + return false; |
| + |
| + sk_X509_NAME_push(cert_names.get(), issuer); |
| + for (OSCertHandles::iterator it = intermediate_ca_certs_.begin(); |
| + it != intermediate_ca_certs_.end(); ++it) { |
| + issuer = X509_get_subject_name(*it); |
|
Ryan Sleevi
2012/12/13 19:49:05
BUG: See previous comments re: subject vs issuer
digit1
2012/12/14 17:54:33
Done.
|
| + if (issuer == NULL) |
| + return false; |
| + sk_X509_NAME_push(cert_names.get(), issuer); |
| + } |
| + |
| + // and 'cert_names'. |
|
Ryan Sleevi
2012/12/13 19:49:05
Not sure this comment really makes sense. Is it a
digit1
2012/12/14 17:54:33
Yes, it's a left-over, I've removed it.
|
| + X509_NAME* issued_by = NULL; |
| + for (int n = 0; n < sk_X509_NAME_num(cert_names.get()); ++n) { |
| + X509_NAME* cert_name = sk_X509_NAME_value(cert_names.get(), n); |
| + for (int m = 0; m < sk_X509_NAME_num(issuer_names.get()); ++m) { |
| + X509_NAME* issuer = sk_X509_NAME_value(issuer_names.get(), m); |
| + if (X509_NAME_cmp(issuer, cert_name) == 0) { |
| + issued_by = cert_name; |
| + break; |
|
Ryan Sleevi
2012/12/13 19:49:05
This breaks the inner loop but keeps spinning the
digit1
2012/12/14 17:54:33
Doh. Thanks for this.
|
| + } |
| + } |
| + } |
| + |
| + return (issued_by != NULL); |
| +} |
| + |
| } // namespace net |