summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-30 01:44:29 +0000
committerabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-30 01:44:29 +0000
commit8155f1a70fb66b287df28784bab5235eb07ceb44 (patch)
tree80cec32822c451dd81b2b2af72fdd0722a4e0a7d
parentf402503e9d2461d38f864560edac4c62b245a427 (diff)
downloadchromium_src-8155f1a70fb66b287df28784bab5235eb07ceb44.zip
chromium_src-8155f1a70fb66b287df28784bab5235eb07ceb44.tar.gz
chromium_src-8155f1a70fb66b287df28784bab5235eb07ceb44.tar.bz2
MAC Cookies (patch 1 of N)
This is the first patch towards implementing https://github.com/hueniverse/draft-hammer-http-mac/raw/master/draft-hammer-oauth-v2-mac-token.txt Parse MAC-Key and MAC-Algorithm from Set-Cookie and store the values in memory. Future patches will use these values to sign requests. Review URL: http://codereview.chromium.org/6883253 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83649 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/automation_util.cc10
-rw-r--r--chrome/browser/extensions/extension_cookies_unittest.cc26
-rw-r--r--chrome/browser/net/sqlite_persistent_cookie_store.cc2
-rw-r--r--chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc7
-rw-r--r--net/base/cookie_monster.cc60
-rw-r--r--net/base/cookie_monster.h17
-rw-r--r--net/base/cookie_monster_store_test.cc8
-rw-r--r--net/base/cookie_monster_unittest.cc29
8 files changed, 124 insertions, 35 deletions
diff --git a/chrome/browser/automation/automation_util.cc b/chrome/browser/automation/automation_util.cc
index 2291a37..159b16c 100644
--- a/chrome/browser/automation/automation_util.cc
+++ b/chrome/browser/automation/automation_util.cc
@@ -269,6 +269,8 @@ void SetCookieJSON(AutomationProvider* provider,
std::string name, value;
std::string domain;
std::string path = "/";
+ std::string mac_key;
+ std::string mac_algorithm;
bool secure = false;
double expiry = 0;
bool http_only = false;
@@ -290,6 +292,11 @@ void SetCookieJSON(AutomationProvider* provider,
reply.SendError("optional 'path' invalid");
return;
}
+ // mac_key and mac_algorithm are optional.
+ if (cookie_dict->HasKey("mac_key"))
+ cookie_dict->GetString("mac_key", &mac_key);
+ if (cookie_dict->HasKey("mac_algorithm"))
+ cookie_dict->GetString("mac_algorithm", &mac_algorithm);
if (cookie_dict->HasKey("secure") &&
!cookie_dict->GetBoolean("secure", &secure)) {
reply.SendError("optional 'secure' invalid");
@@ -312,7 +319,8 @@ void SetCookieJSON(AutomationProvider* provider,
scoped_ptr<net::CookieMonster::CanonicalCookie> cookie(
net::CookieMonster::CanonicalCookie::Create(
- GURL(url), name, value, domain, path, base::Time(),
+ GURL(url), name, value, domain, path,
+ mac_key, mac_algorithm, base::Time(),
base::Time::FromDoubleT(expiry), secure, http_only));
if (!cookie.get()) {
reply.SendError("given 'cookie' parameters are invalid");
diff --git a/chrome/browser/extensions/extension_cookies_unittest.cc b/chrome/browser/extensions/extension_cookies_unittest.cc
index 5913412..c435fa4 100644
--- a/chrome/browser/extensions/extension_cookies_unittest.cc
+++ b/chrome/browser/extensions/extension_cookies_unittest.cc
@@ -107,8 +107,10 @@ TEST_F(ExtensionCookiesTest, ExtensionTypeCreation) {
Value* value;
net::CookieMonster::CanonicalCookie cookie1(
- GURL(), "ABC", "DEF", "www.foobar.com", "/", base::Time(), base::Time(),
- base::Time(), false, false, false);
+ GURL(), "ABC", "DEF", "www.foobar.com", "/",
+ std::string(), std::string(),
+ base::Time(), base::Time(), base::Time(),
+ false, false, false);
scoped_ptr<DictionaryValue> cookie_value1(
extension_cookies_helpers::CreateCookieValue(
cookie1, "some cookie store"));
@@ -134,7 +136,7 @@ TEST_F(ExtensionCookiesTest, ExtensionTypeCreation) {
EXPECT_EQ("some cookie store", string_value);
net::CookieMonster::CanonicalCookie cookie2(
- GURL(), "ABC", "DEF", ".foobar.com", "/",
+ GURL(), "ABC", "DEF", ".foobar.com", "/", std::string(), std::string(),
base::Time(), base::Time::FromDoubleT(10000), base::Time(),
false, false, true);
scoped_ptr<DictionaryValue> cookie_value2(
@@ -160,15 +162,19 @@ TEST_F(ExtensionCookiesTest, ExtensionTypeCreation) {
TEST_F(ExtensionCookiesTest, GetURLFromCanonicalCookie) {
net::CookieMonster::CanonicalCookie cookie1(
- GURL(), "ABC", "DEF", "www.foobar.com", "/", base::Time(), base::Time(),
- base::Time(), false, false, false);
+ GURL(), "ABC", "DEF", "www.foobar.com", "/",
+ std::string(), std::string(),
+ base::Time(), base::Time(), base::Time(),
+ false, false, false);
EXPECT_EQ("http://www.foobar.com/",
extension_cookies_helpers::GetURLFromCanonicalCookie(
cookie1).spec());
net::CookieMonster::CanonicalCookie cookie2(
- GURL(), "ABC", "DEF", ".helloworld.com", "/", base::Time(), base::Time(),
- base::Time(), true, false, false);
+ GURL(), "ABC", "DEF", ".helloworld.com", "/",
+ std::string(), std::string(),
+ base::Time(), base::Time(), base::Time(),
+ true, false, false);
EXPECT_EQ("https://helloworld.com/",
extension_cookies_helpers::GetURLFromCanonicalCookie(
cookie2).spec());
@@ -199,9 +205,9 @@ TEST_F(ExtensionCookiesTest, DomainMatching) {
details->SetString(keys::kDomainKey, std::string(tests[i].filter));
extension_cookies_helpers::MatchFilter filter(details.get());
net::CookieMonster::CanonicalCookie cookie(GURL(), "", "", tests[i].domain,
- "", base::Time(), base::Time(),
- base::Time(), false, false,
- false);
+ "", "", "", base::Time(),
+ base::Time(), base::Time(),
+ false, false, false);
EXPECT_EQ(tests[i].matches, filter.MatchesCookie(cookie));
}
}
diff --git a/chrome/browser/net/sqlite_persistent_cookie_store.cc b/chrome/browser/net/sqlite_persistent_cookie_store.cc
index f4a4642..c3c9ac7 100644
--- a/chrome/browser/net/sqlite_persistent_cookie_store.cc
+++ b/chrome/browser/net/sqlite_persistent_cookie_store.cc
@@ -204,6 +204,8 @@ bool SQLitePersistentCookieStore::Backend::Load(
smt.ColumnString(3), // value
smt.ColumnString(1), // domain
smt.ColumnString(4), // path
+ std::string(), // TODO(abarth): Persist mac_key
+ std::string(), // TODO(abarth): Persist mac_algorithm
Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc
Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc
Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
diff --git a/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc b/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc
index be4edcb..7e05697 100644
--- a/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc
+++ b/chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc
@@ -35,7 +35,8 @@ class SQLitePersistentCookieStoreTest : public testing::Test {
// Make sure the store gets written at least once.
store_->AddCookie(
net::CookieMonster::CanonicalCookie(GURL(), "A", "B", "http://foo.bar",
- "/", base::Time::Now(),
+ "/", std::string(), std::string(),
+ base::Time::Now(),
base::Time::Now(),
base::Time::Now(),
false, false, true));
@@ -129,7 +130,9 @@ TEST_F(SQLitePersistentCookieStoreTest, TestFlush) {
std::string value(1000, c);
store_->AddCookie(
net::CookieMonster::CanonicalCookie(GURL(), name, value,
- "http://foo.bar", "/", t, t, t,
+ "http://foo.bar", "/",
+ std::string(), std::string(),
+ t, t, t,
false, false, true));
}
diff --git a/net/base/cookie_monster.cc b/net/base/cookie_monster.cc
index eeb129e..6fe9bef 100644
--- a/net/base/cookie_monster.cc
+++ b/net/base/cookie_monster.cc
@@ -549,9 +549,14 @@ bool CookieMonster::SetCookieWithDetails(
Time creation_time = CurrentTime();
last_time_seen_ = creation_time;
+ // TODO(abarth): Take these values as parameters.
+ std::string mac_key;
+ std::string mac_algorithm;
+
scoped_ptr<CanonicalCookie> cc;
cc.reset(CanonicalCookie::Create(
url, name, value, domain, path,
+ mac_key, mac_algorithm,
creation_time, expiration_time,
secure, http_only));
@@ -1212,11 +1217,16 @@ bool CookieMonster::SetCookieWithCreationTimeAndOptions(
std::string cookie_path = CanonPath(url, pc);
+ // TODO(abarth): Take these values as parameters.
+ std::string mac_key;
+ std::string mac_algorithm;
+
scoped_ptr<CanonicalCookie> cc;
Time cookie_expires = CanonExpiration(pc, creation_time, options);
cc.reset(new CanonicalCookie(url, pc.Name(), pc.Value(), cookie_domain,
- cookie_path, creation_time, cookie_expires,
+ cookie_path, mac_key, mac_algorithm,
+ creation_time, cookie_expires,
creation_time, pc.IsSecure(), pc.IsHttpOnly(),
!cookie_expires.is_null()));
@@ -1634,6 +1644,8 @@ CookieMonster::ParsedCookie::ParsedCookie(const std::string& cookie_line)
: is_valid_(false),
path_index_(0),
domain_index_(0),
+ mac_key_index_(0),
+ mac_algorithm_index_(0),
expires_index_(0),
maxage_index_(0),
secure_index_(0),
@@ -1881,12 +1893,14 @@ void CookieMonster::ParsedCookie::ParseTokenValuePairs(
}
void CookieMonster::ParsedCookie::SetupAttributes() {
- static const char kPathTokenName[] = "path";
- static const char kDomainTokenName[] = "domain";
- static const char kExpiresTokenName[] = "expires";
- static const char kMaxAgeTokenName[] = "max-age";
- static const char kSecureTokenName[] = "secure";
- static const char kHttpOnlyTokenName[] = "httponly";
+ static const char kPathTokenName[] = "path";
+ static const char kDomainTokenName[] = "domain";
+ static const char kMACKeyTokenName[] = "mac-key";
+ static const char kMACAlgorithmTokenName[] = "mac-algorithm";
+ static const char kExpiresTokenName[] = "expires";
+ static const char kMaxAgeTokenName[] = "max-age";
+ static const char kSecureTokenName[] = "secure";
+ static const char kHttpOnlyTokenName[] = "httponly";
// We skip over the first token/value, the user supplied one.
for (size_t i = 1; i < pairs_.size(); ++i) {
@@ -1894,6 +1908,10 @@ void CookieMonster::ParsedCookie::SetupAttributes() {
path_index_ = i;
} else if (pairs_[i].first == kDomainTokenName) {
domain_index_ = i;
+ } else if (pairs_[i].first == kMACKeyTokenName) {
+ mac_key_index_ = i;
+ } else if (pairs_[i].first == kMACAlgorithmTokenName) {
+ mac_algorithm_index_ = i;
} else if (pairs_[i].first == kExpiresTokenName) {
expires_index_ = i;
} else if (pairs_[i].first == kMaxAgeTokenName) {
@@ -1914,22 +1932,19 @@ CookieMonster::CanonicalCookie::CanonicalCookie()
has_expires_(false) {
}
-CookieMonster::CanonicalCookie::CanonicalCookie(const GURL& url,
- const std::string& name,
- const std::string& value,
- const std::string& domain,
- const std::string& path,
- const base::Time& creation,
- const base::Time& expiration,
- const base::Time& last_access,
- bool secure,
- bool httponly,
- bool has_expires)
+CookieMonster::CanonicalCookie::CanonicalCookie(
+ const GURL& url, const std::string& name, const std::string& value,
+ const std::string& domain, const std::string& path,
+ const std::string& mac_key, const std::string& mac_algorithm,
+ const base::Time& creation, const base::Time& expiration,
+ const base::Time& last_access, bool secure, bool httponly, bool has_expires)
: source_(GetCookieSourceFromURL(url)),
name_(name),
value_(value),
domain_(domain),
path_(path),
+ mac_key_(mac_key),
+ mac_algorithm_(mac_algorithm),
creation_date_(creation),
expiry_date_(expiration),
last_access_date_(last_access),
@@ -1944,6 +1959,8 @@ CookieMonster::CanonicalCookie::CanonicalCookie(const GURL& url,
name_(pc.Name()),
value_(pc.Value()),
path_(CanonPath(url, pc)),
+ mac_key_(pc.MACKey()),
+ mac_algorithm_(pc.MACAlgorithm()),
creation_date_(Time::Now()),
last_access_date_(Time()),
secure_(pc.IsSecure()),
@@ -1988,6 +2005,8 @@ CookieMonster::CanonicalCookie* CookieMonster::CanonicalCookie::Create(
const std::string& value,
const std::string& domain,
const std::string& path,
+ const std::string& mac_key,
+ const std::string& mac_algorithm,
const base::Time& creation,
const base::Time& expiration,
bool secure,
@@ -2026,8 +2045,9 @@ CookieMonster::CanonicalCookie* CookieMonster::CanonicalCookie::Create(
canon_path_component.len);
return new CanonicalCookie(url, parsed_name, parsed_value, cookie_domain,
- cookie_path, creation, expiration, creation,
- secure, http_only, !expiration.is_null());
+ cookie_path, mac_key, mac_algorithm, creation,
+ expiration, creation, secure, http_only,
+ !expiration.is_null());
}
bool CookieMonster::CanonicalCookie::IsOnPath(
diff --git a/net/base/cookie_monster.h b/net/base/cookie_monster.h
index e150e25..00e53e4 100644
--- a/net/base/cookie_monster.h
+++ b/net/base/cookie_monster.h
@@ -539,6 +539,8 @@ class CookieMonster::CanonicalCookie {
const std::string& value,
const std::string& domain,
const std::string& path,
+ const std::string& mac_key,
+ const std::string& mac_algorithm,
const base::Time& creation,
const base::Time& expiration,
const base::Time& last_access,
@@ -563,6 +565,8 @@ class CookieMonster::CanonicalCookie {
const std::string& value,
const std::string& domain,
const std::string& path,
+ const std::string& mac_key,
+ const std::string& mac_algorithm,
const base::Time& creation,
const base::Time& expiration,
bool secure,
@@ -573,6 +577,8 @@ class CookieMonster::CanonicalCookie {
const std::string& Value() const { return value_; }
const std::string& Domain() const { return domain_; }
const std::string& Path() const { return path_; }
+ const std::string& MACKey() const { return mac_key_; }
+ const std::string& MACAlgorithm() const { return mac_algorithm_; }
const base::Time& CreationDate() const { return creation_date_; }
const base::Time& LastAccessDate() const { return last_access_date_; }
bool DoesExpire() const { return has_expires_; }
@@ -624,11 +630,14 @@ class CookieMonster::CanonicalCookie {
// this field will be null. CanonicalCookie consumers should not rely on
// this field unless they guarantee that the creator of those
// CanonicalCookies properly initialized the field.
+ // TODO(abarth): We might need to make this field persistent for MAC cookies.
std::string source_;
std::string name_;
std::string value_;
std::string domain_;
std::string path_;
+ std::string mac_key_; // TODO(abarth): Persist to disk.
+ std::string mac_algorithm_; // TODO(abarth): Persist to disk.
base::Time creation_date_;
base::Time expiry_date_;
base::Time last_access_date_;
@@ -699,6 +708,12 @@ class CookieMonster::ParsedCookie {
const std::string& Path() const { return pairs_[path_index_].second; }
bool HasDomain() const { return domain_index_ != 0; }
const std::string& Domain() const { return pairs_[domain_index_].second; }
+ bool HasMACKey() const { return mac_key_index_ != 0; }
+ const std::string& MACKey() const { return pairs_[mac_key_index_].second; }
+ bool HasMACAlgorithm() const { return mac_algorithm_index_ != 0; }
+ const std::string& MACAlgorithm() const {
+ return pairs_[mac_algorithm_index_].second;
+ }
bool HasExpires() const { return expires_index_ != 0; }
const std::string& Expires() const { return pairs_[expires_index_].second; }
bool HasMaxAge() const { return maxage_index_ != 0; }
@@ -759,6 +774,8 @@ class CookieMonster::ParsedCookie {
// could fit these into 3 bits each if we're worried about size...
size_t path_index_;
size_t domain_index_;
+ size_t mac_key_index_;
+ size_t mac_algorithm_index_;
size_t expires_index_;
size_t maxage_index_;
size_t secure_index_;
diff --git a/net/base/cookie_monster_store_test.cc b/net/base/cookie_monster_store_test.cc
index 3fcaa29..b3a6c13 100644
--- a/net/base/cookie_monster_store_test.cc
+++ b/net/base/cookie_monster_store_test.cc
@@ -95,6 +95,7 @@ void AddCookieToList(
scoped_ptr<CookieMonster::CanonicalCookie> cookie(
new CookieMonster::CanonicalCookie(
GURL(), pc.Name(), pc.Value(), key, cookie_path,
+ pc.MACKey(), pc.MACAlgorithm(),
creation_time, creation_time, cookie_expires,
pc.IsSecure(), pc.IsHttpOnly(),
!cookie_expires.is_null()));
@@ -163,10 +164,13 @@ CookieMonster* CreateMonsterFromStoreForGC(
(i < num_old_cookies) ? current - base::TimeDelta::FromDays(days_old) :
current;
+ std::string mac_key;
+ std::string mac_algorithm;
+
CookieMonster::CanonicalCookie cc(
GURL(), "a", "1", base::StringPrintf("h%05d.izzle", i), "/path",
- creation_time, expiration_time, last_access_time,
- false, false, true);
+ mac_key, mac_algorithm, creation_time, expiration_time,
+ last_access_time, false, false, true);
store->AddCookie(cc);
}
diff --git a/net/base/cookie_monster_unittest.cc b/net/base/cookie_monster_unittest.cc
index abaf84c..8233c7e 100644
--- a/net/base/cookie_monster_unittest.cc
+++ b/net/base/cookie_monster_unittest.cc
@@ -253,6 +253,35 @@ TEST(ParsedCookieTest, MultipleEquals) {
EXPECT_EQ(4U, pc.NumberOfAttributes());
}
+TEST(ParsedCookieTest, MACKey) {
+ CookieMonster::ParsedCookie pc("foo=bar; MAC-Key=3900ac9anw9incvw9f");
+ EXPECT_TRUE(pc.IsValid());
+ EXPECT_EQ("foo", pc.Name());
+ EXPECT_EQ("bar", pc.Value());
+ EXPECT_EQ("3900ac9anw9incvw9f", pc.MACKey());
+ EXPECT_EQ(1U, pc.NumberOfAttributes());
+}
+
+TEST(ParsedCookieTest, MACAlgorithm) {
+ CookieMonster::ParsedCookie pc("foo=bar; MAC-Algorithm=hmac-sha-1");
+ EXPECT_TRUE(pc.IsValid());
+ EXPECT_EQ("foo", pc.Name());
+ EXPECT_EQ("bar", pc.Value());
+ EXPECT_EQ("hmac-sha-1", pc.MACAlgorithm());
+ EXPECT_EQ(1U, pc.NumberOfAttributes());
+}
+
+TEST(ParsedCookieTest, MACKeyAndMACAlgorithm) {
+ CookieMonster::ParsedCookie pc(
+ "foo=bar; MAC-Key=voiae-09fj0302nfqf; MAC-Algorithm=hmac-sha-256");
+ EXPECT_TRUE(pc.IsValid());
+ EXPECT_EQ("foo", pc.Name());
+ EXPECT_EQ("bar", pc.Value());
+ EXPECT_EQ("voiae-09fj0302nfqf", pc.MACKey());
+ EXPECT_EQ("hmac-sha-256", pc.MACAlgorithm());
+ EXPECT_EQ(2U, pc.NumberOfAttributes());
+}
+
TEST(ParsedCookieTest, QuotedTrailingWhitespace) {
CookieMonster::ParsedCookie pc("ANCUUID=\"zohNumRKgI0oxyhSsV3Z7D\" ; "
"expires=Sun, 18-Apr-2027 21:06:29 GMT ; "