diff options
author | raymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-12 03:38:22 +0000 |
---|---|---|
committer | raymes@chromium.org <raymes@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-12 03:38:22 +0000 |
commit | 92a794994111f442e9c7ba1792a5418a77c2ca74 (patch) | |
tree | 6ccf61412e2d7c33adab5611354db381c8367fc1 /ppapi/shared_impl | |
parent | 8d813a832c341a54a8a8aff5702bd392e990cda7 (diff) | |
download | chromium_src-92a794994111f442e9c7ba1792a5418a77c2ca74.zip chromium_src-92a794994111f442e9c7ba1792a5418a77c2ca74.tar.gz chromium_src-92a794994111f442e9c7ba1792a5418a77c2ca74.tar.bz2 |
This adds the following to functions to the ppapi TCPSocket interface:
1) GetServer certificate, which returns the server X509Certificate if an SSL connection has been established.
2) AddChainBuilding certificate. This is currently unimplemented in Chrome but the interface and plumbing has been added so it can easily be hooked up. This should add a trusted/untrusted chain building certificate to be used by the client for a particular connection when performing the SSL handshake.
BUG=114626
TEST=out/Release/browser_tests --gtest_filter=*PPAPITest.*TCP*Trusted*
Review URL: http://codereview.chromium.org/9699100
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131918 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/shared_impl')
4 files changed, 94 insertions, 12 deletions
diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc index 665ca73..35c9d0e 100644 --- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc +++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc @@ -11,6 +11,13 @@ namespace ppapi { +PPB_X509Certificate_Fields::PPB_X509Certificate_Fields() {} + +PPB_X509Certificate_Fields::PPB_X509Certificate_Fields( + const PPB_X509Certificate_Fields& fields) { + values_.Swap(fields.values_.DeepCopy()); +} + void PPB_X509Certificate_Fields::SetField( PP_X509Certificate_Private_Field field, base::Value* value) { @@ -84,9 +91,9 @@ PPB_X509Certificate_Private_Shared::PPB_X509Certificate_Private_Shared( PPB_X509Certificate_Private_Shared::PPB_X509Certificate_Private_Shared( ResourceObjectType type, PP_Instance instance, - PPB_X509Certificate_Fields* fields) + const PPB_X509Certificate_Fields& fields) : Resource(type, instance), - fields_(fields) { + fields_(new PPB_X509Certificate_Fields(fields)) { } PPB_X509Certificate_Private_Shared::~PPB_X509Certificate_Private_Shared() { diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h index 70f84cd..8e87517 100644 --- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h +++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h @@ -22,6 +22,9 @@ namespace ppapi { class PPAPI_SHARED_EXPORT PPB_X509Certificate_Fields { public: + PPB_X509Certificate_Fields(); + PPB_X509Certificate_Fields(const PPB_X509Certificate_Fields& fields); + // Takes ownership of |value|. void SetField(PP_X509Certificate_Private_Field field, base::Value* value); PP_Var GetFieldAsPPVar(PP_X509Certificate_Private_Field field) const; @@ -42,10 +45,10 @@ class PPAPI_SHARED_EXPORT PPB_X509Certificate_Private_Shared PPB_X509Certificate_Private_Shared(ResourceObjectType type, PP_Instance instance); // Used by tcp_socket_shared_impl to construct a certificate resource from a - // server certificate. This object owns the pointer passed in. + // server certificate. PPB_X509Certificate_Private_Shared(ResourceObjectType type, PP_Instance instance, - PPB_X509Certificate_Fields* fields); + const PPB_X509Certificate_Fields& fields); virtual ~PPB_X509Certificate_Private_Shared(); // Resource overrides. diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.cc b/ppapi/shared_impl/private/tcp_socket_private_impl.cc index de99e20..c37940b 100644 --- a/ppapi/shared_impl/private/tcp_socket_private_impl.cc +++ b/ppapi/shared_impl/private/tcp_socket_private_impl.cc @@ -14,6 +14,12 @@ #include "base/message_loop.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" +#include "ppapi/shared_impl/ppapi_globals.h" +#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" +#include "ppapi/shared_impl/var_tracker.h" +#include "ppapi/shared_impl/var.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_x509_certificate_private_api.h" namespace ppapi { @@ -22,13 +28,15 @@ const int32_t TCPSocketPrivateImpl::kMaxWriteSize = 1024 * 1024; TCPSocketPrivateImpl::TCPSocketPrivateImpl(PP_Instance instance, uint32 socket_id) - : Resource(OBJECT_IS_IMPL, instance) { + : Resource(OBJECT_IS_IMPL, instance), + resource_type_(OBJECT_IS_IMPL) { Init(socket_id); } TCPSocketPrivateImpl::TCPSocketPrivateImpl(const HostResource& resource, uint32 socket_id) - : Resource(OBJECT_IS_PROXY, resource) { + : Resource(OBJECT_IS_PROXY, resource), + resource_type_(OBJECT_IS_PROXY) { Init(socket_id); } @@ -112,10 +120,48 @@ int32_t TCPSocketPrivateImpl::SSLHandshake(const char* server_name, ssl_handshake_callback_ = new TrackedCallback(this, callback); // Send the request, the browser will call us back via SSLHandshakeACK. - SendSSLHandshake(server_name, server_port); + SendSSLHandshake(server_name, server_port, trusted_certificates_, + untrusted_certificates_); return PP_OK_COMPLETIONPENDING; } +PP_Resource TCPSocketPrivateImpl::GetServerCertificate() { + if (!server_certificate_.get()) + return 0; + return server_certificate_->GetReference(); +} + +PP_Bool TCPSocketPrivateImpl::AddChainBuildingCertificate( + PP_Resource certificate, + PP_Bool trusted) { + // TODO(raymes): The plumbing for this functionality is implemented but the + // certificates aren't yet used for the connection, so just return false for + // now. + return PP_FALSE; + + thunk::EnterResourceNoLock<thunk::PPB_X509Certificate_Private_API> + enter_cert(certificate, true); + if (enter_cert.failed()) + return PP_FALSE; + + PP_Var der_var = enter_cert.object()->GetField( + PP_X509CERTIFICATE_PRIVATE_RAW); + ArrayBufferVar* der_array_buffer = ArrayBufferVar::FromPPVar(der_var); + PP_Bool success = PP_FALSE; + if (der_array_buffer) { + const char* der_bytes = static_cast<const char*>(der_array_buffer->Map()); + uint32_t der_length = der_array_buffer->ByteLength(); + std::vector<char> der(der_bytes, der_bytes + der_length); + if (PP_ToBool(trusted)) + trusted_certificates_.push_back(der); + else + untrusted_certificates_.push_back(der); + success = PP_TRUE; + } + PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(der_var); + return success; +} + int32_t TCPSocketPrivateImpl::Read(char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) { @@ -179,6 +225,7 @@ void TCPSocketPrivateImpl::Disconnect() { PostAbortIfNecessary(&write_callback_); read_buffer_ = NULL; bytes_to_read_ = -1; + server_certificate_ = NULL; } void TCPSocketPrivateImpl::OnConnectCompleted( @@ -200,7 +247,9 @@ void TCPSocketPrivateImpl::OnConnectCompleted( succeeded ? PP_OK : PP_ERROR_FAILED); } -void TCPSocketPrivateImpl::OnSSLHandshakeCompleted(bool succeeded) { +void TCPSocketPrivateImpl::OnSSLHandshakeCompleted( + bool succeeded, + const PPB_X509Certificate_Fields& certificate_fields) { if (connection_state_ != CONNECTED || !TrackedCallback::IsPending(ssl_handshake_callback_)) { NOTREACHED(); @@ -209,6 +258,10 @@ void TCPSocketPrivateImpl::OnSSLHandshakeCompleted(bool succeeded) { if (succeeded) { connection_state_ = SSL_CONNECTED; + server_certificate_ = new PPB_X509Certificate_Private_Shared( + resource_type_, + pp_instance(), + certificate_fields); TrackedCallback::ClearAndRun(&ssl_handshake_callback_, PP_OK); } else { TrackedCallback::ClearAndRun(&ssl_handshake_callback_, PP_ERROR_FAILED); diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.h b/ppapi/shared_impl/private/tcp_socket_private_impl.h index c9a65a7..8038b5c 100644 --- a/ppapi/shared_impl/private/tcp_socket_private_impl.h +++ b/ppapi/shared_impl/private/tcp_socket_private_impl.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,6 +6,7 @@ #define PPAPI_SHARED_IMPL_PRIVATE_TCP_SOCKET_PRIVATE_IMPL_H_ #include <string> +#include <vector> #include "base/compiler_specific.h" #include "ppapi/shared_impl/resource.h" @@ -14,6 +15,9 @@ namespace ppapi { +class PPB_X509Certificate_Fields; +class PPB_X509Certificate_Private_Shared; + // This class provides the shared implementation of a // PPB_TCPSocket_Private. The functions that actually send messages // to browser are implemented differently for the proxied and @@ -51,6 +55,9 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl virtual int32_t SSLHandshake(const char* server_name, uint16_t server_port, PP_CompletionCallback callback) OVERRIDE; + virtual PP_Resource GetServerCertificate() OVERRIDE; + virtual PP_Bool AddChainBuildingCertificate(PP_Resource certificate, + PP_Bool trusted) OVERRIDE; virtual int32_t Read(char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) OVERRIDE; @@ -63,7 +70,9 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl void OnConnectCompleted(bool succeeded, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr); - void OnSSLHandshakeCompleted(bool succeeded); + void OnSSLHandshakeCompleted( + bool succeeded, + const PPB_X509Certificate_Fields& certificate_fields); void OnReadCompleted(bool succeeded, const std::string& data); void OnWriteCompleted(bool succeeded, int32_t bytes_written); @@ -71,8 +80,11 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl // proxied and non-proxied derived classes. virtual void SendConnect(const std::string& host, uint16_t port) = 0; virtual void SendConnectWithNetAddress(const PP_NetAddress_Private& addr) = 0; - virtual void SendSSLHandshake(const std::string& server_name, - uint16_t server_port) = 0; + virtual void SendSSLHandshake( + const std::string& server_name, + uint16_t server_port, + const std::vector<std::vector<char> >& trusted_certs, + const std::vector<std::vector<char> >& untrusted_certs) = 0; virtual void SendRead(int32_t bytes_to_read) = 0; virtual void SendWrite(const std::string& buffer) = 0; virtual void SendDisconnect() = 0; @@ -95,6 +107,8 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl bool IsConnected() const; void PostAbortIfNecessary(scoped_refptr<TrackedCallback>* callback); + ResourceObjectType resource_type_; + uint32 socket_id_; ConnectionState connection_state_; @@ -109,6 +123,11 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl PP_NetAddress_Private local_addr_; PP_NetAddress_Private remote_addr_; + scoped_refptr<PPB_X509Certificate_Private_Shared> server_certificate_; + + std::vector<std::vector<char> > trusted_certificates_; + std::vector<std::vector<char> > untrusted_certificates_; + DISALLOW_COPY_AND_ASSIGN(TCPSocketPrivateImpl); }; |