Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / common / extensions / api / networking_private / networking_private_crypto.cc
blob9bc336407bc17884a7eb4aecd08cf5aa4848571c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/extensions/api/networking_private/networking_private_crypto.h"
7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_util.h"
10 #include "extensions/common/cast/cast_cert_validator.h"
11 #include "net/cert/pem_tokenizer.h"
13 namespace {
15 namespace cast_crypto = ::extensions::api::cast_crypto;
17 } // namespace
19 namespace networking_private_crypto {
21 bool VerifyCredentials(
22 const std::string& certificate,
23 const std::vector<std::string>& intermediate_certificates,
24 const std::string& signature,
25 const std::string& data,
26 const std::string& connected_mac) {
27 static const char kErrorPrefix[] = "Device verification failed. ";
29 std::vector<std::string> headers;
30 headers.push_back("CERTIFICATE");
32 // Convert certificate from PEM to raw DER
33 net::PEMTokenizer pem_tok(certificate, headers);
34 if (!pem_tok.GetNext()) {
35 LOG(ERROR) << kErrorPrefix << "Failed to parse device certificate.";
36 return false;
38 std::string der_certificate = pem_tok.data();
40 // Convert intermediate certificates from PEM to raw DER
41 std::vector<std::string> der_intermediate_certificates;
42 for (size_t idx = 0; idx < intermediate_certificates.size(); ++idx) {
43 net::PEMTokenizer ica_pem_tok(intermediate_certificates[idx], headers);
44 if (ica_pem_tok.GetNext()) {
45 der_intermediate_certificates.push_back(ica_pem_tok.data());
46 } else {
47 LOG(WARNING) << "Failed to parse intermediate certificates.";
51 // Verify device certificate
52 scoped_ptr<cast_crypto::CertVerificationContext> verification_context;
53 cast_crypto::VerificationResult verification_result =
54 cast_crypto::VerifyDeviceCert(der_certificate,
55 der_intermediate_certificates,
56 &verification_context);
58 if (verification_result.Failure()) {
59 LOG(ERROR) << kErrorPrefix << verification_result.GetLogString();
60 return false;
63 // Check that the device listed in the certificate is correct.
64 // Something like evt_e161 001a11ffacdf
65 std::string common_name = verification_context->GetCommonName();
66 std::string translated_mac;
67 base::RemoveChars(connected_mac, ":", &translated_mac);
68 if (!base::EndsWith(common_name, translated_mac,
69 base::CompareCase::INSENSITIVE_ASCII)) {
70 LOG(ERROR) << kErrorPrefix << "MAC addresses don't match.";
71 return false;
74 // Use the public key from verified certificate to verify |signature| over
75 // |data|.
76 verification_result =
77 verification_context->VerifySignatureOverData(signature, data);
79 if (verification_result.Failure()) {
80 LOG(ERROR) << kErrorPrefix << verification_result.GetLogString();
81 return false;
83 return true;
86 } // namespace networking_private_crypto