def _get_keyset(self, kid=None):
        """
        Get keyset from available sources.

        If using a RSA key, forcefully set the key id
        to match the one from the JWT token.
        """
        keyset = []

        if self.keyset_url:
            try:
                keys = load_jwks_from_url(self.keyset_url)
            except Exception as err:
                # Broad Exception is required here because jwkest raises
                # an Exception object explicitly.
                # Beware that many different scenarios are being handled
                # as an invalid key when the JWK loading fails.
                raise exceptions.NoSuitableKeys() from err
            keyset.extend(keys)

        if self.public_key and kid:
            # Fill in key id of stored key.
            # This is needed because if the JWS is signed with a
            # key with a kid, pyjwkest doesn't match them with
            # keys without kid (kid=None) and fails verification
            self.public_key.kid = kid

            # Add to keyset
            keyset.append(self.public_key)

        return keyset
Beispiel #2
0
    def _get_keys(self):
        if "jwk" in self:
            return [self["jwk"]]
        elif "jku" in self:
            keys = load_jwks_from_url(self["jku"], {})
            return dict(keys)
        elif "x5u" in self:
            try:
                return {"rsa": [load_x509_cert(self["x5u"], {})]}
            except Exception:
                ca_chain = load_x509_cert_chain(self["x5u"])

        return {}
Beispiel #3
0
    def _get_keys(self):
        if "jwk" in self:
            return [self["jwk"]]
        elif "jku" in self:
            keys = load_jwks_from_url(self["jku"], {})
            return dict(keys)
        elif "x5u" in self:
            try:
                return {"rsa": [load_x509_cert(self["x5u"], {})]}
            except Exception:
                #ca_chain = load_x509_cert_chain(self["x5u"])
                pass

        return {}
def verify_id(token):
    global jwks_uri

    header, claims, signature = token.split('.')
    header = b64d(header)
    claims = b64d(claims)

    if not signature:
        raise ValueError('Invalid Token')

    if header['alg'] not in ['HS256', 'RS256']:
        raise ValueError('Unsupported signing method')

    if header['alg'] == 'RS256':
        signing_keys = load_jwks_from_url(jwks_uri)
    else:
        signing_keys = [SYMKey(key=str(CLIENT_SECRET))]

    id_token = JWS().verify_compact(token, signing_keys)
    id_token['header_info'] = header
    return id_token
Beispiel #5
0
    def _get_keyset(self, kid=None):
        """
        Get keyset from available sources.

        If using a RSA key, forcefully set the key id
        to match the one from the JWT token.
        """
        keyset = []

        if self.keyset_url:
            # TODO: Improve support for keyset handling, handle errors.
            keyset.extend(load_jwks_from_url(self.keyset_url))

        if self.public_key and kid:
            # Fill in key id of stored key.
            # This is needed because if the JWS is signed with a
            # key with a kid, pyjwkest doesn't match them with
            # keys without kid (kid=None) and fails verification
            self.public_key.kid = kid

            # Add to keyset
            keyset.append(self.public_key)

        return keyset
Beispiel #6
0
    parser.add_argument('-j', dest="jwk_file", help="File containing a JWK")
    parser.add_argument('-J',
                        dest="jwk_url",
                        help="URL pointing to a file containing a JWK")
    parser.add_argument('-r',
                        dest="rsa_file",
                        help="A file containing a RSA key")
    parser.add_argument("-i", dest="int", help="Integrity method")
    parser.add_argument("-f", dest="file", help="File with the message")
    parser.add_argument("message", nargs="?", help="The message to encrypt")

    args = parser.parse_args()

    keys = {}
    if args.jwk_url:
        keys = assign(load_jwks_from_url(lrequest, args.jwk_url))
    elif args.jwk_file:
        keys = load_jwks(open(args.jwk_file).read())
    elif args.x509_url:
        keys = load_x509_cert(lrequest, args.x509_url)
    elif args.x509_file:
        keys = [import_rsa_key_from_file(args.x509_file)]
    elif args.rsa_file:
        key = rsa_load(args.rsa_file)
        rsa_key = RSAKey(key=key)
        rsa_key.serialize()
        keys = [rsa_key]
    else:
        print("Needs encryption key")
        exit()
Beispiel #7
0
    parser.add_argument('-r', dest="rsa_file",
                        help="A file containing a RSA key")
    parser.add_argument('-a', dest="alg",
                        help="The encryption algorithm")
    parser.add_argument("-e", dest="enc", help="The encryption method")
    parser.add_argument("-m", dest="mode", default="public",
                        help="Whether a public or private key should be used")
    parser.add_argument("-f", dest="file",
                        help="File to be encrypted")
    parser.add_argument("message", nargs="?", help="The message to encrypt")

    args = parser.parse_args()

    keys = {}
    if args.jwk_url:
        keys = load_jwks_from_url(args.jwk_url, {})
    elif args.jwk_file:
        keys = load_jwks(open(args.jwk_file).read())
    elif args.x509_url:
        # load_x509_cert returns list of 2-tuples
        keys = [RSAKey(key=x) for x, y in load_x509_cert(lrequest,
                                                         args.x509_url)]
        for key in keys:
            key.serialize()
    elif args.x509_file:
        # import_rsa_key_from_file returns RSA key instance
        _key = RSAKey(key=import_rsa_key_from_file(args.x509_file))
        _key.serialize()
        keys = [_key]
    elif args.rsa_file:
        _key = RSAKey(key=rsa_load(args.rsa_file))
    parser.add_argument('-j', dest="jwk_file", help="File containing a JWK")
    parser.add_argument('-J',
                        dest="jwk_url",
                        help="URL pointing to a file containing a JWK")
    parser.add_argument('-r',
                        dest="rsa_file",
                        help="A file containing a RSA key")
    parser.add_argument("-i", dest="int", help="Integrity method")
    parser.add_argument("-f", dest="file", help="File with the message")
    parser.add_argument("message", nargs="?", help="The message to encrypt")

    args = parser.parse_args()

    keys = {}
    if args.jwk_url:
        keys = load_jwks_from_url(args.jwk_url)
    elif args.jwk_file:
        keys = load_jwks(open(args.jwk_file).read())
    elif args.x509_url:
        keys = load_x509_cert(args.x509_url, {})
    elif args.x509_file:
        keys = [import_rsa_key_from_file(args.x509_file)]
    elif args.rsa_file:
        key = rsa_load(args.rsa_file)
        rsa_key = RSAKey(key=key)
        rsa_key.serialize()
        keys = [rsa_key]
    else:
        print("Needs encryption key")
        exit()
Beispiel #9
0
    parser.add_argument('-J', dest="jwk_url",
                        help="URL pointing to a file containing a JWK")
    parser.add_argument('-r', dest="rsa_file",
                        help="A file containing a RSA key")
    parser.add_argument("-i", dest="int", help="Integrity method")
    parser.add_argument("-m", dest="mode", default="private",
                        help="Whether a public or private key should be used")
    parser.add_argument("-f", dest="file", help="File with the message")
    parser.add_argument("message", nargs="?", help="The message to encrypt")


    args = parser.parse_args()

    keys = {}
    if args.jwk_url:
        keys = assign(load_jwks_from_url(lrequest, args.jwk_url))
        if args.mode == "private":
            print >> sys.stderr, "Missing private key to decrypt with"
            exit()
    elif args.jwk_file:
        keys = assign(load_jwks(open(args.jwk_file).read()))
        if args.mode == "private":
            print >> sys.stderr, "Missing private key to decrypt with"
            exit()
    elif args.x509_url:
        keys = assign(load_x509_cert(lrequest, args.x509_url))
        if args.mode == "private":
            print >> sys.stderr, "Missing private key to decrypt with"
            exit()
    elif args.x509_file:
        keys = {"rsa": [x509_rsa_loads(open(args.x509_file).read())]}
Beispiel #10
0
    def signing_keys(self):
        if self.signing_alg == self.RS256:
            # TODO perform caching, OBVIOUS
            return load_jwks_from_url(self.jwks_uri)

        return [SYMKey(key=str(self.client_secret))]
Beispiel #11
0
    def login(self, manager, context, db, **kwargs):
        """
        Return "username" in the form iss:sub.

        It is expected that the caller will store the resulting username into context.client for reuse.
        
        """
        vals = web.input()

        # Check that this request came from the same user who initiated the oauth flow
        nonce_vals = {
            'auth_url_nonce' : vals.get('state'),
            'auth_cookie_nonce' : web.cookies().get(self.provider.nonce_cookie_name)
            }

        if nonce_vals['auth_url_nonce'] == None:
            raise OAuth2ProtocolError("No authn_nonce in initial redirect")

        if (nonce_vals['auth_cookie_nonce'] == None):
            raise OAuth2ProtocolError("No authn nonce cookie")

        # Has the cookie nonce expired?
        try:
            ts = nonce_util.get_cookie_ts(nonce_vals['auth_cookie_nonce'])
        except:
            raise OAuth2ProtocolError('bad nonce cookie')

        if not self.provider.nonce_state.time_ok(ts):
            raise OAuth2LoginTimeoutError('Login timed out')

        if not self.provider.nonce_state.hash_matches(nonce_vals['auth_cookie_nonce'], nonce_vals['auth_url_nonce'], db):
            raise OAuth2ProtocolError('nonce mismatch')

        # we'll write this to the db if all goes well
        redirect_full_payload=simplejson.dumps(vals, separators=(',', ':'))

        # Get id token
        token_args = {
            'code' : vals.get('code'),
            'client_id' : self.provider.cfg.get('client_id'),
            'client_secret' : self.provider.cfg.get('client_secret'),
            'redirect_uri' : web.ctx.home + web.ctx.path,
            'nonce' : nonce_vals['auth_url_nonce'],
            'grant_type' : 'authorization_code'}
        base_timestamp = datetime.now()
        u=urllib2.urlopen(self.provider.cfg.get('token_endpoint'), urllib.urlencode(token_args))
        payload=simplejson.load(u)
        u.close()
        token_payload=simplejson.dumps(payload, separators=(',', ':'))
        raw_id_token=payload.get('id_token')

        # Validate id token
        raw_keys=jwk.load_jwks_from_url(self.provider.cfg.get('jwks_uri'))
        keys=[]
        for k in raw_keys:
            keys.append(k.key.exportKey())

        id_result=self.verify_signed_jwt_with_keys(raw_id_token, keys, self.provider.cfg.get('client_id'))
        id_token=id_result.get('body')
        id_header=id_result.get('header')
        if id_token.get('iss') == None or id_token.get('iss').strip() == '':
            raise OAuth2IDTokenError('No issuer in ID token')
        if id_token.get('sub') == None or id_token.get('sub').strip() == '':
            raise OAuth2IDTokenError('No subject in ID token')
        if self.provider.provider_sets_token_nonce and id_token.get('nonce') != nonce_vals['auth_url_nonce']:
            raise OAuth2IDTokenError('Bad nonce in ID token')

        # Validate access token
        self.validate_access_token(id_header.get('alg'), id_token.get('at_hash'), payload.get('access_token'))

        # Get user directory data. Right now we're assuming the server will return json.
        # TODO: in theory the return value could be signed jwt
        req=urllib2.Request(self.provider.cfg.get('userinfo_endpoint'), headers={'Authorization' : 'Bearer ' + payload.get('access_token')})
        f = urllib2.urlopen(req)
        userinfo=simplejson.load(f)
        f.close()
        username = id_token.get('iss') + ':' + id_token.get('sub')

        # Update user table
        self.create_or_update_user(manager, context, username, id_token, userinfo, base_timestamp, payload, db)
        return username
Beispiel #12
0
    def signing_keys(self):
        if self.signing_alg == self.RS256:
            # TODO perform caching, OBVIOUS
            return load_jwks_from_url(self.jwks_uri)

        return [SYMKey(key=str(self.client_secret))]
Beispiel #13
0
    parser.add_argument("-x", dest="x509_file", help="File containing a X509 certificate")
    parser.add_argument("-X", dest="x509_url", help="URL pointing to a file containing a X509 " "certificate")
    parser.add_argument("-j", dest="jwk_file", help="File containing a JWK")
    parser.add_argument("-J", dest="jwk_url", help="URL pointing to a file containing a JWK")
    parser.add_argument("-r", dest="rsa_file", help="A file containing a RSA key")
    parser.add_argument("-a", dest="alg", help="The encryption algorithm")
    parser.add_argument("-e", dest="enc", help="The encryption method")
    parser.add_argument("-m", dest="mode", default="public", help="Whether a public or private key should be used")
    parser.add_argument("-f", dest="file", help="File to be encrypted")
    parser.add_argument("message", nargs="?", help="The message to encrypt")

    args = parser.parse_args()

    keys = {}
    if args.jwk_url:
        keys = assign(load_jwks_from_url(args.jwk_url, {}))
    elif args.jwk_file:
        keys = assign(load_jwks(open(args.jwk_file).read()))
    elif args.x509_url:
        keys = assign(load_x509_cert(lrequest, args.x509_url))
    elif args.x509_file:
        keys = {"RSA": [import_rsa_key_from_file(args.x509_file)]}
    elif args.rsa_file:
        keys = {"RSA": [rsa_load(args.rsa_file)]}
        mode = ""
    else:
        print >> sys.stderr, "Needs encryption key"
        exit()

    if not args.enc or not args.alg:
        print >> sys.stderr, "There are no default encryption methods"