| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/net/gaia/oauth_request_signer.h" | 5 #include "chrome/common/net/gaia/oauth_request_signer.h" |
| 6 | 6 |
| 7 #include <cctype> | 7 #include <cctype> |
| 8 #include <cstddef> | 8 #include <cstddef> |
| 9 #include <cstdlib> | 9 #include <cstdlib> |
| 10 #include <cstring> | 10 #include <cstring> |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 // oauth_signature_method is RSA-SHA1. | 227 // oauth_signature_method is RSA-SHA1. |
| 228 // | 228 // |
| 229 // Not yet implemented, and might never be. | 229 // Not yet implemented, and might never be. |
| 230 bool SignRsaSha1(const std::string& text, | 230 bool SignRsaSha1(const std::string& text, |
| 231 const std::string& key, | 231 const std::string& key, |
| 232 std::string* result) { | 232 std::string* result) { |
| 233 NOTIMPLEMENTED(); | 233 NOTIMPLEMENTED(); |
| 234 return false; | 234 return false; |
| 235 } | 235 } |
| 236 | 236 |
| 237 // Adds parameters that are required by OAuth added as needed to |parameters|. | |
| 238 void PrepareParameters(OAuthRequestSigner::Parameters* parameters, | |
| 239 OAuthRequestSigner::SignatureMethod signature_method, | |
| 240 OAuthRequestSigner::HttpMethod http_method, | |
| 241 const std::string& consumer_key, | |
| 242 const std::string& token_key) { | |
| 243 if (parameters->find(kOAuthNonceLabel) == parameters->end()) | |
| 244 (*parameters)[kOAuthNonceLabel] = GenerateNonce(); | |
| 245 | |
| 246 if (parameters->find(kOAuthTimestampLabel) == parameters->end()) | |
| 247 (*parameters)[kOAuthTimestampLabel] = GenerateTimestamp(); | |
| 248 | |
| 249 (*parameters)[kOAuthConsumerKeyLabel] = consumer_key; | |
| 250 (*parameters)[kOAuthSignatureMethodLabel] = | |
| 251 SignatureMethodName(signature_method); | |
| 252 (*parameters)[kOAuthTokenLabel] = token_key; | |
| 253 (*parameters)[kOAuthVersionLabel] = kOAuthVersion; | |
| 254 } | |
| 255 | |
| 256 // Implements shared signing logic, generating the signature and storing it in | |
| 257 // |parameters|. Returns true if the signature has been generated succesfully. | |
| 258 bool SignParameters(const GURL& request_base_url, | |
| 259 OAuthRequestSigner::SignatureMethod signature_method, | |
| 260 OAuthRequestSigner::HttpMethod http_method, | |
| 261 const std::string& consumer_key, | |
| 262 const std::string& consumer_secret, | |
| 263 const std::string& token_key, | |
| 264 const std::string& token_secret, | |
| 265 OAuthRequestSigner::Parameters* parameters) { | |
| 266 DCHECK(request_base_url.is_valid()); | |
| 267 PrepareParameters(parameters, signature_method, http_method, | |
| 268 consumer_key, token_key); | |
| 269 std::string base_parameters = BuildBaseStringParameters(*parameters); | |
| 270 std::string base = BuildBaseString(request_base_url, http_method, | |
| 271 base_parameters); | |
| 272 std::string key = consumer_secret + '&' + token_secret; | |
| 273 bool is_signed = false; | |
| 274 std::string signature; | |
| 275 switch (signature_method) { | |
| 276 case OAuthRequestSigner::HMAC_SHA1_SIGNATURE: | |
| 277 is_signed = SignHmacSha1(base, key, &signature); | |
| 278 break; | |
| 279 case OAuthRequestSigner::RSA_SHA1_SIGNATURE: | |
| 280 is_signed = SignRsaSha1(base, key, &signature); | |
| 281 break; | |
| 282 case OAuthRequestSigner::PLAINTEXT_SIGNATURE: | |
| 283 is_signed = SignPlaintext(base, key, &signature); | |
| 284 break; | |
| 285 default: | |
| 286 NOTREACHED(); | |
| 287 } | |
| 288 if (is_signed) | |
| 289 (*parameters)[kOAuthSignatureLabel] = signature; | |
| 290 return is_signed; | |
| 291 } | |
| 292 | |
| 293 | |
| 294 } // namespace | 237 } // namespace |
| 295 | 238 |
| 296 // static | 239 // static |
| 297 bool OAuthRequestSigner::Decode(const std::string& text, | 240 bool OAuthRequestSigner::Decode(const std::string& text, |
| 298 std::string* decoded_text) { | 241 std::string* decoded_text) { |
| 299 std::string accumulator = ""; | 242 std::string accumulator = ""; |
| 300 std::string::const_iterator cursor; | 243 std::string::const_iterator cursor; |
| 301 std::string::const_iterator limit; | 244 std::string::const_iterator limit; |
| 302 for (limit = text.end(), cursor = text.begin(); cursor != limit; ++cursor) { | 245 for (limit = text.end(), cursor = text.begin(); cursor != limit; ++cursor) { |
| 303 char character = *cursor; | 246 char character = *cursor; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 if (!query.empty()) { | 318 if (!query.empty()) { |
| 376 if (!ParseQuery(query, ¶meters)) | 319 if (!ParseQuery(query, ¶meters)) |
| 377 return false; | 320 return false; |
| 378 } | 321 } |
| 379 } | 322 } |
| 380 std::string spec = request_url_with_parameters.spec(); | 323 std::string spec = request_url_with_parameters.spec(); |
| 381 std::string url_without_parameters = spec; | 324 std::string url_without_parameters = spec; |
| 382 std::string::size_type question = spec.find("?"); | 325 std::string::size_type question = spec.find("?"); |
| 383 if (question != std::string::npos) | 326 if (question != std::string::npos) |
| 384 url_without_parameters = spec.substr(0,question); | 327 url_without_parameters = spec.substr(0,question); |
| 385 return SignURL(GURL(url_without_parameters), parameters, signature_method, | 328 return Sign (GURL(url_without_parameters), parameters, signature_method, |
| 386 http_method, consumer_key, consumer_secret, token_key, | 329 http_method, consumer_key, consumer_secret, token_key, |
| 387 token_secret, result); | 330 token_secret, result); |
| 331 } |
| 332 |
| 333 // Returns a copy of request_parameters, with parameters that are required by |
| 334 // OAuth added as needed. |
| 335 OAuthRequestSigner::Parameters |
| 336 PrepareParameters(const OAuthRequestSigner::Parameters& request_parameters, |
| 337 OAuthRequestSigner::SignatureMethod signature_method, |
| 338 OAuthRequestSigner::HttpMethod http_method, |
| 339 const std::string& consumer_key, |
| 340 const std::string& token_key) { |
| 341 OAuthRequestSigner::Parameters result(request_parameters); |
| 342 |
| 343 if (result.find(kOAuthNonceLabel) == result.end()) |
| 344 result[kOAuthNonceLabel] = GenerateNonce(); |
| 345 |
| 346 if (result.find(kOAuthTimestampLabel) == result.end()) |
| 347 result[kOAuthTimestampLabel] = GenerateTimestamp(); |
| 348 |
| 349 result[kOAuthConsumerKeyLabel] = consumer_key; |
| 350 result[kOAuthSignatureMethodLabel] = SignatureMethodName(signature_method); |
| 351 result[kOAuthTokenLabel] = token_key; |
| 352 result[kOAuthVersionLabel] = kOAuthVersion; |
| 353 |
| 354 return result; |
| 388 } | 355 } |
| 389 | 356 |
| 390 // static | 357 // static |
| 391 bool OAuthRequestSigner::SignURL( | 358 bool OAuthRequestSigner::Sign( |
| 392 const GURL& request_base_url, | 359 const GURL& request_base_url, |
| 393 const Parameters& request_parameters, | 360 const Parameters& request_parameters, |
| 394 SignatureMethod signature_method, | 361 SignatureMethod signature_method, |
| 395 HttpMethod http_method, | 362 HttpMethod http_method, |
| 396 const std::string& consumer_key, | 363 const std::string& consumer_key, |
| 397 const std::string& consumer_secret, | 364 const std::string& consumer_secret, |
| 398 const std::string& token_key, | 365 const std::string& token_key, |
| 399 const std::string& token_secret, | 366 const std::string& token_secret, |
| 400 std::string* signed_text_return) { | 367 std::string* signed_text_return) { |
| 401 DCHECK(request_base_url.is_valid()); | 368 DCHECK(request_base_url.is_valid()); |
| 402 Parameters parameters(request_parameters); | 369 Parameters parameters = PrepareParameters(request_parameters, |
| 403 bool is_signed = SignParameters(request_base_url, signature_method, | 370 signature_method, |
| 404 http_method, consumer_key, consumer_secret, | 371 http_method, |
| 405 token_key, token_secret, ¶meters); | 372 consumer_key, |
| 373 token_key); |
| 374 std::string base_parameters = BuildBaseStringParameters(parameters); |
| 375 std::string base = BuildBaseString(request_base_url, |
| 376 http_method, |
| 377 base_parameters); |
| 378 std::string key = consumer_secret + '&' + token_secret; |
| 379 bool is_signed = false; |
| 380 std::string signature; |
| 381 switch (signature_method) { |
| 382 case HMAC_SHA1_SIGNATURE: |
| 383 is_signed = SignHmacSha1(base, key, &signature); |
| 384 break; |
| 385 case RSA_SHA1_SIGNATURE: |
| 386 is_signed = SignRsaSha1(base, key, &signature); |
| 387 break; |
| 388 case PLAINTEXT_SIGNATURE: |
| 389 is_signed = SignPlaintext(base, key, &signature); |
| 390 break; |
| 391 default: |
| 392 NOTREACHED(); |
| 393 } |
| 406 if (is_signed) { | 394 if (is_signed) { |
| 407 std::string signed_text; | 395 std::string signed_text; |
| 408 switch (http_method) { | 396 switch (http_method) { |
| 409 case GET_METHOD: | 397 case GET_METHOD: |
| 410 signed_text = request_base_url.spec() + '?'; | 398 signed_text = request_base_url.spec() + '?'; |
| 411 // Intentionally falling through | 399 // Intentionally falling through |
| 412 case POST_METHOD: | 400 case POST_METHOD: |
| 413 signed_text += BuildBaseStringParameters(parameters); | 401 signed_text += base_parameters + '&' + kOAuthSignatureLabel + '=' + |
| 402 Encode(signature); |
| 414 break; | 403 break; |
| 415 default: | 404 default: |
| 416 NOTREACHED(); | 405 NOTREACHED(); |
| 417 } | 406 } |
| 418 *signed_text_return = signed_text; | 407 *signed_text_return = signed_text; |
| 419 } | 408 } |
| 420 return is_signed; | 409 return is_signed; |
| 421 } | 410 } |
| 422 | |
| 423 // static | |
| 424 bool OAuthRequestSigner::SignAuthHeader( | |
| 425 const GURL& request_base_url, | |
| 426 const Parameters& request_parameters, | |
| 427 SignatureMethod signature_method, | |
| 428 HttpMethod http_method, | |
| 429 const std::string& consumer_key, | |
| 430 const std::string& consumer_secret, | |
| 431 const std::string& token_key, | |
| 432 const std::string& token_secret, | |
| 433 std::string* signed_text_return) { | |
| 434 DCHECK(request_base_url.is_valid()); | |
| 435 Parameters parameters(request_parameters); | |
| 436 bool is_signed = SignParameters(request_base_url, signature_method, | |
| 437 http_method, consumer_key, consumer_secret, | |
| 438 token_key, token_secret, ¶meters); | |
| 439 if (is_signed) { | |
| 440 std::string signed_text = "OAuth "; | |
| 441 bool first = true; | |
| 442 for (Parameters::const_iterator param = parameters.begin(); | |
| 443 param != parameters.end(); | |
| 444 ++param) { | |
| 445 if (first) | |
| 446 first = false; | |
| 447 else | |
| 448 signed_text += ", "; | |
| 449 signed_text += | |
| 450 StringPrintf("%s=\"%s\"", | |
| 451 OAuthRequestSigner::Encode(param->first).c_str(), | |
| 452 OAuthRequestSigner::Encode(param->second).c_str()); | |
| 453 } | |
| 454 *signed_text_return = signed_text; | |
| 455 } | |
| 456 return is_signed; | |
| 457 } | |
| OLD | NEW |