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..d1feda8a58ba7d14669be92ebd40aad72b5486e2 100644 |
--- a/net/base/x509_certificate_openssl.cc |
+++ b/net/base/x509_certificate_openssl.cc |
@@ -21,6 +21,8 @@ |
#include "crypto/openssl_util.h" |
#include "net/base/net_errors.h" |
#include "net/base/net_util.h" |
+#include "net/base/ssl_cert_request_info.h" |
+#include "net/base/x509_cert_types.h" |
#include "net/base/x509_util_openssl.h" |
#if defined(OS_ANDROID) |
@@ -471,4 +473,79 @@ void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, |
} |
} |
+bool X509Certificate::IsValidClientCertificate( |
+ const SSLCertRequestInfo& cert_info) { |
+ |
+ bool cert_still_valid = true; |
+ |
+ // Some unit tests can explicitely set |no_client_certs| to false |
+ // and fill up |client_certs|, so handle this here. |
+ if (!cert_info.no_client_certs) { |
+ const std::vector<scoped_refptr<X509Certificate> >& client_certs = |
+ cert_info.client_certs; |
+ for (size_t i = 0; i < client_certs.size(); ++i) { |
+ if (Equals(client_certs[i])) { |
+ return true; |
+ } |
+ } |
+ return false; |
+ } |
+ |
+ DCHECK(cert_info.no_client_certs == true); |
+ |
+ // TODO(digit): Check certificate authorities. |
+ // It's unclear what the best way to do this is, i.e. the specication |
+ // states that about the "certificate_authorities" field of a |
+ // CertificateRequest message: |
+ // |
+ // A list of the distinguished names of acceptable certificate |
+ // authorities. These distinguished names may specify a desired |
+ // distinguished name for a root CA or for a subordinate CA; |
+ // thus, this message can be used both to describe known roots |
+ // and a desired authorization space. |
+ // |
+ // The "authorization space" seems to indicate that each listed |
+ // distinguished name may only include a small set of strings that |
+ // need to be matched against those in the certificate chain. |
+ // |
+ // For now, ignore this step, and assume that the server will |
+ // perform the verification itself. |
+ // |
+ |
+ // Check the key type |
+ crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> scoped_key( |
+ X509_get_pubkey(cert_handle_)); |
+ if (!scoped_key.get()) |
+ return false; |
+ |
+ SSLClientCertType key_type; |
+ switch (scoped_key.get()->type) { |
+ case EVP_PKEY_RSA: |
+ key_type = CLIENT_CERT_RSA_SIGN; |
+ break; |
+#if 0 |
+ // TODO(digit): Add CLIENT_CERT_DSA_SIGN to SSLClientCertType. |
+ case EVP_PKEY_DSA: |
+ key_type = CLIENT_CERT_DSA_SIGN; |
+ break; |
+#endif |
+ case EVP_PKEY_EC: |
+ key_type = CLIENT_CERT_ECDSA_SIGN; |
+ break; |
+ default: |
+ // Unknown key type |
+ return false; |
+ } |
+ |
+ cert_still_valid = false; |
+ for (size_t n = 0; n < cert_info.valid_key_types.size(); ++n) { |
+ if (cert_info.valid_key_types[n] == key_type) { |
+ cert_still_valid = true; |
+ break; |
+ } |
+ } |
+ |
+ return cert_still_valid; |
+} |
+ |
} // namespace net |