aboutsummaryrefslogtreecommitdiff
path: root/pandora/transport.py
diff options
context:
space:
mode:
Diffstat (limited to 'pandora/transport.py')
-rw-r--r--pandora/transport.py46
1 files changed, 2 insertions, 44 deletions
diff --git a/pandora/transport.py b/pandora/transport.py
index 0174eac..6f1a174 100644
--- a/pandora/transport.py
+++ b/pandora/transport.py
@@ -13,16 +13,12 @@ import random
13import time 13import time
14import json 14import json
15import base64 15import base64
16import blowfish
16import requests 17import requests
17from requests.adapters import HTTPAdapter 18from requests.adapters import HTTPAdapter
18 19
19from .errors import PandoraException 20from .errors import PandoraException
20 21
21try:
22 import blowfish
23except ImportError:
24 blowfish = None
25
26 22
27DEFAULT_API_HOST = "tuner.pandora.com/services/json/" 23DEFAULT_API_HOST = "tuner.pandora.com/services/json/"
28 24
@@ -272,40 +268,6 @@ class BlowfishCryptor(object):
272 return data[:-pad_size] 268 return data[:-pad_size]
273 269
274 270
275class CryptographyBlowfish(BlowfishCryptor):
276 """Cryptography Blowfish Cryptor
277
278 Uses the python cryptography library which wraps OpenSSL. Compatible with
279 both Python 2 and 3 but requires a native dependency.
280 """
281
282 def __init__(self, key):
283 from cryptography.hazmat.backends import default_backend
284 from cryptography.hazmat.primitives.ciphers import Cipher
285 from cryptography.hazmat.primitives.ciphers.modes import ECB
286 from cryptography.hazmat.primitives.ciphers.algorithms import Blowfish
287
288 self.cipher = Cipher(
289 Blowfish(key.encode("ascii")), ECB(), backend=default_backend())
290
291 def _make_bytearray(self, data):
292 return bytearray(len(data) + (self.block_size - 1))
293
294 def decrypt(self, data, strip_padding=True):
295 buf = self._make_bytearray(data)
296 dec = self.cipher.decryptor()
297 len_dec = dec.update_into(data, buf)
298 data = bytes(buf[:len_dec]) + dec.finalize()
299 return self._strip_padding(data) if strip_padding else data
300
301 def encrypt(self, data):
302 data = self._add_padding(data)
303 enc = self.cipher.encryptor()
304 buf = self._make_bytearray(data)
305 len_enc = enc.update_into(data, buf)
306 return bytes(buf[:len_enc]) + enc.finalize()
307
308
309class PurePythonBlowfish(BlowfishCryptor): 271class PurePythonBlowfish(BlowfishCryptor):
310 """Pure Python 3 Blowfish Cryptor 272 """Pure Python 3 Blowfish Cryptor
311 273
@@ -323,10 +285,6 @@ class PurePythonBlowfish(BlowfishCryptor):
323 return b"".join(self.cipher.encrypt_ecb(self._add_padding(data))) 285 return b"".join(self.cipher.encrypt_ecb(self._add_padding(data)))
324 286
325 287
326# Python 3 users can use pure-python mode, if possible prefer that as default
327_default_crypto = PurePythonBlowfish if blowfish else CryptographyBlowfish
328
329
330class Encryptor(object): 288class Encryptor(object):
331 """Pandora Blowfish Encryptor 289 """Pandora Blowfish Encryptor
332 290
@@ -334,7 +292,7 @@ class Encryptor(object):
334 API request and response. It handles the formats that the API expects. 292 API request and response. It handles the formats that the API expects.
335 """ 293 """
336 294
337 def __init__(self, in_key, out_key, crypto_class=_default_crypto): 295 def __init__(self, in_key, out_key, crypto_class=PurePythonBlowfish):
338 self.bf_out = crypto_class(out_key) 296 self.bf_out = crypto_class(out_key)
339 self.bf_in = crypto_class(in_key) 297 self.bf_in = crypto_class(in_key)
340 298