示例#1
0
    def _verify_jws(self, payload, key):
        """
        Verify the given JWS payload with the given key and return the payload.
        """
        jws = JWS.from_compact(payload)

        try:
            alg = jws.signature.combined.alg.name
        except KeyError:
            msg = 'No alg value found in header'
            raise SuspiciousOperation(msg)

        if alg != self.OIDC_RP_SIGN_ALGO:
            msg = "The provider algorithm {!r} does not match the client's " \
                  "OIDC_RP_SIGN_ALGO.".format(alg)
            raise SuspiciousOperation(msg)

        if isinstance(key, six.string_types):
            # Use smart_bytes here since the key string comes from settings.
            jwk = JWK.load(smart_bytes(key))
        else:
            # The key is a json returned from the IDP JWKS endpoint.
            jwk = JWK.from_json(key)

        if not jws.verify(jwk):
            msg = 'JWS token verification failed.'
            raise SuspiciousOperation(msg)

        return jws.payload
示例#2
0
def cert_to_jwk(certificates: str, public_key: str) -> str:
    """
    coverts a pem public key and a pem certificate chain to a jwk with a x5c element
    :param certificates: the certificates for the x5c as pem key list
    :param public_key: the pem public key as string
    :return: the jwk as string
    """

    # convert public key to jwk
    public_key = crypto.load_publickey(crypto.FILETYPE_PEM, public_key)
    jwk = JWK.load(crypto.dump_publickey(crypto.FILETYPE_PEM, public_key))

    # covert cert chain to base64 encoded ASN1 according to https://tools.ietf.org/html/rfc7517#section-4.7
    x5c = []
    for cert in pem.parse(str.encode(certificates)):
        cert_pem = crypto.load_certificate(crypto.FILETYPE_PEM,
                                           cert.as_bytes())
        x5c.append(
            base64.b64encode(
                crypto.dump_certificate(crypto.FILETYPE_ASN1,
                                        cert_pem)).decode())

    # dump jwk obj to json and add x5c cer chain
    jwk_j = jwk.to_json()
    jwk_j["x5c"] = x5c
    return json.dumps(jwk_j)
示例#3
0
    def verify(self, chall: 'KeyAuthorizationChallenge',
               account_public_key: jose.JWK) -> bool:
        """Verify the key authorization.

        :param KeyAuthorization chall: Challenge that corresponds to
            this response.
        :param JWK account_public_key:

        :return: ``True`` iff verification of the key authorization was
            successful.
        :rtype: bool

        """
        parts = self.key_authorization.split('.')  # pylint: disable=no-member
        if len(parts) != 2:
            logger.debug("Key authorization (%r) is not well formed",
                         self.key_authorization)
            return False

        if parts[0] != chall.encode("token"):
            logger.debug(
                "Mismatching token in key authorization: "
                "%r instead of %r", parts[0], chall.encode("token"))
            return False

        thumbprint = jose.b64encode(
            account_public_key.thumbprint(
                hash_function=self.thumbprint_hash_function)).decode()
        if parts[1] != thumbprint:
            logger.debug(
                "Mismatching thumbprint in key authorization: "
                "%r instead of %r", parts[0], thumbprint)
            return False

        return True
示例#4
0
    def key_authorization(self, account_key: jose.JWK) -> str:
        """Generate Key Authorization.

        :param JWK account_key:
        :rtype str:

        """
        return self.encode("token") + "." + jose.b64encode(
            account_key.thumbprint(
                hash_function=self.thumbprint_hash_function)).decode()
示例#5
0
    def from_data(cls, account_public_key: jose.JWK, kid: str, hmac_key: str,
                  directory: Directory) -> Dict[str, Any]:
        """Create External Account Binding Resource from contact details, kid and hmac."""

        key_json = json.dumps(account_public_key.to_partial_json()).encode()
        decoded_hmac_key = jose.b64.b64decode(hmac_key)
        url = directory["newAccount"]

        eab = jws.JWS.sign(key_json, jose.jwk.JWKOct(key=decoded_hmac_key),
                           jose.jwa.HS256, None, url, kid)

        return eab.to_partial_json()
示例#6
0
文件: crypto.py 项目: valohai/oidckit
def decode_jws(
    payload: bytes, key: dict, expected_algorithm: str, verify: bool = True
) -> dict:
    jws = JWS.from_compact(payload)
    if verify:
        try:
            alg = jws.signature.combined.alg.name
        except KeyError as exc:
            raise OIDCError("No alg value found in header") from exc

        if alg != expected_algorithm:
            raise OIDCError(
                f"Algorithm mismatch: offered {alg} is not expected {expected_algorithm}"
            )

        jwk = JWK.from_json(key)
        if not jws.verify(jwk):
            raise OIDCError("JWS token verification failed.")

    return jws.payload
示例#7
0
文件: jws.py 项目: adferrand/josepy
    def sign(cls,
             payload: bytes,
             key: josepy.JWK,
             alg: josepy.JWASignature,
             include_jwk: bool = True,
             protect: FrozenSet = frozenset(),
             **kwargs: Any) -> 'Signature':
        """Sign.

        :param bytes payload: Payload to sign.
        :param JWK key: Key for signature.
        :param JWASignature alg: Signature algorithm to use to sign.
        :param bool include_jwk: If True, insert the JWK inside the signature headers.
        :param FrozenSet protect: List of headers to protect.

        """
        assert isinstance(key, alg.kty)

        header_params = kwargs
        header_params['alg'] = alg
        if include_jwk:
            header_params['jwk'] = key.public_key()

        assert set(header_params).issubset(cls.header_cls._fields)
        assert protect.issubset(cls.header_cls._fields)

        protected_params = {}
        for header in protect:
            if header in header_params:
                protected_params[header] = header_params.pop(header)
        if protected_params:
            protected = cls.header_cls(**protected_params).json_dumps()
        else:
            protected = ''

        header = cls.header_cls(**header_params)
        signature = alg.sign(key.key, cls._msg(protected, payload))

        return cls(protected=protected, header=header, signature=signature)
def pem_to_jwk(pem):
    return JWK.load(pem)