summaryrefslogtreecommitdiffstats
path: root/base/base64url.cc
diff options
context:
space:
mode:
authorpeter <peter@chromium.org>2015-10-29 04:35:15 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-29 11:36:09 +0000
commit2b9a5dc681a6a41e2acee6468ef5f42b42a58097 (patch)
tree438328622cc93fe1992225bbe9860b45828c5888 /base/base64url.cc
parent8daf2c6f84b1a4ad4458c9efb6ecac9e37a8c354 (diff)
downloadchromium_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.cc98
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