Esempio n. 1
0
    def load(cls,
             data: bytes,
             password: Optional[bytes] = None,
             backend: Optional[Any] = None) -> 'JWK':
        """Load serialized key as JWK.

        :param str data: Public or private key serialized as PEM or DER.
        :param str password: Optional password.
        :param backend: A `.PEMSerializationBackend` and
            `.DERSerializationBackend` provider.

        :raises errors.Error: if unable to deserialize, or unsupported
            JWK algorithm

        :returns: JWK of an appropriate type.
        :rtype: `JWK`

        """
        try:
            key = cls._load_cryptography_key(data, password, backend)
        except errors.Error as error:
            logger.debug('Loading symmetric key, asymmetric failed: %s', error)
            return JWKOct(key=data)

        if cls.typ is not NotImplemented and not isinstance(
                key, cls.cryptography_key_types):
            raise errors.Error('Unable to deserialize {0} into {1}'.format(
                key.__class__, cls.__class__))
        for jwk_cls in cls.TYPES.values():
            if isinstance(key, jwk_cls.cryptography_key_types):
                return jwk_cls(key=key)
        raise errors.Error('Unsupported algorithm: {0}'.format(key.__class__))
Esempio n. 2
0
 def _sign(self, key: ec.EllipticCurvePrivateKey, msg: bytes) -> bytes:
     try:
         return key.sign(msg, ec.ECDSA(self.hash))
     except AttributeError as error:
         logger.debug(error, exc_info=True)
         raise errors.Error('Public key cannot be used for signing')
     except ValueError as error:  # digest too large
         logger.debug(error, exc_info=True)
         raise errors.Error(str(error))
Esempio n. 3
0
 def sign(self, key: rsa.RSAPrivateKey, msg: bytes) -> bytes:
     """Sign the ``msg`` using ``key``."""
     try:
         return key.sign(msg, self.padding, self.hash)
     except AttributeError as error:
         logger.debug(error, exc_info=True)
         raise errors.Error("Public key cannot be used for signing")
     except ValueError as error:  # digest too large
         logger.debug(error, exc_info=True)
         raise errors.Error(str(error))
Esempio n. 4
0
    def _load_cryptography_key(cls,
                               data: bytes,
                               password: Optional[bytes] = None,
                               backend: Optional[Any] = None) -> Any:
        backend = default_backend() if backend is None else backend
        exceptions = {}

        # private key?
        loader_private: Any
        for loader_private in (serialization.load_pem_private_key,
                               serialization.load_der_private_key):
            try:
                return loader_private(data, password, backend)
            except (ValueError, TypeError,
                    cryptography.exceptions.UnsupportedAlgorithm) as error:
                exceptions[str(loader_private)] = error

        # public key?
        loader_public: Any
        for loader_public in (serialization.load_pem_public_key,
                              serialization.load_der_public_key):
            try:
                return loader_public(data, backend)
            except (ValueError,
                    cryptography.exceptions.UnsupportedAlgorithm) as error:
                exceptions[str(loader_public)] = error

        # no luck
        raise errors.Error('Unable to deserialize key: {0}'.format(exceptions))
Esempio n. 5
0
 def sign(self, key, msg):
     """Sign the ``msg`` using ``key``."""
     try:
         signer = key.signer(self.padding, self.hash)
     except AttributeError as error:
         logger.debug(error, exc_info=True)
         raise errors.Error("Public key cannot be used for signing")
     except ValueError as error:  # digest too large
         logger.debug(error, exc_info=True)
         raise errors.Error(str(error))
     signer.update(msg)
     try:
         return signer.finalize()
     except ValueError as error:
         logger.debug(error, exc_info=True)
         raise errors.Error(str(error))
 def sign(self, key, msg):
     """Sign the ``msg`` using ``key``."""
     # If cryptography library supports new style api (v1.4 and later)
     new_api = hasattr(key, "sign")
     try:
         if new_api:
             return key.sign(msg, self.padding, self.hash)
         signer = key.signer(self.padding, self.hash)
     except AttributeError as error:
         logger.debug(error, exc_info=True)
         raise errors.Error("Public key cannot be used for signing")
     except ValueError as error:  # digest too large
         logger.debug(error, exc_info=True)
         raise errors.Error(str(error))
     signer.update(msg)
     try:
         return signer.finalize()
     except ValueError as error:
         logger.debug(error, exc_info=True)
         raise errors.Error(str(error))
Esempio n. 7
0
    def find_key(self) -> josepy.JWK:
        """Find key based on header.

        .. todo:: Supports only "jwk" header parameter lookup.

        :returns: (Public) key found in the header.
        :rtype: .JWK

        :raises josepy.errors.Error: if key could not be found

        """
        if self.jwk is None:
            raise errors.Error('No key found')
        return self.jwk
Esempio n. 8
0
    def encode(self, name: str) -> Any:
        """Encode a single field.

        :param str name: Name of the field to be encoded.

        :raises errors.SerializationError: if field cannot be serialized
        :raises errors.Error: if field could not be found

        """
        try:
            field = self._fields[name]  # type: ignore[attr-defined]
        except KeyError:
            raise errors.Error("Field not found: {0}".format(name))

        return field.encode(getattr(self, name))
Esempio n. 9
0
    def fields_from_json(cls, jobj: Mapping[str, Any]) -> 'JWKRSA':
        # pylint: disable=invalid-name
        n, e = (cls._decode_param(jobj[x]) for x in ('n', 'e'))
        public_numbers = rsa.RSAPublicNumbers(e=e, n=n)

        # public key
        if 'd' not in jobj:
            return cls(key=public_numbers.public_key(default_backend()))

        # private key
        d = cls._decode_param(jobj['d'])
        if ('p' in jobj or 'q' in jobj or 'dp' in jobj or 'dq' in jobj
                or 'qi' in jobj or 'oth' in jobj):
            # "If the producer includes any of the other private
            # key parameters, then all of the others MUST be
            # present, with the exception of "oth", which MUST
            # only be present when more than two prime factors
            # were used."
            p, q, dp, dq, qi, = all_params = tuple(
                jobj.get(x) for x in ('p', 'q', 'dp', 'dq', 'qi'))
            if tuple(param for param in all_params if param is None):
                raise errors.Error(
                    'Some private parameters are missing: {0}'.format(
                        all_params))
            p, q, dp, dq, qi = tuple(
                cls._decode_param(str(x)) for x in all_params)

            # TODO: check for oth
        else:
            # cryptography>=0.8
            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)

        key = rsa.RSAPrivateNumbers(
            p, q, d, dp, dq, qi, public_numbers).private_key(default_backend())

        return cls(key=key)
Esempio n. 10
0
    def _load_cryptography_key(cls, data, password=None, backend=None):
        backend = default_backend() if backend is None else backend
        exceptions = {}

        # private key?
        for loader in (serialization.load_pem_private_key,
                       serialization.load_der_private_key):
            try:
                return loader(data, password, backend)
            except (ValueError, TypeError,
                    cryptography.exceptions.UnsupportedAlgorithm) as error:
                exceptions[loader] = error

        # public key?
        for loader in (serialization.load_pem_public_key,
                       serialization.load_der_public_key):
            try:
                return loader(data, backend)
            except (ValueError,
                    cryptography.exceptions.UnsupportedAlgorithm) as error:
                exceptions[loader] = error

        # no luck
        raise errors.Error('Unable to deserialize key: {0}'.format(exceptions))