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__))
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()))
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 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
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))
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)
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))