diff options
author | peter <peter@chromium.org> | 2015-10-29 04:35:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-29 11:36:09 +0000 |
commit | 2b9a5dc681a6a41e2acee6468ef5f42b42a58097 (patch) | |
tree | 438328622cc93fe1992225bbe9860b45828c5888 /base/base64url.cc | |
parent | 8daf2c6f84b1a4ad4458c9efb6ecac9e37a8c354 (diff) | |
download | chromium_src-2b9a5dc681a6a41e2acee6468ef5f42b42a58097.zip chromium_src-2b9a5dc681a6a41e2acee6468ef5f42b42a58097.tar.gz chromium_src-2b9a5dc681a6a41e2acee6468ef5f42b42a58097.tar.bz2 |
Generalize a base64url implementation in //base.
We currently have eight different base64url implementations living in
Chrome. This CL generalizes them to a single implementation in //base.
Uses will be updated after this CL lands on a per-feature basis with the
appropriate OWNERS.
BUG=536745
Review URL: https://codereview.chromium.org/1399363008
Cr-Commit-Position: refs/heads/master@{#356812}
Diffstat (limited to 'base/base64url.cc')
-rw-r--r-- | base/base64url.cc | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/base/base64url.cc b/base/base64url.cc new file mode 100644 index 0000000..106bba9 --- /dev/null +++ b/base/base64url.cc @@ -0,0 +1,98 @@ +// Copyright 2015 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 "base/base64url.h" + +#include "base/base64.h" +#include "base/numerics/safe_math.h" +#include "base/strings/string_util.h" +#include "third_party/modp_b64/modp_b64.h" + +namespace base { + +const char kPaddingChar = '='; + +// Base64url maps {+, /} to {-, _} in order for the encoded content to be safe +// to use in a URL. These characters will be translated by this implementation. +const char kBase64Chars[] = "+/"; +const char kBase64UrlSafeChars[] = "-_"; + +void Base64UrlEncode(const StringPiece& input, + Base64UrlEncodePolicy policy, + std::string* output) { + Base64Encode(input, output); + + ReplaceChars(*output, "+", "-", output); + ReplaceChars(*output, "/", "_", output); + + switch (policy) { + case Base64UrlEncodePolicy::INCLUDE_PADDING: + // The padding included in |*output| will not be amended. + break; + case Base64UrlEncodePolicy::OMIT_PADDING: + // The padding included in |*output| will be removed. + const size_t last_non_padding_pos = + output->find_last_not_of(kPaddingChar); + if (last_non_padding_pos != std::string::npos) + output->resize(last_non_padding_pos + 1); + + break; + } +} + +bool Base64UrlDecode(const StringPiece& input, + Base64UrlDecodePolicy policy, + std::string* output) { + // Characters outside of the base64url alphabet are disallowed, which includes + // the {+, /} characters found in the conventional base64 alphabet. + if (input.find_first_of(kBase64Chars) != std::string::npos) + return false; + + const size_t required_padding_characters = input.size() % 4; + const bool needs_replacement = + input.find_first_of(kBase64UrlSafeChars) != std::string::npos; + + switch (policy) { + case Base64UrlDecodePolicy::REQUIRE_PADDING: + // Fail if the required padding is not included in |input|. + if (required_padding_characters > 0) + return false; + break; + case Base64UrlDecodePolicy::IGNORE_PADDING: + // Missing padding will be silently appended. + break; + case Base64UrlDecodePolicy::DISALLOW_PADDING: + // Fail if padding characters are included in |input|. + if (input.find_first_of(kPaddingChar) != std::string::npos) + return false; + break; + } + + // If the string either needs replacement of URL-safe characters to normal + // base64 ones, or additional padding, a copy of |input| needs to be made in + // order to make these adjustments without side effects. + if (required_padding_characters > 0 || needs_replacement) { + std::string base64_input; + + CheckedNumeric<size_t> base64_input_size = input.size(); + if (required_padding_characters > 0) + base64_input_size += 4 - required_padding_characters; + + base64_input.reserve(base64_input_size.ValueOrDie()); + input.AppendToString(&base64_input); + + // Substitute the base64url URL-safe characters to their base64 equivalents. + ReplaceChars(base64_input, "-", "+", &base64_input); + ReplaceChars(base64_input, "_", "/", &base64_input); + + // Append the necessary padding characters. + base64_input.resize(base64_input_size.ValueOrDie(), '='); + + return Base64Decode(base64_input, output); + } + + return Base64Decode(input, output); +} + +} // namespace base |