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/importutils
|
||||||
api/netutils
|
api/netutils
|
||||||
api/reflection
|
api/reflection
|
||||||
|
api/secretutils
|
||||||
api/strutils
|
api/strutils
|
||||||
api/timeutils
|
api/timeutils
|
||||||
api/units
|
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