| 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
|
|
|