Merge "Create secretutils and include 'constant_time_compare' function"
This commit is contained in:
commit
123e12201a
6
doc/source/api/secretutils.rst
Normal file
6
doc/source/api/secretutils.rst
Normal file
@ -0,0 +1,6 @@
|
||||
=============
|
||||
secretutils
|
||||
=============
|
||||
|
||||
.. automodule:: oslo_utils.secretutils
|
||||
:members:
|
@ -28,6 +28,7 @@ API Documentation
|
||||
api/importutils
|
||||
api/netutils
|
||||
api/reflection
|
||||
api/secretutils
|
||||
api/strutils
|
||||
api/timeutils
|
||||
api/units
|
||||
|
35
oslo_utils/secretutils.py
Normal file
35
oslo_utils/secretutils.py
Normal file
@ -0,0 +1,35 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import hmac
|
||||
|
||||
|
||||
try:
|
||||
constant_time_compare = hmac.compare_digest
|
||||
except AttributeError:
|
||||
def constant_time_compare(first, second):
|
||||
"""Returns True if both string inputs are equal, otherwise False.
|
||||
|
||||
This function should take a constant amount of time regardless of
|
||||
how many characters in the strings match. This function uses an
|
||||
approach designed to prevent timing analysis by avoiding
|
||||
content-based short circuiting behaviour, making it appropriate
|
||||
for cryptography.
|
||||
"""
|
||||
if len(first) != len(second):
|
||||
return False
|
||||
result = 0
|
||||
for x, y in zip(first, second):
|
||||
result |= ord(x) ^ ord(y)
|
||||
return result == 0
|
52
oslo_utils/tests/test_secretutils.py
Normal file
52
oslo_utils/tests/test_secretutils.py
Normal file
@ -0,0 +1,52 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslotest import base as test_base
|
||||
import testscenarios
|
||||
|
||||
from oslo_utils import secretutils
|
||||
|
||||
|
||||
class SecretUtilsTest(testscenarios.TestWithScenarios,
|
||||
test_base.BaseTestCase):
|
||||
|
||||
scenarios = [
|
||||
('binary', {'converter': lambda text: text.encode('utf-8')}),
|
||||
('unicode', {'converter': lambda text: text}),
|
||||
]
|
||||
|
||||
def test_constant_time_compare(self):
|
||||
# make sure it works as a compare, the "constant time" aspect
|
||||
# isn't appropriate to test in unittests
|
||||
ctc = secretutils.constant_time_compare
|
||||
self.assertTrue(ctc(self.converter(u'abcd'),
|
||||
self.converter(u'abcd')))
|
||||
self.assertTrue(ctc(self.converter(u''),
|
||||
self.converter(u'')))
|
||||
self.assertFalse(ctc(self.converter(u'abcd'),
|
||||
self.converter(u'efgh')))
|
||||
self.assertFalse(ctc(self.converter(u'abc'),
|
||||
self.converter(u'abcd')))
|
||||
self.assertFalse(ctc(self.converter(u'abc'),
|
||||
self.converter(u'abc\x00')))
|
||||
self.assertFalse(ctc(self.converter(u''),
|
||||
self.converter(u'abc')))
|
||||
self.assertTrue(ctc(self.converter(u'abcd1234'),
|
||||
self.converter(u'abcd1234')))
|
||||
self.assertFalse(ctc(self.converter(u'abcd1234'),
|
||||
self.converter(u'ABCD234')))
|
||||
self.assertFalse(ctc(self.converter(u'abcd1234'),
|
||||
self.converter(u'a')))
|
||||
self.assertFalse(ctc(self.converter(u'abcd1234'),
|
||||
self.converter(u'1234abcd')))
|
Loading…
Reference in New Issue
Block a user