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

Side by Side Diff: net/http/http_mac_signature.cc

Issue 6901121: MAC Cookies (patch 2 of N) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 8 months 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 | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "net/http/http_mac_signature.h"
6
7 #include "base/base64.h"
8 #include "base/rand_util.h"
9 #include "base/string_number_conversions.h"
10 #include "base/string_util.h"
11 #include "base/time.h"
12 #include "crypto/hmac.h"
13
14 namespace net {
15
16 namespace {
17
18 const char kSHA1Name[] = "hmac-sha-1";
19 const char kSHA256Name[] = "hmac-sha-256";
20 const int kNonceLength = 256 / 8;
21
22 size_t LengthForHMACAlgorithm(crypto::HMAC::HashAlgorithm algorithm) {
cbentzel 2011/04/29 14:44:49 I'm kind of surprised this isn't an HMAC method. S
abarth-chromium 2011/04/29 18:16:01 Yes. I'll add it.
23 if (algorithm == crypto::HMAC::SHA1)
24 return 20;
25 if (algorithm == crypto::HMAC::SHA256)
26 return 32;
27 NOTREACHED();
28 return 20;
29 }
30
31 bool IsPlainStringCharacter(char character) {
32 return character == 0x20 || character == 0x21 ||
33 (character >= 0x23 && character <= 0x5B) ||
34 (character >= 0x5D && character <= 0x7E);
35 }
36
37 bool IsPlainString(const std::string& string) {
38 for (size_t i = 0; i < string.size(); ++i) {
39 if (!IsPlainStringCharacter(string[i]))
40 return false;
41 }
42 return true;
43 }
44
45 std::string GenerateNonce() {
46 std::string nonce;
47 bool result = base::Base64Encode(base::RandString(kNonceLength), &nonce);
48 DCHECK(result);
49 return nonce;
50 }
51
52 }
53
54 HttpMacSignature::HttpMacSignature()
55 : mac_algorithm_(crypto::HMAC::SHA1)
56 {
cbentzel 2011/04/29 14:44:49 Nit: { typically on same line as the last initiali
abarth-chromium 2011/04/29 18:16:01 Fixed. (WebKit style leaking in.)
57 }
58
59 HttpMacSignature::~HttpMacSignature() {
60 }
61
62 bool HttpMacSignature::AddStateInfo(const std::string& id,
cbentzel 2011/04/29 14:44:49 Should this be callable multiple times?
abarth-chromium 2011/04/29 18:16:01 Not if it returns true. DCHECK added.
63 const std::string& mac_key,
64 const std::string& mac_algorithm,
65 const std::string& issuer) {
66 if (!IsPlainString(id) || id.empty()
67 || !IsPlainString(mac_key) || mac_key.empty()
68 || !IsPlainString(issuer) || issuer.empty())
69 return false;
70
71 if (mac_algorithm == kSHA1Name)
cbentzel 2011/04/29 14:44:49 Very tiny issue: maybe do input validity checking
abarth-chromium 2011/04/29 18:16:01 Do you mean checking for IsPlainString ? The mac_
cbentzel 2011/04/29 18:37:56 Sorry, I just meant moving this into if (!IsPlain
72 mac_algorithm_ = crypto::HMAC::SHA1;
73 else if (mac_algorithm == kSHA256Name)
74 mac_algorithm_ = crypto::HMAC::SHA256;
75 else
76 return false;
77
78 id_ = id;
79 mac_key_ = mac_key;
80 issuer_ = issuer;
81 return true;
82 }
83
84 bool HttpMacSignature::AddHttpInfo(const std::string& method,
85 const std::string& request_uri,
86 const std::string& host,
87 int port) {
88 if (!IsPlainString(method) || method.empty()
89 || !IsPlainString(request_uri) || request_uri.empty()
90 || !IsPlainString(host) || host.empty()
91 || port <= 0)
cbentzel 2011/04/29 14:44:49 Add a port > 65535 check as well.
abarth-chromium 2011/04/29 18:16:01 Done.
92 return false;
93
94 method_ = StringToUpperASCII(method);
95 request_uri_ = request_uri;
96 host_ = StringToLowerASCII(host);
97 port_ = base::IntToString(port);
98 return true;
99 }
100
101 std::string HttpMacSignature::GenerateAuthorizationHeader() {
102 DCHECK(!id_.empty()) << "Call AddStateInfo first.";
103 DCHECK(port_.empty()) << "Call AddHttpInfo first.";
cbentzel 2011/04/29 14:44:49 !port_.empty()
abarth-chromium 2011/04/29 18:16:01 I've changed this to used method_, actually, which
104
105 std::string timestamp = base::IntToString((base::Time::Now() -
106 base::Time::UnixEpoch()).InSeconds());
107 std::string nonce = GenerateNonce();
108 std::string mac = GenerateMAC(timestamp, nonce);
109
110 DCHECK(IsPlainString(timestamp));
111 DCHECK(IsPlainString(nonce));
112 DCHECK(IsPlainString(mac));
113
114 std::string header = "MAC id=\"" + id_ +
115 "\", issuer=\"" + issuer_ +
116 "\", timestamp=\"" + timestamp +
117 "\", nonce=\"" + nonce +
118 "\", mac=\"" + mac + "\"";
119
120 return header;
121 }
122
123 std::string HttpMacSignature::GenerateNormalizedRequest(
124 const std::string& timestamp,
125 const std::string& nonce) {
126 static const std::string kNewLine = "\n";
127
128 std::string normalized_request = id_ + kNewLine;
129 normalized_request += issuer_ + kNewLine;
130 normalized_request += timestamp + kNewLine;
131 normalized_request += nonce + kNewLine;
132 normalized_request += method_ + kNewLine;
133 normalized_request += request_uri_ + kNewLine;
134 normalized_request += host_ + kNewLine;
135 normalized_request += port_ + kNewLine;
136
137 return normalized_request;
138 }
139
140 std::string HttpMacSignature::GenerateMAC(const std::string& timestamp,
cbentzel 2011/04/29 14:44:49 Should these be returning a bool in case hmac.Sign
abarth-chromium 2011/04/29 18:16:01 Base64Encode can't fail in these cases because the
cbentzel 2011/04/29 18:37:56 DCHECK seems fine, although I have not looked at w
141 const std::string& nonce) {
142 std::string request = GenerateNormalizedRequest(timestamp, nonce);
143
144 crypto::HMAC hmac(mac_algorithm_);
145 hmac.Init(mac_key_);
146
147 std::string signature;
148 size_t length = LengthForHMACAlgorithm(mac_algorithm_);
149 char* buffer = WriteInto(&signature, length);
150 hmac.Sign(request, reinterpret_cast<unsigned char*>(buffer), length);
cbentzel 2011/04/29 14:44:49 You should check the result of hmac.Sign
abarth-chromium 2011/04/29 18:16:01 I've added a DCHECK.
151
152 std::string encoded_signature;
153 bool result = base::Base64Encode(signature, &encoded_signature);
154 DCHECK(result);
155 return encoded_signature;
156 }
157
158 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698