Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: content/browser/experiments/api_key.cc

Issue 1522813002: Add public key and signature verification to browser-side API keys (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@keys
Patch Set: Rebase against nonbroken issue 1521063003 Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/experiments/api_key.h ('k') | content/browser/experiments/api_key_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/experiments/api_key.h" 5 #include "content/browser/experiments/api_key.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_split.h" 11 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "crypto/signature_verifier.h"
16 #include "net/cert/pem_tokenizer.h"
17
18 namespace {
19
20 const char kPublicKeyPEM[] =
21 "-----BEGIN PUBLIC KEY-----"
22 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA38CwBHcz8YoCnPVwhH1p"
23 "jzmz/TKFu1ggI0+gzugBE+esApjm4I9N1PJ3/GLa+qpzp/VpgyzWqXiRoGM/RCZA"
24 "V5U+kDaoukxA33GdeA3BUrcYBIaspGRx6xXX36HLLPJF6YdjxbEByYprzecXhNUI"
25 "ql5VW3D0IR4frU5FzPy/XB5iblFxZAG4682IRRL5KdGL4OWFAPuzaKOMq7ojeKA9"
26 "y8Gu29huRknKALuScxqk+Jn5Qf3zWckLTpwyPoooXDQ116vs0b9ssalRSuBSRh4Q"
27 "tjzoQ6S1S5Zqw+2rvXfYhVZ65iiR1zzz6nBXIuUm9HAzIIF43LE6akG9E/F93ZYN"
28 "mwIDAQAB"
29 "-----END PUBLIC KEY-----";
30
31 /* By RFC 3447, the maximum salt length for RSAPSS is
32 * ceil((keySize-1)/8) - hashSize/8 - 2
33 */
34 const size_t kSaltLength = ((2048 + 6) >> 3) - (256 >> 3) - 2;
35
36 } // namespace
15 37
16 namespace content { 38 namespace content {
17 39
18 ApiKey::~ApiKey() {} 40 ApiKey::~ApiKey() {}
19 41
20 scoped_ptr<ApiKey> ApiKey::Parse(const std::string& keyText) { 42 scoped_ptr<ApiKey> ApiKey::Parse(const std::string& keyText) {
21 if (keyText.empty()) { 43 if (keyText.empty()) {
22 return nullptr; 44 return nullptr;
23 } 45 }
24 46
(...skipping 27 matching lines...) Expand all
52 const GURL& origin, 74 const GURL& origin,
53 const std::string& api_name, 75 const std::string& api_name,
54 uint64_t expiry_timestamp) 76 uint64_t expiry_timestamp)
55 : signature_(signature), 77 : signature_(signature),
56 data_(data), 78 data_(data),
57 origin_(origin), 79 origin_(origin),
58 api_name_(api_name), 80 api_name_(api_name),
59 expiry_timestamp_(expiry_timestamp) {} 81 expiry_timestamp_(expiry_timestamp) {}
60 82
61 bool ApiKey::IsValidNow(const base::Time& now) const { 83 bool ApiKey::IsValidNow(const base::Time& now) const {
84 return ValidateDate(now) && ValidateSignature(kPublicKeyPEM);
85 }
86
87 bool ApiKey::ValidateDate(const base::Time& now) const {
62 base::Time expiry_time = base::Time::FromDoubleT((double)expiry_timestamp_); 88 base::Time expiry_time = base::Time::FromDoubleT((double)expiry_timestamp_);
63 return expiry_time > now; 89 return expiry_time > now;
64 } 90 }
65 91
92 bool ApiKey::ValidateSignature(const char* publicKeyPEM) const {
93 return ValidateSignature(signature_, data_, publicKeyPEM);
94 }
95
96 // static
97 bool ApiKey::ValidateSignature(const std::string& signatureText,
98 const std::string& data,
99 const char* publicKeyPEM) {
100 std::string signature;
101 // signature is base64-encoded
102 if (!base::IsStringASCII(signatureText)) {
103 return false;
104 }
105 if (!base::Base64Decode(signatureText, &signature)) {
106 return false;
107 }
108
109 net::PEMTokenizer pem_tokenizer(publicKeyPEM, {"PUBLIC KEY"});
110 if (!pem_tokenizer.GetNext()) {
111 NOTREACHED();
112 }
113 std::string publicKey = pem_tokenizer.data();
114 std::string dataInUTF8 = data;
115 crypto::SignatureVerifier sv;
116 sv.VerifyInitRSAPSS(
117 crypto::SignatureVerifier::SHA256, crypto::SignatureVerifier::SHA256,
chasej 2015/12/17 14:13:58 Nit: add a TODO to indicate that this will eventua
iclelland 2015/12/17 15:46:02 Done.
118 kSaltLength, reinterpret_cast<const uint8*>(signature.data()),
119 signature.length(), reinterpret_cast<const uint8*>(publicKey.data()),
120 publicKey.length());
121 sv.VerifyUpdate(reinterpret_cast<const uint8*>(dataInUTF8.data()),
122 dataInUTF8.length());
123 // TODO(iclelland): Support Key revocation through CRL
124 return sv.VerifyFinal();
125 }
126
66 } // namespace 127 } // namespace
OLDNEW
« no previous file with comments | « content/browser/experiments/api_key.h ('k') | content/browser/experiments/api_key_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698