aboutsummaryrefslogtreecommitdiffstats
path: root/keystone-moon/keystone/common/base64utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'keystone-moon/keystone/common/base64utils.py')
-rw-r--r--keystone-moon/keystone/common/base64utils.py401
1 files changed, 0 insertions, 401 deletions
diff --git a/keystone-moon/keystone/common/base64utils.py b/keystone-moon/keystone/common/base64utils.py
deleted file mode 100644
index d19eade7..00000000
--- a/keystone-moon/keystone/common/base64utils.py
+++ /dev/null
@@ -1,401 +0,0 @@
-# Copyright 2013 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-
-Python provides the base64 module as a core module but this is mostly
-limited to encoding and decoding base64 and it's variants. It is often
-useful to be able to perform other operations on base64 text. This
-module is meant to be used in conjunction with the core base64 module.
-
-Standardized base64 is defined in
-RFC-4648 "The Base16, Base32, and Base64 Data Encodings".
-
-This module provides the following base64 utility functionality:
-
- * tests if text is valid base64
- * filter formatting from base64
- * convert base64 between different alphabets
- * Handle padding issues
- - test if base64 is padded
- - removes padding
- - restores padding
- * wraps base64 text into formatted blocks
- - via iterator
- - return formatted string
-
-"""
-
-import re
-import string
-
-import six
-from six.moves import urllib
-
-from keystone.i18n import _
-
-
-class InvalidBase64Error(ValueError):
- pass
-
-base64_alphabet_re = re.compile(r'^[^A-Za-z0-9+/=]+$')
-base64url_alphabet_re = re.compile(r'^[^A-Za-z0-9---_=]+$')
-
-base64_non_alphabet_re = re.compile(r'[^A-Za-z0-9+/=]+')
-base64url_non_alphabet_re = re.compile(r'[^A-Za-z0-9---_=]+')
-
-_strip_formatting_re = re.compile(r'\s+')
-
-if six.PY2:
- str_ = string
-else:
- str_ = str
-
-_base64_to_base64url_trans = str_.maketrans('+/', '-_')
-_base64url_to_base64_trans = str_.maketrans('-_', '+/')
-
-
-def _check_padding_length(pad):
- if len(pad) != 1:
- raise ValueError(_('pad must be single character'))
-
-
-def is_valid_base64(text):
- """Test if input text can be base64 decoded.
-
- :param text: input base64 text
- :type text: string
- :returns: bool -- True if text can be decoded as base64, False otherwise
- """
-
- text = filter_formatting(text)
-
- if base64_non_alphabet_re.search(text):
- return False
-
- try:
- return base64_is_padded(text)
- except InvalidBase64Error:
- return False
-
-
-def is_valid_base64url(text):
- """Test if input text can be base64url decoded.
-
- :param text: input base64 text
- :type text: string
- :returns: bool -- True if text can be decoded as base64url,
- False otherwise
- """
-
- text = filter_formatting(text)
-
- if base64url_non_alphabet_re.search(text):
- return False
-
- try:
- return base64_is_padded(text)
- except InvalidBase64Error:
- return False
-
-
-def filter_formatting(text):
- """Return base64 text without any formatting, just the base64.
-
- Base64 text is often formatted with whitespace, line endings,
- etc. This function strips out any formatting, the result will
- contain only base64 characters.
-
- Note, this function does not filter out all non-base64 alphabet
- characters, it only removes characters used for formatting.
-
- :param text: input text to filter
- :type text: string
- :returns: string -- filtered text without formatting
- """
- return _strip_formatting_re.sub('', text)
-
-
-def base64_to_base64url(text):
- """Convert base64 text to base64url text.
-
- base64url text is designed to be safe for use in file names and
- URL's. It is defined in RFC-4648 Section 5.
-
- base64url differs from base64 in the last two alphabet characters
- at index 62 and 63, these are sometimes referred as the
- altchars. The '+' character at index 62 is replaced by '-'
- (hyphen) and the '/' character at index 63 is replaced by '_'
- (underscore).
-
- This function only translates the altchars, non-alphabet
- characters are not filtered out.
-
- WARNING::
-
- base64url continues to use the '=' pad character which is NOT URL
- safe. RFC-4648 suggests two alternate methods to deal with this:
-
- percent-encode
- percent-encode the pad character (e.g. '=' becomes
- '%3D'). This makes the base64url text fully safe. But
- percent-encoding has the downside of requiring
- percent-decoding prior to feeding the base64url text into a
- base64url decoder since most base64url decoders do not
- recognize %3D as a pad character and most decoders require
- correct padding.
-
- no-padding
- padding is not strictly necessary to decode base64 or
- base64url text, the pad can be computed from the input text
- length. However many decoders demand padding and will consider
- non-padded text to be malformed. If one wants to omit the
- trailing pad character(s) for use in URL's it can be added back
- using the base64_assure_padding() function.
-
- This function makes no decisions about which padding methodology to
- use. One can either call base64_strip_padding() to remove any pad
- characters (restoring later with base64_assure_padding()) or call
- base64url_percent_encode() to percent-encode the pad characters.
-
- :param text: input base64 text
- :type text: string
- :returns: string -- base64url text
- """
- return text.translate(_base64_to_base64url_trans)
-
-
-def base64url_to_base64(text):
- """Convert base64url text to base64 text.
-
- See base64_to_base64url() for a description of base64url text and
- it's issues.
-
- This function does NOT handle percent-encoded pad characters, they
- will be left intact. If the input base64url text is
- percent-encoded you should call
-
- :param text: text in base64url alphabet
- :type text: string
- :returns: string -- text in base64 alphabet
-
- """
- return text.translate(_base64url_to_base64_trans)
-
-
-def base64_is_padded(text, pad='='):
- """Test if the text is base64 padded.
-
- The input text must be in a base64 alphabet. The pad must be a
- single character. If the text has been percent-encoded (e.g. pad
- is the string '%3D') you must convert the text back to a base64
- alphabet (e.g. if percent-encoded use the function
- base64url_percent_decode()).
-
- :param text: text containing ONLY characters in a base64 alphabet
- :type text: string
- :param pad: pad character (must be single character) (default: '=')
- :type pad: string
- :returns: bool -- True if padded, False otherwise
- :raises: ValueError, InvalidBase64Error
- """
-
- _check_padding_length(pad)
-
- text_len = len(text)
- if text_len > 0 and text_len % 4 == 0:
- pad_index = text.find(pad)
- if pad_index >= 0 and pad_index < text_len - 2:
- raise InvalidBase64Error(_('text is multiple of 4, '
- 'but pad "%s" occurs before '
- '2nd to last char') % pad)
- if pad_index == text_len - 2 and text[-1] != pad:
- raise InvalidBase64Error(_('text is multiple of 4, '
- 'but pad "%s" occurs before '
- 'non-pad last char') % pad)
- return True
-
- if text.find(pad) >= 0:
- raise InvalidBase64Error(_('text is not a multiple of 4, '
- 'but contains pad "%s"') % pad)
- return False
-
-
-def base64url_percent_encode(text):
- """Percent-encode base64url padding.
-
- The input text should only contain base64url alphabet
- characters. Any non-base64url alphabet characters will also be
- subject to percent-encoding.
-
- :param text: text containing ONLY characters in the base64url alphabet
- :type text: string
- :returns: string -- percent-encoded base64url text
- :raises: InvalidBase64Error
- """
-
- if len(text) % 4 != 0:
- raise InvalidBase64Error(_('padded base64url text must be '
- 'multiple of 4 characters'))
-
- return urllib.parse.quote(text)
-
-
-def base64url_percent_decode(text):
- """Percent-decode base64url padding.
-
- The input text should only contain base64url alphabet
- characters and the percent-encoded pad character. Any other
- percent-encoded characters will be subject to percent-decoding.
-
- :param text: base64url alphabet text
- :type text: string
- :returns: string -- percent-decoded base64url text
- """
-
- decoded_text = urllib.parse.unquote(text)
-
- if len(decoded_text) % 4 != 0:
- raise InvalidBase64Error(_('padded base64url text must be '
- 'multiple of 4 characters'))
-
- return decoded_text
-
-
-def base64_strip_padding(text, pad='='):
- """Remove padding from input base64 text.
-
- :param text: text containing ONLY characters in a base64 alphabet
- :type text: string
- :param pad: pad character (must be single character) (default: '=')
- :type pad: string
- :returns: string -- base64 text without padding
- :raises: ValueError
- """
- _check_padding_length(pad)
-
- # Can't be padded if text is less than 4 characters.
- if len(text) < 4:
- return text
-
- if text[-1] == pad:
- if text[-2] == pad:
- return text[0:-2]
- else:
- return text[0:-1]
- else:
- return text
-
-
-def base64_assure_padding(text, pad='='):
- """Assure the input text ends with padding.
-
- Base64 text is normally expected to be a multiple of 4
- characters. Each 4 character base64 sequence produces 3 octets of
- binary data. If the binary data is not a multiple of 3 the base64
- text is padded at the end with a pad character such that it is
- always a multiple of 4. Padding is ignored and does not alter the
- binary data nor it's length.
-
- In some circumstances it is desirable to omit the padding
- character due to transport encoding conflicts. Base64 text can
- still be correctly decoded if the length of the base64 text
- (consisting only of characters in the desired base64 alphabet) is
- known, padding is not absolutely necessary.
-
- Some base64 decoders demand correct padding or one may wish to
- format RFC compliant base64, this function performs this action.
-
- Input is assumed to consist only of members of a base64
- alphabet (i.e no whitespace). Iteration yields a sequence of lines.
- The line does NOT terminate with a line ending.
-
- Use the filter_formatting() function to assure the input text
- contains only the members of the alphabet.
-
- If the text ends with the pad it is assumed to already be
- padded. Otherwise the binary length is computed from the input
- text length and correct number of pad characters are appended.
-
- :param text: text containing ONLY characters in a base64 alphabet
- :type text: string
- :param pad: pad character (must be single character) (default: '=')
- :type pad: string
- :returns: string -- input base64 text with padding
- :raises: ValueError
- """
- _check_padding_length(pad)
-
- if text.endswith(pad):
- return text
-
- n = len(text) % 4
- if n == 0:
- return text
-
- n = 4 - n
- padding = pad * n
- return text + padding
-
-
-def base64_wrap_iter(text, width=64):
- """Fold text into lines of text with max line length.
-
- Input is assumed to consist only of members of a base64
- alphabet (i.e no whitespace). Iteration yields a sequence of lines.
- The line does NOT terminate with a line ending.
-
- Use the filter_formatting() function to assure the input text
- contains only the members of the alphabet.
-
- :param text: text containing ONLY characters in a base64 alphabet
- :type text: string
- :param width: number of characters in each wrapped line (default: 64)
- :type width: int
- :returns: generator -- sequence of lines of base64 text.
- """
-
- text = six.text_type(text)
- for x in six.moves.range(0, len(text), width):
- yield text[x:x + width]
-
-
-def base64_wrap(text, width=64):
- """Fold text into lines of text with max line length.
-
- Input is assumed to consist only of members of a base64
- alphabet (i.e no whitespace). Fold the text into lines whose
- line length is width chars long, terminate each line with line
- ending (default is '\\n'). Return the wrapped text as a single
- string.
-
- Use the filter_formatting() function to assure the input text
- contains only the members of the alphabet.
-
- :param text: text containing ONLY characters in a base64 alphabet
- :type text: string
- :param width: number of characters in each wrapped line (default: 64)
- :type width: int
- :returns: string -- wrapped text.
- """
-
- buf = six.StringIO()
-
- for line in base64_wrap_iter(text, width):
- buf.write(line)
- buf.write(u'\n')
-
- text = buf.getvalue()
- buf.close()
- return text