def decrypt(self, body): ''' :param body: Body message to be 1) decrypted and 2) check for correct signature. **REQUIRED** :returns: Decrypted body message ''' jweKeySet = self.__getJwkKeySet( location=self.clientPrivateKeySetLocation) jwkDecryptKey = self.__findJwkKeyByAlgorithm( jwkKeySet=jweKeySet, algorithm=self.encryptionAlgorithm) privateKeyToDecrypt = jwk.JWK(**jwkDecryptKey) jweToken = jwe.JWE() try: jweToken.deserialize(body, key=privateKeyToDecrypt) except Exception as e: raise HyperwalletException(str(e)) payload = jweToken.payload self.checkJwsExpiration(payload) jwsKeySet = self.__getJwkKeySet( location=self.hyperwalletKeySetLocation) jwkCheckSignKey = self.__findJwkKeyByAlgorithm( jwkKeySet=jwsKeySet, algorithm=self.signAlgorithm) try: return jws.verify(payload, json.dumps(jwkCheckSignKey), algorithms=self.signAlgorithm) except Exception as e: raise HyperwalletException(str(e))
def __checkJwsExpiration(self, payload): ''' Check if JWS signature has not expired. ''' header = jws.get_unverified_header(payload) if 'exp' not in header: raise HyperwalletException('While trying to verify JWS signature no [exp] header is found') exp = header['exp'] if not isinstance(exp, (int, long)): raise HyperwalletException('Wrong value in [exp] header of JWS signature, must be integer') if exp < int(time.time()): raise HyperwalletException('JWS signature has expired, checked by [exp] JWS header')
def __getJwkKeySet(self, location): ''' Retrieves JWK key data from given location. :param location: Location(can be a URL or path to file) of JWK key data. **REQUIRED** :returns: JWK key set found at given location. ''' try: url = urlparse(location) if url.scheme and url.netloc and url.path: return requests.get(location).text raise HyperwalletException('Failed to parse url from string = ' + location) except Exception as e: if os.path.isfile(location): with open(location) as f: return f.read() else: raise HyperwalletException('Wrong JWK key set location path = ' + location)
def __findJwkKeyByAlgorithm(self, jwkKeySet, algorithm): ''' Finds JWK key by given algorithm. :param jwkKeySet: JSON representation of JWK key set. **REQUIRED** :param algorithm: Algorithm of the JWK key to be found in key set. **REQUIRED** :returns: JWK key with given algorithm. ''' try: keySet = json.loads(jwkKeySet) except ValueError as e: raise HyperwalletException('Wrong JWK key set' + jwkKeySet) for key in keySet['keys']: if key['alg'] == algorithm: return key raise HyperwalletException('No JWK key found with algorithm = ' + algorithm)
def __getJwkKeySet(self, location): ''' Retrieves JWK key data from given location. :param location: Location(can be a URL or path to file) of JWK key data. **REQUIRED** :returns: JWK key set found at given location. ''' try: URLValidator()(location) except ValidationError, e: if os.path.isfile(location): with open(location) as f: return f.read() else: raise HyperwalletException('Wrong client JWK set location')