Esempio n. 1
0
    def load(cls, data, password=None, backend=None):
        """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, assymentric 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 six.itervalues(cls.TYPES):
            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, msg):
     try:
         return self.padding.new(key).sign(self.digestmod.new(msg))
     except TypeError:
         raise errors.Error('Key has no private part necessary for signing')
     except (AttributeError, ValueError):
         # ValueError for PS, AttributeError for RS
         raise errors.Error('Key too small ({0})'.format(key.size()))
Esempio n. 3
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))
Esempio n. 4
0
    def find_key(self):
        """Find key based on header.

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

        :returns: (Public) key found in the header.
        :rtype: :class:`acme.jose.jwk.JWK`

        :raises acme.jose.errors.Error: if key could not be found

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

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

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

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

        return field.encode(getattr(self, name))
Esempio n. 6
0
    def fields_from_json(cls, jobj):
        # pylint: disable=invalid-name
        n, e = (cls._decode_param(jobj[x]) for x in ('n', 'e'))
        public_numbers = rsa.RSAPublicNumbers(e=e, n=n)
        if 'd' not in jobj:  # public key
            key = public_numbers.public_key(default_backend())
        else:  # 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(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. 7
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))