12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/memory/ref_counted.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/content_browser_client.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/site_instance.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/cert/x509_certificate.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/private/ppb_net_address_private.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/private/net_address_private_impl.h"
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace pepper_socket_utils {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SocketPermissionRequest CreateSocketPermissionRequest(
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SocketPermissionRequest::OperationType type,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_NetAddress_Private& net_addr) {
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  std::string host =
30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      ppapi::NetAddressPrivateImpl::DescribeNetAddress(net_addr, false);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int port = 0;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<unsigned char> address;
33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ppapi::NetAddressPrivateImpl::NetAddressToIPEndPoint(
34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      net_addr, &address, &port);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SocketPermissionRequest(type, host, port);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CanUseSocketAPIs(bool external_plugin,
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                      bool private_api,
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                      const SocketPermissionRequest* params,
412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                      int render_process_id,
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      int render_frame_id) {
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!external_plugin) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Always allow socket APIs for out-process plugins (other than external
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // plugins instantiated by the embeeder through
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // BrowserPpapiHost::CreateExternalPluginProcess).
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RenderFrameHost* render_frame_host =
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RenderFrameHost::FromID(render_process_id, render_frame_id);
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!render_frame_host)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SiteInstance* site_instance = render_frame_host->GetSiteInstance();
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!site_instance)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!GetContentClient()->browser()->AllowPepperSocketAPI(
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          site_instance->GetBrowserContext(),
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          site_instance->GetSiteURL(),
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          private_api,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          params)) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Host " << site_instance->GetSiteURL().host()
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << " cannot use socket API or destination is not allowed";
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool GetCertificateFields(const net::X509Certificate& cert,
72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                          ppapi::PPB_X509Certificate_Fields* fields) {
73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const net::CertPrincipal& issuer = cert.issuer();
74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COMMON_NAME,
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(issuer.common_name));
76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_LOCALITY_NAME,
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(issuer.locality_name));
78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_STATE_OR_PROVINCE_NAME,
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(issuer.state_or_province_name));
80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COUNTRY_NAME,
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(issuer.country_name));
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  fields->SetField(
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_NAME,
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      new base::StringValue(JoinString(issuer.organization_names, '\n')));
85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  fields->SetField(
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_UNIT_NAME,
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      new base::StringValue(JoinString(issuer.organization_unit_names, '\n')));
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const net::CertPrincipal& subject = cert.subject();
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COMMON_NAME,
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(subject.common_name));
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_LOCALITY_NAME,
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(subject.locality_name));
94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_STATE_OR_PROVINCE_NAME,
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(subject.state_or_province_name));
96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COUNTRY_NAME,
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::StringValue(subject.country_name));
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  fields->SetField(
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_NAME,
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      new base::StringValue(JoinString(subject.organization_names, '\n')));
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  fields->SetField(
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_UNIT_NAME,
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      new base::StringValue(JoinString(subject.organization_unit_names, '\n')));
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const std::string& serial_number = cert.serial_number();
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_SERIAL_NUMBER,
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   base::BinaryValue::CreateWithCopiedBuffer(
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                       serial_number.data(), serial_number.length()));
109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_BEFORE,
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::FundamentalValue(cert.valid_start().ToDoubleT()));
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  fields->SetField(PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_AFTER,
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                   new base::FundamentalValue(cert.valid_expiry().ToDoubleT()));
113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::string der;
114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  net::X509Certificate::GetDEREncoded(cert.os_cert_handle(), &der);
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  fields->SetField(
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      PP_X509CERTIFICATE_PRIVATE_RAW,
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::BinaryValue::CreateWithCopiedBuffer(der.data(), der.length()));
118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return true;
119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool GetCertificateFields(const char* der,
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                          uint32_t length,
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                          ppapi::PPB_X509Certificate_Fields* fields) {
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_refptr<net::X509Certificate> cert =
125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      net::X509Certificate::CreateFromBytes(der, length);
126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!cert.get())
127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return false;
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return GetCertificateFields(*cert.get(), fields);
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace pepper_socket_utils
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
133