Index: chrome/common/net/gaia/oauth_request_signer.cc |
diff --git a/chrome/common/net/gaia/oauth_request_signer.cc b/chrome/common/net/gaia/oauth_request_signer.cc |
deleted file mode 100644 |
index 651d48373deaaa69160a85b290b60dd4c1d40f18..0000000000000000000000000000000000000000 |
--- a/chrome/common/net/gaia/oauth_request_signer.cc |
+++ /dev/null |
@@ -1,458 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/common/net/gaia/oauth_request_signer.h" |
- |
-#include <cctype> |
-#include <cstddef> |
-#include <cstdlib> |
-#include <cstring> |
-#include <ctime> |
-#include <map> |
-#include <string> |
- |
-#include "base/base64.h" |
-#include "base/format_macros.h" |
-#include "base/logging.h" |
-#include "base/rand_util.h" |
-#include "base/string_util.h" |
-#include "base/stringprintf.h" |
-#include "base/time.h" |
-#include "crypto/hmac.h" |
-#include "googleurl/src/gurl.h" |
- |
-namespace { |
- |
-static const int kHexBase = 16; |
-static char kHexDigits[] = "0123456789ABCDEF"; |
-static const size_t kHmacDigestLength = 20; |
-static const int kMaxNonceLength = 30; |
-static const int kMinNonceLength = 15; |
- |
-static const char kOAuthConsumerKeyLabel[] = "oauth_consumer_key"; |
-static const char kOAuthConsumerSecretLabel[] = "oauth_consumer_secret"; |
-static const char kOAuthNonceCharacters[] = |
- "abcdefghijklmnopqrstuvwyz" |
- "ABCDEFGHIJKLMNOPQRSTUVWYZ" |
- "0123456789_"; |
-static const char kOAuthNonceLabel[] = "oauth_nonce"; |
-static const char kOAuthSignatureLabel[] = "oauth_signature"; |
-static const char kOAuthSignatureMethodLabel[] = "oauth_signature_method"; |
-static const char kOAuthTimestampLabel[] = "oauth_timestamp"; |
-static const char kOAuthTokenLabel[] = "oauth_token"; |
-static const char kOAuthTokenSecretLabel[] = "oauth_token_secret"; |
-static const char kOAuthVersion[] = "1.0"; |
-static const char kOAuthVersionLabel[] = "oauth_version"; |
- |
-enum ParseQueryState { |
- START_STATE, |
- KEYWORD_STATE, |
- VALUE_STATE, |
-}; |
- |
-const std::string HttpMethodName(OAuthRequestSigner::HttpMethod method) { |
- switch (method) { |
- case OAuthRequestSigner::GET_METHOD: |
- return "GET"; |
- case OAuthRequestSigner::POST_METHOD: |
- return "POST"; |
- } |
- NOTREACHED(); |
- return *(new std::string()); |
-} |
- |
-const std::string SignatureMethodName( |
- OAuthRequestSigner::SignatureMethod method) { |
- switch (method) { |
- case OAuthRequestSigner::HMAC_SHA1_SIGNATURE: |
- return "HMAC-SHA1"; |
- case OAuthRequestSigner::RSA_SHA1_SIGNATURE: |
- return "RSA-SHA1"; |
- case OAuthRequestSigner::PLAINTEXT_SIGNATURE: |
- return "PLAINTEXT"; |
- } |
- NOTREACHED(); |
- return *(new std::string()); |
-} |
- |
-std::string BuildBaseString(const GURL& request_base_url, |
- OAuthRequestSigner::HttpMethod http_method, |
- const std::string& base_parameters) { |
- return StringPrintf("%s&%s&%s", |
- HttpMethodName(http_method).c_str(), |
- OAuthRequestSigner::Encode( |
- request_base_url.spec()).c_str(), |
- OAuthRequestSigner::Encode( |
- base_parameters).c_str()); |
-} |
- |
-std::string BuildBaseStringParameters( |
- const OAuthRequestSigner::Parameters& parameters) { |
- std::string result = ""; |
- OAuthRequestSigner::Parameters::const_iterator cursor; |
- OAuthRequestSigner::Parameters::const_iterator limit; |
- bool first = true; |
- for (cursor = parameters.begin(), limit = parameters.end(); |
- cursor != limit; |
- ++cursor) { |
- if (first) |
- first = false; |
- else |
- result += '&'; |
- result += OAuthRequestSigner::Encode(cursor->first); |
- result += '='; |
- result += OAuthRequestSigner::Encode(cursor->second); |
- } |
- return result; |
-} |
- |
-std::string GenerateNonce() { |
- char result[kMaxNonceLength + 1]; |
- int length = base::RandUint64() % (kMaxNonceLength - kMinNonceLength + 1) + |
- kMinNonceLength; |
- result[length] = '\0'; |
- for (int index = 0; index < length; ++index) |
- result[index] = kOAuthNonceCharacters[ |
- base::RandUint64() % (sizeof(kOAuthNonceCharacters) - 1)]; |
- return result; |
-} |
- |
-std::string GenerateTimestamp() { |
- return base::StringPrintf( |
- "%" PRId64, |
- (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()).InSeconds()); |
-} |
- |
-// Creates a string-to-string, keyword-value map from a parameter/query string |
-// that uses ampersand (&) to seperate paris and equals (=) to seperate |
-// keyword from value. |
-bool ParseQuery(const std::string& query, |
- OAuthRequestSigner::Parameters* parameters_result) { |
- std::string::const_iterator cursor; |
- std::string keyword; |
- std::string::const_iterator limit; |
- OAuthRequestSigner::Parameters parameters; |
- ParseQueryState state; |
- std::string value; |
- |
- state = START_STATE; |
- for (cursor = query.begin(), limit = query.end(); |
- cursor != limit; |
- ++cursor) { |
- char character = *cursor; |
- switch (state) { |
- case KEYWORD_STATE: |
- switch (character) { |
- case '&': |
- parameters[keyword] = value; |
- keyword = ""; |
- value = ""; |
- state = START_STATE; |
- break; |
- case '=': |
- state = VALUE_STATE; |
- break; |
- default: |
- keyword += character; |
- } |
- break; |
- case START_STATE: |
- switch (character) { |
- case '&': // Intentionally falling through |
- case '=': |
- return false; |
- default: |
- keyword += character; |
- state = KEYWORD_STATE; |
- } |
- break; |
- case VALUE_STATE: |
- switch (character) { |
- case '=': |
- return false; |
- case '&': |
- parameters[keyword] = value; |
- keyword = ""; |
- value = ""; |
- state = START_STATE; |
- break; |
- default: |
- value += character; |
- } |
- break; |
- } |
- } |
- switch (state) { |
- case START_STATE: |
- break; |
- case KEYWORD_STATE: // Intentionally falling through |
- case VALUE_STATE: |
- parameters[keyword] = value; |
- break; |
- default: |
- NOTREACHED(); |
- } |
- *parameters_result = parameters; |
- return true; |
-} |
- |
-// Creates the value for the oauth_signature parameter when the |
-// oauth_signature_method is HMAC-SHA1. |
-bool SignHmacSha1(const std::string& text, |
- const std::string& key, |
- std::string* signature_return) { |
- crypto::HMAC hmac(crypto::HMAC::SHA1); |
- DCHECK(hmac.DigestLength() == kHmacDigestLength); |
- unsigned char digest[kHmacDigestLength]; |
- bool result = hmac.Init(key) && |
- hmac.Sign(text, digest, kHmacDigestLength) && |
- base::Base64Encode(std::string(reinterpret_cast<const char*>(digest), |
- kHmacDigestLength), |
- signature_return); |
- return result; |
-} |
- |
-// Creates the value for the oauth_signature parameter when the |
-// oauth_signature_method is PLAINTEXT. |
-// |
-// Not yet implemented, and might never be. |
-bool SignPlaintext(const std::string& text, |
- const std::string& key, |
- std::string* result) { |
- NOTIMPLEMENTED(); |
- return false; |
-} |
- |
-// Creates the value for the oauth_signature parameter when the |
-// oauth_signature_method is RSA-SHA1. |
-// |
-// Not yet implemented, and might never be. |
-bool SignRsaSha1(const std::string& text, |
- const std::string& key, |
- std::string* result) { |
- NOTIMPLEMENTED(); |
- return false; |
-} |
- |
-// Adds parameters that are required by OAuth added as needed to |parameters|. |
-void PrepareParameters(OAuthRequestSigner::Parameters* parameters, |
- OAuthRequestSigner::SignatureMethod signature_method, |
- OAuthRequestSigner::HttpMethod http_method, |
- const std::string& consumer_key, |
- const std::string& token_key) { |
- if (parameters->find(kOAuthNonceLabel) == parameters->end()) |
- (*parameters)[kOAuthNonceLabel] = GenerateNonce(); |
- |
- if (parameters->find(kOAuthTimestampLabel) == parameters->end()) |
- (*parameters)[kOAuthTimestampLabel] = GenerateTimestamp(); |
- |
- (*parameters)[kOAuthConsumerKeyLabel] = consumer_key; |
- (*parameters)[kOAuthSignatureMethodLabel] = |
- SignatureMethodName(signature_method); |
- (*parameters)[kOAuthTokenLabel] = token_key; |
- (*parameters)[kOAuthVersionLabel] = kOAuthVersion; |
-} |
- |
-// Implements shared signing logic, generating the signature and storing it in |
-// |parameters|. Returns true if the signature has been generated succesfully. |
-bool SignParameters(const GURL& request_base_url, |
- OAuthRequestSigner::SignatureMethod signature_method, |
- OAuthRequestSigner::HttpMethod http_method, |
- const std::string& consumer_key, |
- const std::string& consumer_secret, |
- const std::string& token_key, |
- const std::string& token_secret, |
- OAuthRequestSigner::Parameters* parameters) { |
- DCHECK(request_base_url.is_valid()); |
- PrepareParameters(parameters, signature_method, http_method, |
- consumer_key, token_key); |
- std::string base_parameters = BuildBaseStringParameters(*parameters); |
- std::string base = BuildBaseString(request_base_url, http_method, |
- base_parameters); |
- std::string key = consumer_secret + '&' + token_secret; |
- bool is_signed = false; |
- std::string signature; |
- switch (signature_method) { |
- case OAuthRequestSigner::HMAC_SHA1_SIGNATURE: |
- is_signed = SignHmacSha1(base, key, &signature); |
- break; |
- case OAuthRequestSigner::RSA_SHA1_SIGNATURE: |
- is_signed = SignRsaSha1(base, key, &signature); |
- break; |
- case OAuthRequestSigner::PLAINTEXT_SIGNATURE: |
- is_signed = SignPlaintext(base, key, &signature); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- if (is_signed) |
- (*parameters)[kOAuthSignatureLabel] = signature; |
- return is_signed; |
-} |
- |
- |
-} // namespace |
- |
-// static |
-bool OAuthRequestSigner::Decode(const std::string& text, |
- std::string* decoded_text) { |
- std::string accumulator = ""; |
- std::string::const_iterator cursor; |
- std::string::const_iterator limit; |
- for (limit = text.end(), cursor = text.begin(); cursor != limit; ++cursor) { |
- char character = *cursor; |
- if (character == '%') { |
- ++cursor; |
- if (cursor == limit) |
- return false; |
- char* first = strchr(kHexDigits, *cursor); |
- if (!first) |
- return false; |
- int high = first - kHexDigits; |
- DCHECK(high >= 0 && high < kHexBase); |
- |
- ++cursor; |
- if (cursor == limit) |
- return false; |
- char* second = strchr(kHexDigits, *cursor); |
- if (!second) |
- return false; |
- int low = second - kHexDigits; |
- DCHECK(low >= 0 || low < kHexBase); |
- |
- char decoded = static_cast<char>(high * kHexBase + low); |
- DCHECK(!(IsAsciiAlpha(decoded) || IsAsciiDigit(decoded))); |
- DCHECK(!(decoded && strchr("-._~", decoded))); |
- accumulator += decoded; |
- } else { |
- accumulator += character; |
- } |
- } |
- *decoded_text = accumulator; |
- return true; |
-} |
- |
-// static |
-std::string OAuthRequestSigner::Encode(const std::string& text) { |
- std::string result = ""; |
- std::string::const_iterator cursor; |
- std::string::const_iterator limit; |
- for (limit = text.end(), cursor = text.begin(); cursor != limit; ++cursor) { |
- char character = *cursor; |
- if (IsAsciiAlpha(character) || IsAsciiDigit(character)) { |
- result += character; |
- } else { |
- switch (character) { |
- case '-': |
- case '.': |
- case '_': |
- case '~': |
- result += character; |
- break; |
- default: |
- unsigned char byte = static_cast<unsigned char>(character); |
- result = result + '%' + kHexDigits[byte / kHexBase] + |
- kHexDigits[byte % kHexBase]; |
- } |
- } |
- } |
- return result; |
-} |
- |
-// static |
-bool OAuthRequestSigner::ParseAndSign(const GURL& request_url_with_parameters, |
- SignatureMethod signature_method, |
- HttpMethod http_method, |
- const std::string& consumer_key, |
- const std::string& consumer_secret, |
- const std::string& token_key, |
- const std::string& token_secret, |
- std::string* result) { |
- DCHECK(request_url_with_parameters.is_valid()); |
- Parameters parameters; |
- if (request_url_with_parameters.has_query()) { |
- const std::string& query = request_url_with_parameters.query(); |
- if (!query.empty()) { |
- if (!ParseQuery(query, ¶meters)) |
- return false; |
- } |
- } |
- std::string spec = request_url_with_parameters.spec(); |
- std::string url_without_parameters = spec; |
- std::string::size_type question = spec.find("?"); |
- if (question != std::string::npos) |
- url_without_parameters = spec.substr(0,question); |
- return SignURL(GURL(url_without_parameters), parameters, signature_method, |
- http_method, consumer_key, consumer_secret, token_key, |
- token_secret, result); |
-} |
- |
-// static |
-bool OAuthRequestSigner::SignURL( |
- const GURL& request_base_url, |
- const Parameters& request_parameters, |
- SignatureMethod signature_method, |
- HttpMethod http_method, |
- const std::string& consumer_key, |
- const std::string& consumer_secret, |
- const std::string& token_key, |
- const std::string& token_secret, |
- std::string* signed_text_return) { |
- DCHECK(request_base_url.is_valid()); |
- Parameters parameters(request_parameters); |
- bool is_signed = SignParameters(request_base_url, signature_method, |
- http_method, consumer_key, consumer_secret, |
- token_key, token_secret, ¶meters); |
- if (is_signed) { |
- std::string signed_text; |
- switch (http_method) { |
- case GET_METHOD: |
- signed_text = request_base_url.spec() + '?'; |
- // Intentionally falling through |
- case POST_METHOD: |
- signed_text += BuildBaseStringParameters(parameters); |
- break; |
- default: |
- NOTREACHED(); |
- } |
- *signed_text_return = signed_text; |
- } |
- return is_signed; |
-} |
- |
-// static |
-bool OAuthRequestSigner::SignAuthHeader( |
- const GURL& request_base_url, |
- const Parameters& request_parameters, |
- SignatureMethod signature_method, |
- HttpMethod http_method, |
- const std::string& consumer_key, |
- const std::string& consumer_secret, |
- const std::string& token_key, |
- const std::string& token_secret, |
- std::string* signed_text_return) { |
- DCHECK(request_base_url.is_valid()); |
- Parameters parameters(request_parameters); |
- bool is_signed = SignParameters(request_base_url, signature_method, |
- http_method, consumer_key, consumer_secret, |
- token_key, token_secret, ¶meters); |
- if (is_signed) { |
- std::string signed_text = "OAuth "; |
- bool first = true; |
- for (Parameters::const_iterator param = parameters.begin(); |
- param != parameters.end(); |
- ++param) { |
- if (first) |
- first = false; |
- else |
- signed_text += ", "; |
- signed_text += |
- StringPrintf("%s=\"%s\"", |
- OAuthRequestSigner::Encode(param->first).c_str(), |
- OAuthRequestSigner::Encode(param->second).c_str()); |
- } |
- *signed_text_return = signed_text; |
- } |
- return is_signed; |
-} |