Exemplo n.º 1
0
def test_make_id_token():
    srv = Server()
    srv.keyjar = KEYJ
    srv.keyjar["http://oic.example/rp"] = KC_RSA

    session = {"sub": "user0", "client_id": "http://oic.example/rp"}
    issuer = "http://oic.example/idp"
    code = "abcdefghijklmnop"
    _idt = srv.make_id_token(session,
                             loa="2",
                             issuer=issuer,
                             code=code,
                             access_token="access_token")

    algo = "RS256"
    ckey = srv.keyjar.get_signing_key(alg2keytype(algo), session["client_id"])
    _signed_jwt = _idt.to_jwt(key=ckey, algorithm="RS256")

    idt = IdToken().from_jwt(_signed_jwt, keyjar=srv.keyjar)
    print idt
    header = unpack(_signed_jwt)

    lha = left_hash(code, func="HS" + header[0]["alg"][-3:])
    assert lha == idt["c_hash"]

    atr = AccessTokenResponse(id_token=_signed_jwt,
                              access_token="access_token",
                              token_type="Bearer")
    atr["code"] = code
    assert atr.verify(keyjar=srv.keyjar)
Exemplo n.º 2
0
def test_make_id_token():
    srv = Server()
    srv.keyjar = KEYJ
    srv.keyjar["http://oic.example/rp"] = KC_RSA

    session = {"sub": "user0",
               "client_id": "http://oic.example/rp"}
    issuer = "http://oic.example/idp"
    code = "abcdefghijklmnop"
    _idt = srv.make_id_token(session, loa="2", issuer=issuer,
                             code=code, access_token="access_token")

    algo = "RS256"
    ckey = srv.keyjar.get_signing_key(alg2keytype(algo), session["client_id"])
    _signed_jwt = _idt.to_jwt(key=ckey, algorithm="RS256")

    idt = IdToken().from_jwt(_signed_jwt, keyjar=srv.keyjar)
    print idt
    header = unpack(_signed_jwt)

    lha = left_hash(code, func="HS" + header[0]["alg"][-3:])
    assert lha == idt["c_hash"]

    atr = AccessTokenResponse(id_token=_signed_jwt, access_token="access_token",
                              token_type="Bearer")
    atr["code"] = code
    assert atr.verify(keyjar=srv.keyjar)
Exemplo n.º 3
0
def test_assertion_jwt():
    cli = Client("Foo")
    cli.client_secret = "secert"
    at = oic.assertion_jwt(cli, {}, audience="audience", algorithm="none")
    print at
    header, claim, crypto, header_b64, claim_b64 = unpack(at)
    jso = json.loads(claim)
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
Exemplo n.º 4
0
def test_a_1_3a():
    _jwt = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

    #keycol = {"hmac": jwkest.intarr2bin(HMAC_KEY)}
    header, claim, crypto, header_b64, claim_b64 = jwkest.unpack(_jwt)

    hmac = jwkest.intarr2bin(HMAC_KEY)
    signer = SIGNER_ALGS["HS256"]
    info = signer.verify(header_b64 + '.' + claim_b64, crypto, hmac)
Exemplo n.º 5
0
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :return: A class instance
        """
        if key is None and keyjar is not None:
            key = keyjar.get_verify_key(owner="")
        elif key is None:
            key = {}

        header = json.loads(b64d(str(txt.split(".")[0])))
        try:
            htype = header["typ"]
        except KeyError:
            htype = None

        jso = None
        if htype == "JWE" or ("alg" in header and "enc" in header):  # encrypted
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
            else:
                dkeys = {}
            txt = jwe.decrypt(txt, dkeys, "private")
            try:
                jso = json.loads(txt)
            except Exception:
                pass

        # assume htype == 'JWS'
        if not jso:
            try:
                jso = jwkest.unpack(txt)[1]
                if isinstance(jso, basestring):
                    jso = json.loads(jso)
                if verify:
                    if keyjar:
                        for ent in ["iss", "aud", "client_id"]:
                            if ent not in jso:
                                continue
                            if ent == "aud":
                                for _e in jso[ent]:
                                    self._add_key(keyjar, _e, key)
                            else:
                                self._add_key(keyjar, jso[ent], key)

                    jws.verify(txt, key)
            except Exception:
                raise

        return self.from_dict(jso)
Exemplo n.º 6
0
def test_a_1_3a():
    _jwt = (
        "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJle"
        "HAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnV"
        "lfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk")

    #keycol = {"hmac": jwkest.intarr2bin(HMAC_KEY)}
    header, claim, crypto, header_b64, claim_b64 = jwkest.unpack(_jwt)

    hmac = jwkest.intarr2bin(HMAC_KEY)
    signer = SIGNER_ALGS["HS256"]
    signer.verify(header_b64 + '.' + claim_b64, crypto, hmac)
Exemplo n.º 7
0
def test_private_key_jwt():
    cli = Client("FOO")
    cli.token_endpoint = "https://example.com/token"
    cli.keyjar[""] = KC_RSA

    cis = AccessTokenRequest()
    at = oic.private_key_jwt(cli, cis, algorithm="RS256")
    assert at == {}
    cas = cis["client_assertion"]
    header, claim, crypto, header_b64, claim_b64 = unpack(cas)
    jso = json.loads(claim)
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print header
    assert header == {'alg': 'RS256'}
Exemplo n.º 8
0
def test_private_key_jwt():
    cli = Client("FOO")
    cli.token_endpoint = "https://example.com/token"
    cli.keyjar[""] = KC_RSA

    cis = AccessTokenRequest()
    pkj = PrivateKeyJWT(cli)
    http_args = pkj.construct(cis, algorithm="RS256")
    assert http_args == {}
    cas = cis["client_assertion"]
    header, claim, crypto, header_b64, claim_b64 = jwkest.unpack(cas)
    jso = json.loads(claim)
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print header
    assert header == {'alg': 'RS256'}
Exemplo n.º 9
0
    def verify(self, **kwargs):
        if "aud" in self:
            if "client_id" in kwargs:
                # check that it's for me
                if kwargs["client_id"] not in self["aud"]:
                    return False

        if "id_token" in self:
            # Try to decode the JWT, checks the signature
            args = {}
            for arg in ["key", "keyjar"]:
                try:
                    args[arg] = kwargs[arg]
                except KeyError:
                    pass
            idt = IdToken().from_jwt(str(self["id_token"]), **args)
            if not idt.verify(**kwargs):
                raise VerificationError("Could not verify id_token", idt)

            hfunc = "HS" + jwkest.unpack(self["id_token"])[0]["alg"][-3:]

            if "access_token" in self:
                try:
                    assert "at_hash" in idt
                except AssertionError:
                    raise MissingRequiredAttribute("Missing at_hash property",
                                                   idt)
                try:
                    assert idt["at_hash"] == jws.left_hash(
                        self["access_token"], hfunc)
                except AssertionError:
                    raise VerificationError(
                        "Failed to verify access_token hash", idt)

            if "code" in self:
                try:
                    assert "c_hash" in idt
                except AssertionError:
                    raise MissingRequiredAttribute("Missing c_hash property",
                                                   idt)
                try:
                    assert idt["c_hash"] == jws.left_hash(self["code"], hfunc)
                except AssertionError:
                    raise VerificationError("Failed to verify code hash", idt)

            self["id_token"] = idt

        return super(AuthorizationResponse, self).verify(**kwargs)
Exemplo n.º 10
0
    def verify(self, **kwargs):
        if "aud" in self:
            if "client_id" in kwargs:
                # check that it's for me
                if kwargs["client_id"] not in self["aud"]:
                    return False

        if "id_token" in self:
            # Try to decode the JWT, checks the signature
            args = {}
            for arg in ["key", "keyjar"]:
                try:
                    args[arg] = kwargs[arg]
                except KeyError:
                    pass
            idt = IdToken().from_jwt(str(self["id_token"]), **args)
            if not idt.verify(**kwargs):
                raise VerificationError("Could not verify id_token", idt)

            hfunc = "HS" + jwkest.unpack(self["id_token"])[0]["alg"][-3:]

            if "access_token" in self:
                try:
                    assert "at_hash" in idt
                except AssertionError:
                    raise MissingRequiredAttribute("Missing at_hash property",
                                                   idt)
                try:
                    assert idt["at_hash"] == jws.left_hash(
                        self["access_token"], hfunc)
                except AssertionError:
                    raise VerificationError(
                        "Failed to verify access_token hash", idt)

            if "code" in self:
                try:
                    assert "c_hash" in idt
                except AssertionError:
                    raise MissingRequiredAttribute("Missing c_hash property",
                                                   idt)
                try:
                    assert idt["c_hash"] == jws.left_hash(self["code"], hfunc)
                except AssertionError:
                    raise VerificationError("Failed to verify code hash", idt)

            self["id_token"] = idt

        return super(AuthorizationResponse, self).verify(**kwargs)
Exemplo n.º 11
0
def test_client_secret_jwt():
    cli = Client("Foo")
    cli.token_endpoint = "https://example.com/token"
    cli.client_secret = "foobar"

    cis = AccessTokenRequest()
    at = oic.client_secret_jwt(cli, cis, algorithm="HS256")
    assert at == {}
    assert cis["client_assertion_type"] == JWT_BEARER
    assert "client_assertion" in cis
    cas = cis["client_assertion"]
    header, claim, crypto, header_b64, claim_b64 = unpack(cas)
    jso = json.loads(claim)
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print header
    assert header == {'alg': 'HS256'}
Exemplo n.º 12
0
    def _func(self, conv=None):
        userinfo_claims = {}

        req = get_authz_request(conv)
        try:
            _scopes = req["scope"]
        except KeyError:
            return {}

        for scope in _scopes:
            try:
                claims = dict([(name, None) for name in SCOPE2CLAIMS[scope]])
                userinfo_claims.update(claims)
            except KeyError:
                pass

        if "request" in req:
            jso = json.loads(unpack(req["request"])[1])
            _uic = jso["userinfo"]
            for key, val in _uic["claims"].items():
                userinfo_claims[key] = val

        # last item should be the UserInfoResponse
        resp = conv.response_message
        if userinfo_claims:
            for key, restr in userinfo_claims.items():
                if key in resp:
                    pass
                else:
                    if restr == {"essential": True}:
                        self._status = self.status
                        self._message = "required attribute '%s' missing" % key
                        return {"returned claims": resp.keys()}

        for key in resp.keys():
            if key not in userinfo_claims:
                self._status = WARNING
                self._message = "Unexpected %s claim in response" % key
                return {"returned claims": resp.keys()}

        return {}
Exemplo n.º 13
0
    def _func(self, conv):
        client = conv.client
        for instance, msg in conv.protocol_response:
            if isinstance(instance, message.AccessTokenResponse):
                _dic = json.loads(msg)
                header = json.loads(b64d(str(_dic["id_token"].split(".")[0])))
                try:
                    assert header["alg"].startswith("RSA")
                except AssertionError:
                    self._status = self.status
                    break

                dkeys = client.keyjar.get_decrypt_key(owner="")
                txt = JWE_RSA().decrypt(_dic["id_token"], dkeys[0].key)
                _tmp = unpack(txt)[0]
                try:
                    assert _tmp["alg"] == "RS256"
                except AssertionError:
                    self._status = self.status
                break

        return {}
Exemplo n.º 14
0
def test_client_secret_jwt():
    cli = Client("Foo")
    cli.token_endpoint = "https://example.com/token"
    cli.client_secret = "foobar"

    csj = ClientSecretJWT(cli)
    cis = AccessTokenRequest()

    http_args = csj.construct(cis, algorithm="HS256")
    print http_args
    assert cis["client_assertion_type"] == JWT_BEARER
    assert "client_assertion" in cis
    cas = cis["client_assertion"]
    header, claim, crypto, header_b64, claim_b64 = jwkest.unpack(cas)
    jso = json.loads(claim)
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print header
    assert header == {'alg': 'HS256'}

    _rj = JWS()
    info = _rj.verify_compact(cas, [SYMKey(key=cli.client_secret)])

    _dict = json.loads(info)
    assert _eq(_dict.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
Exemplo n.º 15
0
                        help="File containing a public RSA key")
    parser.add_argument('-k', dest="hmac_key",
                        help="If using a HMAC algorithm this is the key")
    parser.add_argument('-x', dest="x509_file",
                        help="File containing a X509 certificate")
    parser.add_argument("message", nargs="?",
                        help="The message to verify signature on")


    args = parser.parse_args()

    keys = {}
    if args.rsa_file:
        keys = {"rsa": [rsa_load(args.rsa_file)]}
    elif args.hmac_key:
        keys = {"hmac": [args.hmac_key]}
    elif args.x509_file:
        keys = {"rsa": [x509_rsa_loads(open(args.x509_file).read())]}
    elif args.rsa_pub_file:
        keys = {"rsa": [rsa_pub_load(args.rsa_pub_file)]}

    if args.message == "-":
        message = sys.stdin.read()
    else:
        message = args.message

    if keys:
        print verify(message, keys)
    else:
        print unpack(message)[1]
Exemplo n.º 16
0
                        dest="hmac_key",
                        help="If using a HMAC algorithm this is the key")
    parser.add_argument('-x',
                        dest="x509_file",
                        help="File containing a X509 certificate")
    parser.add_argument("message",
                        nargs="?",
                        help="The message to verify signature on")

    args = parser.parse_args()

    keys = {}
    if args.rsa_file:
        keys = {"rsa": [rsa_load(args.rsa_file)]}
    elif args.hmac_key:
        keys = {"hmac": [args.hmac_key]}
    elif args.x509_file:
        keys = {"rsa": [x509_rsa_loads(open(args.x509_file).read())]}
    elif args.rsa_pub_file:
        keys = {"rsa": [rsa_pub_load(args.rsa_pub_file)]}

    if args.message == "-":
        message = sys.stdin.read()
    else:
        message = args.message

    if keys:
        print verify(message, keys)
    else:
        print unpack(message)[1]
Exemplo n.º 17
0
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :return: A class instance
        """
        if key is None and keyjar is not None:
            key = keyjar.get_verify_key(owner="")
        elif key is None:
            key = {}

        header = json.loads(b64d(str(txt.split(".")[0])))
        logger.debug("header: %s" % (header, ))

        try:
            htype = header["typ"]
        except KeyError:
            htype = None

        try:
            _kid = header["kid"]
        except KeyError:
            _kid = ""

        jso = None
        if htype == "JWE" or ("alg" in header
                              and "enc" in header):  # encrypted
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
            else:
                dkeys = {}
            txt = JWE().decrypt(txt, dkeys)
            try:
                jso = json.loads(txt)
            except Exception:
                pass

        # assume htype == 'JWS'
        _jws = JWS()
        if not jso:
            try:
                jso = jwkest.unpack(txt)[1]
                if isinstance(jso, basestring):
                    jso = json.loads(jso)

                if keyjar:
                    if "jku" in header:
                        if not keyjar.find(header["jku"], jso["iss"]):
                            # This is really questionable
                            try:
                                if kwargs["trusting"]:
                                    keyjar.add(jso["iss"], header["jku"])
                            except KeyError:
                                pass

                    if _kid:
                        try:
                            _key = keyjar.get_key_by_kid(_kid, jso["iss"])
                            if _key:
                                key.append(_key)
                        except KeyError:
                            pass

                    try:
                        self._add_key(keyjar, kwargs["opponent_id"], key)
                    except KeyError:
                        pass

                if verify:
                    if keyjar:
                        for ent in ["iss", "aud", "client_id"]:
                            if ent not in jso:
                                continue
                            if ent == "aud":
                                # list or basestring
                                if isinstance(jso["aud"], basestring):
                                    _aud = [jso["aud"]]
                                else:
                                    _aud = jso["aud"]
                                for _e in _aud:
                                    self._add_key(keyjar, _e, key)
                            else:
                                self._add_key(keyjar, jso[ent], key)

                    if "alg" in header and header["alg"] != "none":
                        if not key:
                            raise MissingSigningKey("alg=%s" % header["alg"])

                    _jws.verify_compact(txt, key)
            except Exception:
                raise

        return self.from_dict(jso)
Exemplo n.º 18
0
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :param keyjar: A KeyJar that might contain the necessary key.
        :param kwargs: Extra key word arguments
        :return: A class instance
        """
        if key is None and keyjar is not None:
            key = keyjar.get_verify_key(owner="")
        elif key is None:
            key = []

        if keyjar is not None and "sender" in kwargs:
            key.extend(keyjar.get_verify_key(owner=kwargs["sender"]))

        _jw = jwe.factory(txt)
        if _jw:
            if "algs" in kwargs and "encalg" in kwargs["algs"]:
                try:
                    assert kwargs["algs"]["encalg"] == _jw["alg"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm("%s != %s" % (
                        _jw["alg"], kwargs["algs"]["encalg"]))
                try:
                    assert kwargs["algs"]["encenc"] == _jw["enc"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm("%s != %s" % (
                        _jw["enc"], kwargs["algs"]["encenc"]))
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
            elif key:
                dkeys = key
            else:
                dkeys = []

            txt = _jw.decrypt(txt, dkeys)
            self.jwe_header = _jw.dump_header()

        _jw = jws.factory(txt)
        if _jw:
            if "algs" in kwargs and "sign" in kwargs["algs"]:
                try:
                    assert kwargs["algs"]["sign"] == _jw["alg"]
                except AssertionError:
                    raise WrongSigningAlgorithm("%s != %s" % (
                        _jw["alg"], kwargs["algs"]["sign"]))
            try:
                p = jwkest.unpack(txt)
                jso = json.loads(p[1])

                logger.debug("Raw JSON: %s" % jso)
                if _jw["alg"] == "none":
                    pass
                else:
                    if keyjar:
                        if "jku" in _jw:
                            if not keyjar.find(_jw["jku"], jso["iss"]):
                                # This is really questionable
                                try:
                                    if kwargs["trusting"]:
                                        keyjar.add(jso["iss"], _jw["jku"])
                                except KeyError:
                                    pass

                        if "kid" in _jw and _jw["kid"]:
                            try:
                                _key = keyjar.get_key_by_kid(_jw["kid"],
                                                             jso["iss"])
                                if _key:
                                    key.append(_key)
                            except KeyError:
                                pass

                        try:
                            self._add_key(keyjar, kwargs["opponent_id"], key)
                        except KeyError:
                            pass

                    if verify:
                        if keyjar:
                            for ent in ["iss", "aud", "client_id"]:
                                if ent not in jso:
                                    continue
                                if ent == "aud":
                                    # list or basestring
                                    if isinstance(jso["aud"], basestring):
                                        _aud = [jso["aud"]]
                                    else:
                                        _aud = jso["aud"]
                                    for _e in _aud:
                                        self._add_key(keyjar, _e, key)
                                else:
                                    self._add_key(keyjar, jso[ent], key)

                        if "alg" in _jw and _jw["alg"] != "none":
                            if not key:
                                raise MissingSigningKey(
                                    "alg=%s" % _jw["alg"])

                        _jw.verify_compact(txt, key)
            except Exception:
                raise
            else:
                self.jws_header = _jw.dump_header()
        else:
            jso = json.loads(txt)

        return self.from_dict(jso)
Exemplo n.º 19
0
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :return: A class instance
        """
        if key is None and keyjar is not None:
            key = keyjar.get_verify_key(owner="")
        elif key is None:
            key = {}

        header = json.loads(b64d(str(txt.split(".")[0])))
        logger.debug("header: %s" % (header,))

        try:
            htype = header["typ"]
        except KeyError:
            htype = None

        try:
            _kid = header["kid"]
        except KeyError:
            _kid = ""

        jso = None
        if htype == "JWE" or ("alg" in header and "enc" in header):  # encrypted
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
            else:
                dkeys = {}
            txt = JWE().decrypt(txt, dkeys, "private")
            try:
                jso = json.loads(txt)
            except Exception:
                pass

        # assume htype == 'JWS'
        _jws = JWS()
        if not jso:
            try:
                jso = jwkest.unpack(txt)[1]
                if isinstance(jso, basestring):
                    jso = json.loads(jso)

                if "jku" in header:
                    if not keyjar.find(header["jku"], jso["iss"]):
                        # This is really questionable
                        try:
                            if kwargs["trusting"]:
                                keyjar.add(jso["iss"], header["jku"])
                        except KeyError:
                            pass

                if _kid:
                    _key = keyjar.get_key_by_kid(_kid, jso["iss"])
                    if _key:
                        key.append(_key)

                try:
                    self._add_key(keyjar, kwargs["opponent_id"], key)
                except KeyError:
                    pass

                if verify:
                    if keyjar:
                        for ent in ["iss", "aud", "client_id"]:
                            if ent not in jso:
                                continue
                            if ent == "aud":
                                # list or basestring
                                if isinstance(jso["aud"], basestring):
                                    _aud = [jso["aud"]]
                                else:
                                    _aud = jso["aud"]
                                for _e in _aud:
                                    self._add_key(keyjar, _e, key)
                            else:
                                self._add_key(keyjar, jso[ent], key)

                    _jws.verify_compact(txt, key)
            except Exception:
                raise

        return self.from_dict(jso)