15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth_request_signer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cctype> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstddef> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstdlib> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctime> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base64.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/hmac.h" 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kHexBase = 16; 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)char kHexDigits[] = "0123456789ABCDEF"; 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const size_t kHmacDigestLength = 20; 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kMaxNonceLength = 30; 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kMinNonceLength = 15; 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthConsumerKeyLabel[] = "oauth_consumer_key"; 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthNonceCharacters[] = 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "abcdefghijklmnopqrstuvwyz" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ABCDEFGHIJKLMNOPQRSTUVWYZ" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0123456789_"; 3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthNonceLabel[] = "oauth_nonce"; 3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthSignatureLabel[] = "oauth_signature"; 4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthSignatureMethodLabel[] = "oauth_signature_method"; 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthTimestampLabel[] = "oauth_timestamp"; 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthTokenLabel[] = "oauth_token"; 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthVersion[] = "1.0"; 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOAuthVersionLabel[] = "oauth_version"; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ParseQueryState { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) START_STATE, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KEYWORD_STATE, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALUE_STATE, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string HttpMethodName(OAuthRequestSigner::HttpMethod method) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (method) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::GET_METHOD: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "GET"; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::POST_METHOD: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "POST"; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string SignatureMethodName( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::SignatureMethod method) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (method) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::HMAC_SHA1_SIGNATURE: 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "HMAC-SHA1"; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::RSA_SHA1_SIGNATURE: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "RSA-SHA1"; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::PLAINTEXT_SIGNATURE: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "PLAINTEXT"; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string BuildBaseString(const GURL& request_base_url, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::HttpMethod http_method, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& base_parameters) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf("%s&%s&%s", 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HttpMethodName(http_method).c_str(), 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuthRequestSigner::Encode( 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_base_url.spec()).c_str(), 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuthRequestSigner::Encode( 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base_parameters).c_str()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string BuildBaseStringParameters( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OAuthRequestSigner::Parameters& parameters) { 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string result; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::Parameters::const_iterator cursor; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::Parameters::const_iterator limit; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool first = true; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (cursor = parameters.begin(), limit = parameters.end(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor != limit; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cursor) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first = false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += '&'; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += OAuthRequestSigner::Encode(cursor->first); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += '='; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += OAuthRequestSigner::Encode(cursor->second); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateNonce() { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char result[kMaxNonceLength + 1]; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int length = base::RandUint64() % (kMaxNonceLength - kMinNonceLength + 1) + 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinNonceLength; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result[length] = '\0'; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int index = 0; index < length; ++index) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result[index] = kOAuthNonceCharacters[ 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RandUint64() % (sizeof(kOAuthNonceCharacters) - 1)]; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GenerateTimestamp() { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::StringPrintf( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%" PRId64, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (base::Time::NowFromSystemTime() - base::Time::UnixEpoch()).InSeconds()); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a string-to-string, keyword-value map from a parameter/query string 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that uses ampersand (&) to seperate paris and equals (=) to seperate 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// keyword from value. 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ParseQuery(const std::string& query, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::Parameters* parameters_result) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator cursor; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string keyword; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator limit; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::Parameters parameters; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParseQueryState state; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string value; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = START_STATE; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (cursor = query.begin(), limit = query.end(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cursor != limit; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cursor) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char character = *cursor; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case KEYWORD_STATE: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (character) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '&': 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parameters[keyword] = value; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyword = ""; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = ""; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = START_STATE; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '=': 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = VALUE_STATE; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyword += character; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case START_STATE: 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (character) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '&': // Intentionally falling through 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '=': 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyword += character; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = KEYWORD_STATE; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VALUE_STATE: 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (character) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '=': 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '&': 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parameters[keyword] = value; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyword = ""; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = ""; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = START_STATE; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += character; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case START_STATE: 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case KEYWORD_STATE: // Intentionally falling through 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VALUE_STATE: 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parameters[keyword] = value; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *parameters_result = parameters; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates the value for the oauth_signature parameter when the 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// oauth_signature_method is HMAC-SHA1. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SignHmacSha1(const std::string& text, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* signature_return) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crypto::HMAC hmac(crypto::HMAC::SHA1); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(hmac.DigestLength() == kHmacDigestLength); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char digest[kHmacDigestLength]; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = hmac.Init(key) && 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hmac.Sign(text, digest, kHmacDigestLength); 208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (result) { 209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Base64Encode( 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string(reinterpret_cast<const char*>(digest), kHmacDigestLength), 211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) signature_return); 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates the value for the oauth_signature parameter when the 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// oauth_signature_method is PLAINTEXT. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Not yet implemented, and might never be. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SignPlaintext(const std::string& text, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* result) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates the value for the oauth_signature parameter when the 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// oauth_signature_method is RSA-SHA1. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Not yet implemented, and might never be. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SignRsaSha1(const std::string& text, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* result) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds parameters that are required by OAuth added as needed to |parameters|. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrepareParameters(OAuthRequestSigner::Parameters* parameters, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::SignatureMethod signature_method, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::HttpMethod http_method, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_key, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_key) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parameters->find(kOAuthNonceLabel) == parameters->end()) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*parameters)[kOAuthNonceLabel] = GenerateNonce(); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parameters->find(kOAuthTimestampLabel) == parameters->end()) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*parameters)[kOAuthTimestampLabel] = GenerateTimestamp(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*parameters)[kOAuthConsumerKeyLabel] = consumer_key; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*parameters)[kOAuthSignatureMethodLabel] = 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignatureMethodName(signature_method); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*parameters)[kOAuthTokenLabel] = token_key; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*parameters)[kOAuthVersionLabel] = kOAuthVersion; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements shared signing logic, generating the signature and storing it in 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |parameters|. Returns true if the signature has been generated succesfully. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SignParameters(const GURL& request_base_url, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::SignatureMethod signature_method, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::HttpMethod http_method, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_key, 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_secret, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_key, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_secret, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OAuthRequestSigner::Parameters* parameters) { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_base_url.is_valid()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrepareParameters(parameters, signature_method, http_method, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumer_key, token_key); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string base_parameters = BuildBaseStringParameters(*parameters); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string base = BuildBaseString(request_base_url, http_method, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_parameters); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string key = consumer_secret + '&' + token_secret; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_signed = false; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string signature; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (signature_method) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::HMAC_SHA1_SIGNATURE: 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_signed = SignHmacSha1(base, key, &signature); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::RSA_SHA1_SIGNATURE: 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_signed = SignRsaSha1(base, key, &signature); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OAuthRequestSigner::PLAINTEXT_SIGNATURE: 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_signed = SignPlaintext(base, key, &signature); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_signed) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*parameters)[kOAuthSignatureLabel] = signature; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_signed; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OAuthRequestSigner::Decode(const std::string& text, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* decoded_text) { 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string accumulator; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator cursor; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator limit; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (limit = text.end(), cursor = text.begin(); cursor != limit; ++cursor) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char character = *cursor; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (character == '%') { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cursor; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor == limit) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* first = strchr(kHexDigits, *cursor); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!first) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int high = first - kHexDigits; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(high >= 0 && high < kHexBase); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cursor; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cursor == limit) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* second = strchr(kHexDigits, *cursor); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!second) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int low = second - kHexDigits; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(low >= 0 || low < kHexBase); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char decoded = static_cast<char>(high * kHexBase + low); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!(IsAsciiAlpha(decoded) || IsAsciiDigit(decoded))); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!(decoded && strchr("-._~", decoded))); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accumulator += decoded; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accumulator += character; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *decoded_text = accumulator; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string OAuthRequestSigner::Encode(const std::string& text) { 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string result; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator cursor; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::const_iterator limit; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (limit = text.end(), cursor = text.begin(); cursor != limit; ++cursor) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char character = *cursor; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsAsciiAlpha(character) || IsAsciiDigit(character)) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += character; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (character) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '-': 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '.': 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '_': 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '~': 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result += character; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char byte = static_cast<unsigned char>(character); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = result + '%' + kHexDigits[byte / kHexBase] + 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kHexDigits[byte % kHexBase]; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OAuthRequestSigner::ParseAndSign(const GURL& request_url_with_parameters, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignatureMethod signature_method, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpMethod http_method, 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_key, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_secret, 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_key, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_secret, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* result) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_url_with_parameters.is_valid()); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parameters parameters; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (request_url_with_parameters.has_query()) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& query = request_url_with_parameters.query(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!query.empty()) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ParseQuery(query, ¶meters)) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string spec = request_url_with_parameters.spec(); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url_without_parameters = spec; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::size_type question = spec.find("?"); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (question != std::string::npos) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_without_parameters = spec.substr(0,question); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SignURL(GURL(url_without_parameters), parameters, signature_method, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_method, consumer_key, consumer_secret, token_key, 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_secret, result); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OAuthRequestSigner::SignURL( 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& request_base_url, 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Parameters& request_parameters, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignatureMethod signature_method, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpMethod http_method, 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_key, 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_secret, 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_key, 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_secret, 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* signed_text_return) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_base_url.is_valid()); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parameters parameters(request_parameters); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_signed = SignParameters(request_base_url, signature_method, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_method, consumer_key, consumer_secret, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_key, token_secret, ¶meters); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_signed) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string signed_text; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (http_method) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GET_METHOD: 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signed_text = request_base_url.spec() + '?'; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Intentionally falling through 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case POST_METHOD: 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signed_text += BuildBaseStringParameters(parameters); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *signed_text_return = signed_text; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_signed; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool OAuthRequestSigner::SignAuthHeader( 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& request_base_url, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Parameters& request_parameters, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignatureMethod signature_method, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpMethod http_method, 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_key, 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& consumer_secret, 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_key, 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token_secret, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* signed_text_return) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(request_base_url.is_valid()); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Parameters parameters(request_parameters); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_signed = SignParameters(request_base_url, signature_method, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_method, consumer_key, consumer_secret, 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_key, token_secret, ¶meters); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_signed) { 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string signed_text = "OAuth "; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool first = true; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Parameters::const_iterator param = parameters.begin(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) param != parameters.end(); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++param) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first = false; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signed_text += ", "; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signed_text += 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf( 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "%s=\"%s\"", 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuthRequestSigner::Encode(param->first).c_str(), 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuthRequestSigner::Encode(param->second).c_str()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *signed_text_return = signed_text; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_signed; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 460