diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2014-02-07 16:07:55 -0600 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2014-02-07 16:07:55 -0600 |
commit | 41ace0a57d8e45b8034237a617ccc9fcaf45f4d4 (patch) | |
tree | c7d1f625ad79724b77ff55a80dabd37376403325 /cryptography/hazmat/primitives/asymmetric/rsa.py | |
parent | de0019fe6943215746d385f65f6fa4e7e2725dd1 (diff) | |
parent | bc29f5b7741f1593234c6cae9df58e2ed8345f92 (diff) | |
download | cryptography-41ace0a57d8e45b8034237a617ccc9fcaf45f4d4.tar.gz cryptography-41ace0a57d8e45b8034237a617ccc9fcaf45f4d4.tar.bz2 cryptography-41ace0a57d8e45b8034237a617ccc9fcaf45f4d4.zip |
Merge pull request #559 from public/rsa-keys
RSA keys
Diffstat (limited to 'cryptography/hazmat/primitives/asymmetric/rsa.py')
-rw-r--r-- | cryptography/hazmat/primitives/asymmetric/rsa.py | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/cryptography/hazmat/primitives/asymmetric/rsa.py b/cryptography/hazmat/primitives/asymmetric/rsa.py new file mode 100644 index 00000000..1b33eaab --- /dev/null +++ b/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -0,0 +1,149 @@ +# 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 __future__ import absolute_import, division, print_function + +import sys + +import six + +from cryptography import utils +from cryptography.hazmat.primitives import interfaces + + +def _bit_length(x): + if sys.version_info >= (2, 7): + return x.bit_length() + else: + return len(bin(x)) - (2 + (x <= 0)) + + +@utils.register_interface(interfaces.RSAPublicKey) +class RSAPublicKey(object): + def __init__(self, public_exponent, modulus): + if ( + not isinstance(public_exponent, six.integer_types) or + not isinstance(modulus, six.integer_types) + ): + raise TypeError("RSAPublicKey arguments must be integers") + + if modulus < 3: + raise ValueError("modulus must be >= 3") + + if public_exponent < 3 or public_exponent >= modulus: + raise ValueError("public_exponent must be >= 3 and < modulus") + + if public_exponent & 1 == 0: + raise ValueError("public_exponent must be odd") + + self._public_exponent = public_exponent + self._modulus = modulus + + @property + def key_size(self): + return _bit_length(self.modulus) + + @property + def public_exponent(self): + return self._public_exponent + + @property + def modulus(self): + return self._modulus + + @property + def e(self): + return self.public_exponent + + @property + def n(self): + return self.modulus + + +@utils.register_interface(interfaces.RSAPrivateKey) +class RSAPrivateKey(object): + def __init__(self, p, q, private_exponent, public_exponent, modulus): + if ( + not isinstance(p, six.integer_types) or + not isinstance(q, six.integer_types) or + not isinstance(private_exponent, six.integer_types) or + not isinstance(public_exponent, six.integer_types) or + not isinstance(modulus, six.integer_types) + ): + raise TypeError("RSAPrivateKey arguments must be integers") + + if modulus < 3: + raise ValueError("modulus must be >= 3") + + if p >= modulus: + raise ValueError("p must be < modulus") + + if q >= modulus: + raise ValueError("q must be < modulus") + + if private_exponent >= modulus: + raise ValueError("private_exponent must be < modulus") + + if public_exponent < 3 or public_exponent >= modulus: + raise ValueError("public_exponent must be >= 3 and < modulus") + + if public_exponent & 1 == 0: + raise ValueError("public_exponent must be odd") + + if p * q != modulus: + raise ValueError("p*q must equal modulus") + + self._p = p + self._q = q + self._private_exponent = private_exponent + self._public_exponent = public_exponent + self._modulus = modulus + + @property + def key_size(self): + return _bit_length(self.modulus) + + def public_key(self): + return RSAPublicKey(self.public_exponent, self.modulus) + + @property + def p(self): + return self._p + + @property + def q(self): + return self._q + + @property + def private_exponent(self): + return self._private_exponent + + @property + def public_exponent(self): + return self._public_exponent + + @property + def modulus(self): + return self._modulus + + @property + def d(self): + return self.private_exponent + + @property + def e(self): + return self.public_exponent + + @property + def n(self): + return self.modulus |