11import json
2- from Cryptodome .PublicKey import RSA
3- from ast import literal_eval
4- import jose .jwk as jwk
5- import jose .jwt as jwt
2+ import os
63import time
74import uuid
8- import os
5+
6+ from ast import literal_eval
7+ from Cryptodome .PublicKey import RSA
8+ from jwcrypto .jwk import JWK , InvalidJWKType
9+ from jwt import encode as jwt_encode
910
1011
1112class JWT ():
@@ -63,32 +64,36 @@ def get_PEM_JWK(private_key):
6364 # if string repr, convert to dict object
6465 if isinstance (private_key , str ):
6566 private_key = literal_eval (private_key )
66- # Create JWK using dict obj
67- my_jwk = jwk .construct (private_key , JWT .HASH_ALGORITHM )
67+ # remove whitespace from key vaules
68+ private_key = {k : '' .join (private_key [k ].split ()) for k in private_key }
69+ # ensure private_key is JSON formatted
70+ try :
71+ json .loads (private_key )
72+ except TypeError :
73+ private_key = json .dumps (private_key )
74+ try :
75+ my_jwk = JWK .from_json (private_key )
76+ except InvalidJWKType :
77+ raise ValueError (
78+ "JWK given is of the wrong type" )
6879 else : # it's a PEM
6980 # check for filepath or explicit private key
7081 if isinstance (private_key , (str , bytes , os .PathLike )) and os .path .exists (private_key ):
71- # open file if exists and import key
82+ # open file if exists and read
7283 pem_file = open (private_key , 'r' )
73- my_pem = RSA . import_key ( pem_file .read () )
84+ private_key = pem_file .read ()
7485 pem_file .close ()
75- else :
76- # convert given string to bytes and import key
77- private_key_bytes = bytes (private_key , 'ascii' )
78- my_pem = RSA .import_key (private_key_bytes )
79-
80- if not my_pem :
81- # return error if import failed
82- return (None , ValueError (
83- "RSA Private Key given is of the wrong type" ))
84-
85- if my_jwk : # was JWK provided
86- # get PEM using JWK
87- pem_bytes = my_jwk .to_pem (JWT .PEM_FORMAT )
88- my_pem = RSA .import_key (pem_bytes )
89- else : # was pem provided
90- # get JWK using PEM
91- my_jwk = jwk .construct (my_pem .export_key (), JWT .HASH_ALGORITHM )
86+ # remove leading whitespaces from each line
87+ my_pem = '\n ' .join ([line .strip () for line in private_key .splitlines ()])
88+ my_pem = bytes (my_pem , 'ascii' )
89+ try :
90+ my_jwk = JWK .from_pem (my_pem )
91+ except ValueError :
92+ raise ValueError (
93+ "RSA Private Key given is of the wrong type" )
94+
95+ my_pem = my_jwk .export_to_pem (private_key = True , password = None )
96+ my_pem = RSA .import_key (my_pem )
9297
9398 return (my_pem , my_jwk )
9499
@@ -108,7 +113,7 @@ def create_token(org_url, client_id, private_key, kid=None):
108113 str: Generated JWT
109114 """
110115 # Generate PEM and JWK
111- my_pem , my_jwk = JWT .get_PEM_JWK (private_key )
116+ my_pem , _ = JWT .get_PEM_JWK (private_key )
112117 # Get current time and expiry time for token
113118 issued_time = int (time .time ())
114119 expiry_time = issued_time + JWT .ONE_HOUR
@@ -142,5 +147,5 @@ def create_token(org_url, client_id, private_key, kid=None):
142147 if "kid" in headers :
143148 del headers ["kid" ]
144149
145- token = jwt . encode (claims , my_jwk . to_dict (), JWT .HASH_ALGORITHM , headers = headers )
150+ token = jwt_encode (claims , my_pem . export_key (), JWT .HASH_ALGORITHM , headers )
146151 return token
0 commit comments