コード例 #1
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get("kty") == "RSA":
            raise JWKError(
                "Incorrect key type. Expected: 'RSA', Received: %s" %
                jwk_dict.get("kty"))

        e = base64_to_long(jwk_dict.get("e"))
        n = base64_to_long(jwk_dict.get("n"))

        if "d" not in jwk_dict:
            return pyrsa.PublicKey(e=e, n=n)
        else:
            d = base64_to_long(jwk_dict.get("d"))
            extra_params = ["p", "q", "dp", "dq", "qi"]

            if any(k in jwk_dict for k in extra_params):
                # Precomputed private key parameters are available.
                if not all(k in jwk_dict for k in extra_params):
                    # These values must be present when 'p' is according to
                    # Section 6.3.2 of RFC7518, so if they are not we raise
                    # an error.
                    raise JWKError(
                        "Precomputed private key parameters are incomplete.")

                p = base64_to_long(jwk_dict["p"])
                q = base64_to_long(jwk_dict["q"])
                return pyrsa.PrivateKey(e=e, n=n, d=d, p=p, q=q)
            else:
                p, q = _rsa_recover_prime_factors(n, e, d)
                return pyrsa.PrivateKey(n=n, e=e, d=d, p=p, q=q)
コード例 #2
0
    def __init__(self, key, algorithm):

        if algorithm not in self.valid_hash_algs:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)
        self.hash_alg = get_algorithm_object(algorithm)

        if isinstance(key, _RSAKey):
            self.prepared_key = key
            return

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if isinstance(key, six.string_types):
            if isinstance(key, six.text_type):
                key = key.encode('utf-8')

            try:
                self.prepared_key = RSA.importKey(key)
            except Exception as e:
                raise JWKError(e)

            return

        raise JWKError('Unable to parse an RSA_JWK from key: %s' % key)
コード例 #3
0
    def __init__(self, key, algorithm):

        if algorithm not in ALGORITHMS.RSA:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)
        self.hash_alg = get_algorithm_object(algorithm)

        if isinstance(key, _RSAKey):
            self.prepared_key = key
            return

        if isinstance(key, dict):
            self._process_jwk(key)
            return

        if isinstance(key, six.string_types):
            if isinstance(key, six.text_type):
                key = key.encode('utf-8')

            if key.startswith(b'-----BEGIN CERTIFICATE-----'):
                try:
                    self._process_cert(key)
                except Exception as e:
                    raise JWKError(e)
                return

            try:
                self.prepared_key = RSA.importKey(key)
            except Exception as e:
                raise JWKError(e)
            return

        raise JWKError('Unable to parse an RSA_JWK from key: %s' % key)
コード例 #4
0
    def __init__(self, key, algorithm):
        if algorithm not in ALGORITHMS.EC:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)
        self.hash_alg = get_algorithm_object(algorithm)

        self.curve = self.CURVE_MAP.get(self.hash_alg)

        if isinstance(key, (ecdsa.SigningKey, ecdsa.VerifyingKey)):
            self.prepared_key = key
            return

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if isinstance(key, six.string_types):
            if isinstance(key, six.text_type):
                key = key.encode('utf-8')

            # Attempt to load key. We don't know if it's
            # a Signing Key or a Verifying Key, so we try
            # the Verifying Key first.
            try:
                key = ecdsa.VerifyingKey.from_pem(key)
            except ecdsa.der.UnexpectedDER:
                key = ecdsa.SigningKey.from_pem(key)
            except Exception as e:
                raise JWKError(e)

            self.prepared_key = key
            return

        raise JWKError('Unable to parse an ECKey from key: %s' % key)
コード例 #5
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'EC':
            raise JWKError(
                "Incorrect key type.  Expected: 'EC', Received: %s" %
                jwk_dict.get('kty'))

        if not all(k in jwk_dict for k in ['x', 'y', 'crv']):
            raise JWKError('Mandatory parameters are missing')

        x = base64_to_long(jwk_dict.get('x'))
        y = base64_to_long(jwk_dict.get('y'))
        curve = {
            'P-256': ec.SECP256R1,
            'P-384': ec.SECP384R1,
            'P-521': ec.SECP521R1,
        }[jwk_dict['crv']]

        public = ec.EllipticCurvePublicNumbers(x, y, curve())

        if 'd' in jwk_dict:
            d = base64_to_long(jwk_dict.get('d'))
            private = ec.EllipticCurvePrivateNumbers(d, public)

            return private.private_key(self.cryptography_backend())
        else:
            return public.public_key(self.cryptography_backend())
コード例 #6
0
    def __init__(self, key, algorithm):
        if algorithm not in self.valid_hash_algs:
            raise JWKError('hash_alg: %s is not a valid hash '
                           'algorithm', algorithm)
        self.curve = self.curve_map.get(algorithm)
        sha_map = {
            'ES256': 'sha256',
            'ES384': 'sha384',
            'ES512': 'sha512',
        }

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key, sha_map[algorithm])
            return

        if isinstance(key, six.string_types):
            if isinstance(key, six.text_type):
                key = key.encode('utf-8')

            # be a bit smart about what you're doing.
            # keys must be in raw form, not ASN1, so convert if needed.

            # The private key provided for testing is a base64 ASN1 that has a
            # PEM wrapper. This may take a bit of guesswork...
            der = self.pem_to_der(key)
            # The key dictates the curve, this emulates the ecdsa lib
            (self.curve, raw_key, raw_pub) = self.asn_to_raw(der, self.curve)
            self.prepared_key = pyelliptic.ECC(curve=self.curve,
                                               privkey=raw_key,
                                               pubkey=raw_pub,
                                               hasher=sha_map[algorithm])
            return
        raise JWKError('Unable to parse an ECKey from key: %s' % key)
コード例 #7
0
    def __init__(self, key, algorithm):
        if algorithm not in ALGORITHMS.HMAC:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)
        self._algorithm = algorithm
        self.hash_alg = get_algorithm_object(algorithm)

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if not isinstance(key, six.string_types) and not isinstance(
                key, bytes):
            raise JWKError('Expecting a string- or bytes-formatted key.')

        if isinstance(key, six.text_type):
            key = key.encode('utf-8')

        invalid_strings = [
            b'-----BEGIN PUBLIC KEY-----', b'-----BEGIN RSA PUBLIC KEY-----',
            b'-----BEGIN CERTIFICATE-----', b'ssh-rsa'
        ]

        if any(string_value in key for string_value in invalid_strings):
            raise JWKError(
                'The specified key is an asymmetric key or x509 certificate and'
                ' should not be used as an HMAC secret.')

        self.prepared_key = key
コード例 #8
0
    def __init__(self, key, algorithm):
        if algorithm not in ALGORITHMS.HMAC:
            raise JWKError("hash_alg: %s is not a valid hash algorithm" %
                           algorithm)
        self._algorithm = algorithm
        self._hash_alg = self.HASHES.get(algorithm)

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if not isinstance(key, str) and not isinstance(key, bytes):
            raise JWKError("Expecting a string- or bytes-formatted key.")

        if isinstance(key, str):
            key = key.encode("utf-8")

        invalid_strings = [
            b"-----BEGIN PUBLIC KEY-----",
            b"-----BEGIN RSA PUBLIC KEY-----",
            b"-----BEGIN CERTIFICATE-----",
            b"ssh-rsa",
        ]

        if any(string_value in key for string_value in invalid_strings):
            raise JWKError(
                "The specified key is an asymmetric key or x509 certificate and"
                " should not be used as an HMAC secret.")

        self.prepared_key = key
コード例 #9
0
ファイル: rsa_backend.py プロジェクト: bthaqi/python-jose
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError("Incorrect key type. Expected: 'RSA', Received: %s" % jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e'))
        n = base64_to_long(jwk_dict.get('n'))

        if 'd' not in jwk_dict:
            return pyrsa.PublicKey(e=e, n=n)
        else:
            d = base64_to_long(jwk_dict.get('d'))
            extra_params = ['p', 'q', 'dp', 'dq', 'qi']

            if any(k in jwk_dict for k in extra_params):
                # Precomputed private key parameters are available.
                if not all(k in jwk_dict for k in extra_params):
                    # These values must be present when 'p' is according to
                    # Section 6.3.2 of RFC7518, so if they are not we raise
                    # an error.
                    raise JWKError('Precomputed private key parameters are incomplete.')

                p = base64_to_long(jwk_dict['p'])
                q = base64_to_long(jwk_dict['q'])
                return pyrsa.PrivateKey(e=e, n=n, d=d, p=p, q=q)
            else:
                p, q = _rsa_recover_prime_factors(n, e, d)
                return pyrsa.PrivateKey(n=n, e=e, d=d, p=p, q=q)
コード例 #10
0
    def __init__(self, key, algorithm):
        if algorithm not in ALGORITHMS.RSA:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)

        if algorithm in ALGORITHMS.RSA_KW and algorithm != ALGORITHMS.RSA1_5:
            raise JWKError('alg: %s is not supported by the RSA backend' %
                           algorithm)

        self.hash_alg = {
            ALGORITHMS.RS256: self.SHA256,
            ALGORITHMS.RS384: self.SHA384,
            ALGORITHMS.RS512: self.SHA512
        }.get(algorithm)
        self._algorithm = algorithm

        if isinstance(key, dict):
            self._prepared_key = self._process_jwk(key)
            return

        if isinstance(key, (pyrsa.PublicKey, pyrsa.PrivateKey)):
            self._prepared_key = key
            return

        if isinstance(key, str):
            key = key.encode('utf-8')

        if isinstance(key, bytes):
            try:
                self._prepared_key = pyrsa.PublicKey.load_pkcs1(key)
            except ValueError:
                try:
                    self._prepared_key = pyrsa.PublicKey.load_pkcs1_openssl_pem(
                        key)
                except ValueError:
                    try:
                        self._prepared_key = pyrsa.PrivateKey.load_pkcs1(key)
                    except ValueError:
                        try:
                            der = pyrsa_pem.load_pem(key, b'PRIVATE KEY')
                            try:
                                pkcs1_key = rsa_private_key_pkcs8_to_pkcs1(der)
                            except PyAsn1Error:
                                # If the key was encoded using the old, invalid,
                                # encoding then pyasn1 will throw an error attempting
                                # to parse the key.
                                pkcs1_key = _legacy_private_key_pkcs8_to_pkcs1(
                                    der)
                            self._prepared_key = pyrsa.PrivateKey.load_pkcs1(
                                pkcs1_key, format="DER")
                        except ValueError as e:
                            raise JWKError(e)
            return
        raise JWKError('Unable to parse an RSA_JWK from key: %s' % key)
コード例 #11
0
    def __init__(self, key, algorithm, cryptography_backend=default_backend):
        if algorithm not in ALGORITHMS.EC:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)

        self.hash_alg = {
            ALGORITHMS.ES256: self.SHA256,
            ALGORITHMS.ES384: self.SHA384,
            ALGORITHMS.ES512: self.SHA512,
            ALGORITHMS.ES256K: self.SHA256
        }.get(algorithm)
        self._algorithm = algorithm

        self.cryptography_backend = cryptography_backend

        if hasattr(key, 'public_bytes') or hasattr(key, 'private_bytes'):
            self.prepared_key = key
            return

        if None not in (EcdsaSigningKey, EcdsaVerifyingKey) and isinstance(
                key, (EcdsaSigningKey, EcdsaVerifyingKey)):
            # convert to PEM and let cryptography below load it as PEM
            key = key.to_pem().decode('utf-8')

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if isinstance(key, six.string_types):
            key = key.encode('utf-8')

        if isinstance(key, six.binary_type):
            # Attempt to load key. We don't know if it's
            # a Public Key or a Private Key, so we try
            # the Public Key first.
            try:
                try:
                    key = load_pem_public_key(key, self.cryptography_backend())
                except ValueError:
                    key = load_pem_private_key(
                        key,
                        password=None,
                        backend=self.cryptography_backend())
            except Exception as e:
                raise JWKError(e)

            self.prepared_key = key
            return

        raise JWKError('Unable to parse an ECKey from key: %s' % key)
コード例 #12
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'EC':
            raise JWKError("Incorrect key type.  Expected: 'EC', Recieved: %s" % jwk_dict.get('kty'))

        x = base64_to_long(jwk_dict.get('x'))
        y = base64_to_long(jwk_dict.get('y'))

        if not ecdsa.ecdsa.point_is_valid(self.curve.generator, x, y):
            raise JWKError("Point: %s, %s is not a valid point" % (x, y))

        point = ecdsa.ellipticcurve.Point(self.curve.curve, x, y, self.curve.order)
        verifying_key = ecdsa.keys.VerifyingKey.from_public_point(point, self.curve)

        return verifying_key
コード例 #13
0
def construct(key_data, algorithm=None):
    """
    Construct a Key object for the given algorithm with the given
    key_data.
    """

    # Allow for pulling the algorithm off of the passed in jwk.
    if not algorithm and isinstance(key_data, dict):
        algorithm = key_data.get('alg', None)

    if not algorithm:
        raise JWKError('Unable to find a algorithm for key: %s' % key_data)

    if algorithm in ALGORITHMS.HMAC:
        return HMACKey(key_data, algorithm)

    if algorithm in ALGORITHMS.RSA:
        return RSAKey(key_data, algorithm)

    if algorithm in ALGORITHMS.EC:
        # TODO: Add switch between libraries.
        # ECKey uses a more forgiving, python based ecdsa library.
        # It may be preferred in a low to medium demand environment,
        # return ECKey(key_data, algorithm)

        # ECKey2 uses a far stricter, openssl wrapper library.
        # It may be preferred in a high demand environment.
        return ECKey(key_data, algorithm)
コード例 #14
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'oct':
            raise JWKError(
                "Incorrect key type.  Expected: 'oct', Received: %s" %
                jwk_dict.get('kty'))

            raise JWKError(
                "Incorrect key type. Expected: 'oct', Received: %s" %
                jwk_dict.get('kty'))

        k = jwk_dict.get('k')
        k = k.encode('utf-8')
        k = bytes(k)
        k = base64url_decode(k)

        return k
コード例 #15
0
 def sign(self, msg):
     try:
         signature = self.prepared_key.sign(msg, padding.PKCS1v15(),
                                            self.hash_alg())
     except Exception as e:
         raise JWKError(e)
     return signature
コード例 #16
0
    def __init__(self, key, algorithm):
        if algorithm not in ALGORITHMS.RSA:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)

        self.hash_alg = {
            ALGORITHMS.RS256: self.SHA256,
            ALGORITHMS.RS384: self.SHA384,
            ALGORITHMS.RS512: self.SHA512
        }.get(algorithm)
        self._algorithm = algorithm

        if isinstance(key, dict):
            self._prepared_key = self._process_jwk(key)
            return

        if isinstance(key, (pyrsa.PublicKey, pyrsa.PrivateKey)):
            self._prepared_key = key
            return

        if isinstance(key, six.string_types):
            key = key.encode('utf-8')

        if isinstance(key, six.binary_type):
            try:
                self._prepared_key = pyrsa.PublicKey.load_pkcs1(key)
            except ValueError:
                try:
                    self._prepared_key = pyrsa.PublicKey.load_pkcs1_openssl_pem(
                        key)
                except ValueError:
                    try:
                        self._prepared_key = pyrsa.PrivateKey.load_pkcs1(key)
                    except ValueError:
                        try:
                            # python-rsa does not support PKCS8 yet so we have to manually remove OID
                            der = pyrsa_pem.load_pem(key, b'PRIVATE KEY')
                            header, der = der[:22], der[22:]
                            if header != PKCS8_RSA_HEADER:
                                raise ValueError("Invalid PKCS8 header")
                            self._prepared_key = pyrsa.PrivateKey._load_pkcs1_der(
                                der)
                        except ValueError as e:
                            raise JWKError(e)
            return
        raise JWKError('Unable to parse an RSA_JWK from key: %s' % key)
コード例 #17
0
def construct(key_data, algorithm=None):
    """
    Construct a Key object for the given algorithm with the given
    key_data.
    """

    # Allow for pulling the algorithm off of the passed in jwk.
    if not algorithm and isinstance(key_data, dict):
        algorithm = key_data.get('alg', None)

    if not algorithm:
        raise JWKError('Unable to find a algorithm for key: %s' % key_data)

    key_class = get_key(algorithm)
    if not key_class:
        raise JWKError('Unable to find a algorithm for key: %s' % key_data)
    return key_class(key_data, algorithm)
コード例 #18
0
    def __init__(self, key, algorithm, cryptography_backend=default_backend):
        if algorithm not in ALGORITHMS.RSA:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)

        self.hash_alg = {
            ALGORITHMS.RS256: self.SHA256,
            ALGORITHMS.RS384: self.SHA384,
            ALGORITHMS.RS512: self.SHA512
        }.get(algorithm)
        self._algorithm = algorithm

        self.cryptography_backend = cryptography_backend

        # if it conforms to RSAPublicKey interface
        if hasattr(key, 'public_bytes') and hasattr(key, 'public_numbers'):
            self.prepared_key = key
            return

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if isinstance(key, six.string_types):
            key = key.encode('utf-8')

        if isinstance(key, six.binary_type):
            try:
                if key.startswith(b'-----BEGIN CERTIFICATE-----'):
                    self._process_cert(key)
                    return

                try:
                    self.prepared_key = load_pem_public_key(
                        key, self.cryptography_backend())
                except ValueError:
                    self.prepared_key = load_pem_private_key(
                        key,
                        password=None,
                        backend=self.cryptography_backend())
            except Exception as e:
                raise JWKError(e)
            return

        raise JWKError('Unable to parse an RSA_JWK from key: %s' % key)
コード例 #19
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError("Incorrect key type.  Expected: 'RSA', Recieved: %s" % jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e', 256))
        n = base64_to_long(jwk_dict.get('n'))

        self.prepared_key = RSA.construct((n, e))
        return self.prepared_key
コード例 #20
0
ファイル: cryptography_backend.py プロジェクト: ykydep/hass
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError("Incorrect key type.  Expected: 'RSA', Recieved: %s" % jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e', 256))
        n = base64_to_long(jwk_dict.get('n'))

        verifying_key = rsa.RSAPublicNumbers(e, n).public_key(self.cryptography_backend())
        return verifying_key
コード例 #21
0
 def sign(self, msg):
     try:
         signer = self.prepared_key.signer(padding.PKCS1v15(),
                                           self.hash_alg())
         signer.update(msg)
         signature = signer.finalize()
     except Exception as e:
         raise JWKError(e)
     return signature
コード例 #22
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError(
                "Incorrect key type.  Expected: 'RSA', Received: %s" %
                jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e', 256))
        n = base64_to_long(jwk_dict.get('n'))
        public = rsa.RSAPublicNumbers(e, n)

        if 'd' not in jwk_dict:
            return public.public_key(self.cryptography_backend())
        else:
            # This is a private key.
            d = base64_to_long(jwk_dict.get('d'))

            extra_params = ['p', 'q', 'dp', 'dq', 'qi']

            if any(k in jwk_dict for k in extra_params):
                # Precomputed private key parameters are available.
                if not all(k in jwk_dict for k in extra_params):
                    # These values must be present when 'p' is according to
                    # Section 6.3.2 of RFC7518, so if they are not we raise
                    # an error.
                    raise JWKError(
                        'Precomputed private key parameters are incomplete.')

                p = base64_to_long(jwk_dict['p'])
                q = base64_to_long(jwk_dict['q'])
                dp = base64_to_long(jwk_dict['dp'])
                dq = base64_to_long(jwk_dict['dq'])
                qi = base64_to_long(jwk_dict['qi'])
            else:
                # The precomputed private key parameters are not available,
                # so we use cryptography's API to fill them in.
                p, q = rsa.rsa_recover_prime_factors(n, e, d)
                dp = rsa.rsa_crt_dmp1(d, p)
                dq = rsa.rsa_crt_dmq1(d, q)
                qi = rsa.rsa_crt_iqmp(p, q)

            private = rsa.RSAPrivateNumbers(p, q, d, dp, dq, qi, public)

            return private.private_key(self.cryptography_backend())
コード例 #23
0
ファイル: jwk.py プロジェクト: takeshixx/python-jose
    def __init__(self, key, algorithm):
        if algorithm not in ALGORITHMS.HMAC:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)
        self._algorithm = algorithm
        self.hash_alg = get_algorithm_object(algorithm)

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if not isinstance(key, six.string_types) and not isinstance(
                key, bytes):
            raise JWKError('Expecting a string- or bytes-formatted key.')

        if isinstance(key, six.text_type):
            key = key.encode('utf-8')

        self.prepared_key = key
コード例 #24
0
ファイル: ecdsa_backend.py プロジェクト: blkpark/python-jose
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'EC':
            raise JWKError("Incorrect key type. Expected: 'EC', Received: %s" % jwk_dict.get('kty'))

        if not all(k in jwk_dict for k in ['x', 'y', 'crv']):
            raise JWKError('Mandatory parameters are missing')

        if 'd' in jwk_dict:
            # We are dealing with a private key; the secret exponent is enough
            # to create an ecdsa key.
            d = base64_to_long(jwk_dict.get('d'))
            return ecdsa.keys.SigningKey.from_secret_exponent(d, self.curve)
        else:
            x = base64_to_long(jwk_dict.get('x'))
            y = base64_to_long(jwk_dict.get('y'))

            if not ecdsa.ecdsa.point_is_valid(self.curve.generator, x, y):
                raise JWKError(f"Point: {x}, {y} is not a valid point")

            point = ecdsa.ellipticcurve.Point(self.curve.curve, x, y, self.curve.order)
            return ecdsa.keys.VerifyingKey.from_public_point(point, self.curve)
コード例 #25
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get("kty") == "oct":
            raise JWKError(
                "Incorrect key type. Expected: 'oct', Received: %s" %
                jwk_dict.get("kty"))

        k = jwk_dict.get("k")
        k = k.encode("utf-8")
        k = bytes(k)
        k = base64url_decode(k)

        return k
コード例 #26
0
    def __init__(self, key, algorithm):
        if algorithm not in ALGORITHMS.EC:
            raise JWKError("hash_alg: %s is not a valid hash algorithm" %
                           algorithm)

        self.hash_alg = {
            ALGORITHMS.ES256: self.SHA256,
            ALGORITHMS.ES384: self.SHA384,
            ALGORITHMS.ES512: self.SHA512,
        }.get(algorithm)
        self._algorithm = algorithm

        self.curve = self.CURVE_MAP.get(self.hash_alg)

        if isinstance(key, (ecdsa.SigningKey, ecdsa.VerifyingKey)):
            self.prepared_key = key
            return

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if isinstance(key, str):
            key = key.encode("utf-8")

        if isinstance(key, bytes):
            # Attempt to load key. We don't know if it's
            # a Signing Key or a Verifying Key, so we try
            # the Verifying Key first.
            try:
                key = ecdsa.VerifyingKey.from_pem(key)
            except ecdsa.der.UnexpectedDER:
                key = ecdsa.SigningKey.from_pem(key)
            except Exception as e:
                raise JWKError(e)

            self.prepared_key = key
            return

        raise JWKError("Unable to parse an ECKey from key: %s" % key)
コード例 #27
0
 def verify(self, msg, sig):
     # Convert byte array strings back into their longs
     if len(sig) % 2:
         raise JWKError("Invalid signature value used.")
     split = len(sig) / 2
     r = Integer(base64_to_long(base64.urlsafe_b64encode(sig[:split])))
     s = Integer(base64_to_long(base64.urlsafe_b64encode(sig[split:])))
     ss = Sequence(tagSet=[tag.Tag(0, 32, 16)])
     ss.setComponentByPosition(0, r)
     ss.setComponentByPosition(1, s)
     sig_asn = encoder.encode(ss)
     ver = self.prepared_key.verify(sig_asn, msg)
     return ver
コード例 #28
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError(
                "Incorrect key type.  Expected: 'RSA', Recieved: %s" %
                jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e', 256))
        n = base64_to_long(jwk_dict.get('n'))
        params = (n, e)

        if 'd' in jwk_dict:
            params += (base64_to_long(jwk_dict.get('d')), )

            extra_params = ['p', 'q', 'dp', 'dq', 'qi']

            if any(k in jwk_dict for k in extra_params):
                # Precomputed private key parameters are available.
                if not all(k in jwk_dict for k in extra_params):
                    # These values must be present when 'p' is according to
                    # Section 6.3.2 of RFC7518, so if they are not we raise
                    # an error.
                    raise JWKError(
                        'Precomputed private key parameters are incomplete.')

                p = base64_to_long(jwk_dict.get('p'))
                q = base64_to_long(jwk_dict.get('q'))
                qi = base64_to_long(jwk_dict.get('qi'))

                # PyCrypto does not take the dp and dq as arguments, so we do
                # not pass them. Furthermore, the parameter qi specified in
                # the JWK is the inverse of q modulo p, whereas PyCrypto
                # takes the inverse of p modulo q. We therefore switch the
                # parameters to make the third parameter the inverse of the
                # second parameter modulo the first parameter.
                params += (q, p, qi)

        self.prepared_key = RSA.construct(params)

        return self.prepared_key
コード例 #29
0
    def asn_to_raw(self, candidate, curve):
        """Extract the ASN1 information and return the curve and key pairs."""
        decoded = base64.urlsafe_b64decode(self.repad(candidate))

        # if it's already raw... (Most likely a public key)
        if len(decoded) == 64:
            return curve, None, "\04" + decoded
        if decoded[0] == "\04":
            return curve, None, decoded

        try:
            asn_set = decoder.decode(decoded)[0]
        except:
            raise JWKError("Invalid EC Key")
        pri_key = self.bitstring_to_str(asn_set[1])
        pub_key = None
        # A private key starts with a Integer(1)
        if (isinstance(asn_set[0], univ.Integer) and asn_set[0] == 1):
            # Followed by the OID
            curve = self.curve_oids.get(asn_set[2])
            if curve:
                # And finally the public key
                pub_key = self.bitstring_to_str(asn_set[3])
        # A public key starts with a sequence
        if isinstance(asn_set[0], univ.Sequence):
            # confirm that the public key curve matches up
            # with the OID pair type (Also includes the public key OID,
            # which we ignore)
            pcurve = self.curve_oids.get(asn_set[0][1])
            if pcurve:
                curve = pcurve
            # Shuffle the key to the right return.
            pub_key = pri_key
            pri_key = None
        if not curve:
            raise JWKError("Invalid EC curve type key specified.")
        return curve, pri_key, pub_key
コード例 #30
0
 def _process_jwk(self, jwk_dict, algorythm="sha256"):
     key_type = jwk_dict.get('kty')
     if key_type != 'EC':
         raise JWKError("Incorrect key type. "
                        "Expected 'EC' Received: %s" % key_type)
     privkey = None
     if 'd' in jwk_dict:
         privkey = base64.urlsafe_b64decode(self.repad(jwk_dict.get('d')))
     key = pyelliptic.ECC(
         curve=self.curve,
         raw_privkey=privkey,
         pubkey_x=base64.urlsafe_b64decode(self.repad(jwk_dict.get('x'))),
         pubkey_y=base64.urlsafe_b64decode(self.repad(jwk_dict.get('y'))),
         hasher=algorythm)
     return key