| 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;
|
| -}
|
|
|