def test_decrypt_bad_header(self): with assert_raises(ECEException) as ex: ece.decrypt( os.urandom(4), version='aes128gcm', key=self.m_key, ) eq_(ex.exception.message, "Could not parse the content header")
def test_decrypt_bad_version(self): with self.assertRaises(ECEException) as ex: ece.decrypt( self.m_input, version='bogus', key=self.m_key, ) self.assertEqual(ex.exception.message, "Invalid version")
def test_decrypt_small_rs(self): header = os.urandom(16) + struct.pack('!L', 2) + b'\0' with self.assertRaises(ECEException) as ex: ece.decrypt( header + self.m_input, version='aes128gcm', key=self.m_key, rs=1, ) self.assertEqual(ex.exception.message, "Record size too small")
def test_damage(self): with assert_raises(ECEException) as ex: ece.decrypt( self.m_header + b'\xbb\xc6\xb1\x1dF:~\x0f\x07+\xbe\xaaD\xe0\xd6.K\xe5\xf9]%\xe3\x86q\xe0}', version='aes128gcm', key=b'd\xc7\x0ed\xa7%U\x14Q\xf2\x08\xdf\xba\xa0\xb9r', keyid=b64e(os.urandom(192)), # 256 bytes ) eq_(ex.exception.message, "Decryption error: InvalidTag()")
def test_bad_final_delimiter(self): with self.assertRaises(ECEException) as ex: ece.decrypt( self.m_header + b'\xba\xc7\xb9ev\x0b\xf0\x9eB\xb1\x08Ji' b'\xe4P\x1b\x8dI\xdb\xc6y#MG\xc2W\x16', version='aes128gcm', key=b'd\xc7\x0ed\xa7%U\x14Q\xf2\x08\xdf\xba\xa0\xb9r', keyid=b64e(os.urandom(192)), # 256 bytes ) self.assertEqual(ex.exception.message, "last record delimiter != 2")
def test_overlong_padding(self): with self.assertRaises(ECEException) as ex: ece.decrypt( self.m_header + b'\xbb\xc7\xb9ev\x0b\xf0f+\x93\xf4' b'\xe5\xd6\x94\xb7e\xf0\xcd\x15\x9b(\x01\xa5', version='aes128gcm', key=b'd\xc7\x0ed\xa7%U\x14Q\xf2\x08\xdf\xba\xa0\xb9r', keyid=b64e(os.urandom(192)), # 256 bytes ) self.assertEqual(ex.exception.message, "all zero record plaintext")
def test_bad_early_delimiter(self): with assert_raises(ECEException) as ex: ece.decrypt( self.m_header + b'\xb9\xc7\xb9ev\x0b\xf0\x9eB\xb1\x08C8u\xa3\x06\xc9x\x06\n\xfc|}\xe9R\x85\x91\x8bX\x02`\xf3' + b'E8z(\xe5%f/H\xc1\xc32\x04\xb1\x95\xb5N\x9ep\xd4\x0e<\xf3\xef\x0cg\x1b\xe0\x14I~\xdc', version='aes128gcm', key=b'd\xc7\x0ed\xa7%U\x14Q\xf2\x08\xdf\xba\xa0\xb9r', keyid=b64e(os.urandom(192)), # 256 bytes ) eq_(ex.exception.message, "record delimiter != 1")
def test_encode(self): for content_encoding in ["aesgcm", "aes128gcm"]: recv_key = ec.generate_private_key( ec.SECP256R1, default_backend()) subscription_info = self._gen_subscription_info(recv_key) data = "Mary had a little lamb, with some nice mint jelly" push = WebPusher(subscription_info) encoded = push.encode(data, content_encoding=content_encoding) """ crypto_key = base64.urlsafe_b64encode( self._get_pubkey_str(recv_key) ).strip(b'=') """ # Convert these b64 strings into their raw, binary form. raw_salt = None if 'salt' in encoded: raw_salt = base64.urlsafe_b64decode( push._repad(encoded['salt'])) raw_dh = None if content_encoding != "aes128gcm": raw_dh = base64.urlsafe_b64decode( push._repad(encoded['crypto_key'])) raw_auth = base64.urlsafe_b64decode( push._repad(subscription_info['keys']['auth'])) decoded = http_ece.decrypt( encoded['body'], salt=raw_salt, dh=raw_dh, private_key=recv_key, auth_secret=raw_auth, version=content_encoding ) eq_(decoded.decode('utf8'), data)
def test_encode(self): recv_key = pyelliptic.ECC(curve="prime256v1") subscription_info = self._gen_subscription_info(recv_key) data = "Mary had a little lamb, with some nice mint jelly" push = WebPusher(subscription_info) encoded = push.encode(data) keyid = base64.urlsafe_b64encode(recv_key.get_pubkey()[1:]) http_ece.keys[keyid] = recv_key http_ece.labels[keyid] = 'P-256' # Convert these b64 strings into their raw, binary form. raw_salt = base64.urlsafe_b64decode(push._repad(encoded['salt'])) raw_dh = base64.urlsafe_b64decode(push._repad(encoded['crypto_key'])) raw_auth = base64.urlsafe_b64decode( push._repad(subscription_info['keys']['auth'])) decoded = http_ece.decrypt( buffer=encoded['body'], salt=raw_salt, dh=raw_dh, keyid=keyid, authSecret=raw_auth ) eq_(decoded, data)
def test_encode(self): for content_encoding in ["aesgcm", "aes128gcm"]: recv_key = ec.generate_private_key(ec.SECP256R1, default_backend()) subscription_info = self._gen_subscription_info(recv_key) data = "Mary had a little lamb, with some nice mint jelly" push = WebPusher(subscription_info) encoded = push.encode(data, content_encoding=content_encoding) """ crypto_key = base64.urlsafe_b64encode( self._get_pubkey_str(recv_key) ).strip(b'=') """ # Convert these b64 strings into their raw, binary form. raw_salt = None if 'salt' in encoded: raw_salt = base64.urlsafe_b64decode( push._repad(encoded['salt'])) raw_dh = base64.urlsafe_b64decode( push._repad(encoded['crypto_key'])) raw_auth = base64.urlsafe_b64decode( push._repad(subscription_info['keys']['auth'])) decoded = http_ece.decrypt(encoded['body'], salt=raw_salt, dh=raw_dh, private_key=recv_key, auth_secret=raw_auth, version=content_encoding) eq_(decoded.decode('utf8'), data)
def test_encode(self): recv_key = pyelliptic.ECC(curve="prime256v1") subscription_info = self._gen_subscription_info(recv_key) data = "Mary had a little lamb, with some nice mint jelly" push = WebPusher(subscription_info) encoded = push.encode(data) keyid = base64.urlsafe_b64encode(recv_key.get_pubkey()[1:]) http_ece.keys[keyid] = recv_key http_ece.labels[keyid] = 'P-256' # Convert these b64 strings into their raw, binary form. raw_salt = base64.urlsafe_b64decode(push._repad(encoded['salt'])) raw_dh = base64.urlsafe_b64decode(push._repad(encoded['crypto_key'])) raw_auth = base64.urlsafe_b64decode( push._repad(subscription_info['keys']['auth'])) decoded = http_ece.decrypt(buffer=encoded['body'], salt=raw_salt, dh=raw_dh, keyid=keyid, authSecret=raw_auth) eq_(decoded.decode('utf8'), data)
def encryptDecrypt(length, encryptParams, decryptParams=None): if decryptParams is None: decryptParams = encryptParams if "key" in encryptParams: logbuf("Key", encryptParams["key"]); logbuf("Salt", encryptParams["salt"]) if "authSecret" in encryptParams: logbuf("Context", encryptParams["authSecret"]) input = os.urandom(min(length, maxLen)) # input = new Buffer("I am the walrus") logbuf("Input", input) encrypted = ece.encrypt(input, salt=encryptParams.get("salt"), key=encryptParams.get("key"), keyid=encryptParams.get("keyid"), dh=encryptParams.get("dh"), rs=encryptParams.get("rs"), authSecret=encryptParams.get("authSecret")) logbuf("Encrypted", encrypted) decrypted = ece.decrypt(encrypted, salt=decryptParams.get("salt"), key=decryptParams.get("key"), keyid=decryptParams.get("keyid"), dh=decryptParams.get("dh"), rs=decryptParams.get("rs"), authSecret=decryptParams.get("authSecret")) logbuf("Decrypted", decrypted) assert input == decrypted log("----- OK");
def detectTruncation(): length = min(rlen(), maxLen) key = os.urandom(16) salt = os.urandom(16) rs = length + 2 input = os.urandom(min(length, maxLen)) encrypted = ece.encrypt(input, salt=salt, key=key, rs=rs) ok = False try: ece.decrypt(encrypted[0:length + 2 + 16], salt=salt, key=key, rs=rs) except Exception as e: log("Decryption error: %s" % e.args) log("----- OK") ok = True if not ok: raise Exception("Decryption succeeded, but should not have")
def detect_truncation(self, version): if version == "aes128gcm": return input = self._generate_input(2) key = os.urandom(16) salt = os.urandom(16) rs = len(input) + self._rsoverhead(version) - 1 encrypted = ece.encrypt(input, salt=salt, key=key, rs=rs, version=version) if version == 'aes128gcm': chunk = encrypted[0:21 + rs] else: chunk = encrypted[0:rs + 16] with self.assertRaises(ECEException) as ex: ece.decrypt(chunk, salt=salt, key=key, rs=rs, version=version) self.assertEqual(ex.exception.message, "Message truncated")
def encrypt_decrypt(self, input, encrypt_params, decrypt_params=None, version=None): """Run and encrypt/decrypt cycle on some test data :param input: data for input :type length: bytearray :param encrypt_params: Dictionary of encryption parameters :type encrypt_params: dict :param decrypt_params: Optional dictionary of decryption parameters :type decrypt_params: dict :param version: Content-Type of the body, formulating encryption :type enumerate("aes128gcm", "aesgcm", "aesgcm128"): """ if decrypt_params is None: decrypt_params = encrypt_params logbuf("Input", input) if "key" in encrypt_params: logbuf("Key", encrypt_params["key"]) if version != "aes128gcm": salt = os.urandom(16) decrypt_rs_default = 4096 else: salt = None decrypt_rs_default = None logbuf("Salt", salt) if "auth_secret" in encrypt_params: logbuf("Auth Secret", encrypt_params["auth_secret"]) encrypted = ece.encrypt(input, salt=salt, key=encrypt_params.get("key"), keyid=encrypt_params.get("keyid"), dh=encrypt_params.get("dh"), private_key=encrypt_params.get("private_key"), auth_secret=encrypt_params.get("auth_secret"), rs=encrypt_params.get("rs", 4096), version=version) logbuf("Encrypted", encrypted) decrypted = ece.decrypt(encrypted, salt=salt, key=decrypt_params.get("key"), keyid=decrypt_params.get("keyid"), dh=decrypt_params.get("dh"), private_key=decrypt_params.get("private_key"), auth_secret=decrypt_params.get("auth_secret"), rs=decrypt_params.get("rs", decrypt_rs_default), version=version) logbuf("Decrypted", decrypted) self.assertEqual(input, decrypted)
def __listen(s, credentials, callback, persistent_ids, obj): import http_ece import cryptography.hazmat.primitives.serialization as serialization from cryptography.hazmat.backends import default_backend load_der_private_key = serialization.load_der_private_key gcm_check_in(**credentials["gcm"]) req = LoginRequest() req.adaptive_heartbeat = False req.auth_service = 2 req.auth_token = credentials["gcm"]["securityToken"] req.id = "chrome-63.0.3234.0" req.domain = "mcs.android.com" req.device_id = "android-%x" % int(credentials["gcm"]["androidId"]) req.network_type = 1 req.resource = credentials["gcm"]["androidId"] req.user = credentials["gcm"]["androidId"] req.use_rmq2 = True req.setting.add(name="new_vc", value="1") req.received_persistent_id.extend(persistent_ids) __send(s, req) login_response = __recv(s, first=True) while True: p = __recv(s) if type(p) is not DataMessageStanza: continue crypto_key = __app_data_by_key(p, "crypto-key")[3:] # strip dh= salt = __app_data_by_key(p, "encryption")[5:] # strip salt= crypto_key = urlsafe_b64decode(crypto_key.encode("ascii")) salt = urlsafe_b64decode(salt.encode("ascii")) der_data = credentials["keys"]["private"] der_data = urlsafe_b64decode(der_data.encode("ascii") + b"========") secret = credentials["keys"]["secret"] secret = urlsafe_b64decode(secret.encode("ascii") + b"========") privkey = load_der_private_key( der_data, password=None, backend=default_backend() ) decrypted = http_ece.decrypt( p.raw_data, salt=salt, private_key=privkey, dh=crypto_key, version="aesgcm", auth_secret=secret ) callback(obj, json.loads(decrypted.decode("utf-8")), p)
def encryptDecrypt(length, encryptParams, decryptParams=None): if decryptParams is None: decryptParams = encryptParams log('Salt: ' + b64e(encryptParams['salt'])) input = os.urandom(min(length, maxLen)) # input = new Buffer('I am the walrus') log('Input: ' + b64e(input)) encrypted = ece.encrypt(input, salt=encryptParams.get('salt'), key=encryptParams.get('key'), keyid=encryptParams.get('keyid'), dh=encryptParams.get('dh'), rs=encryptParams.get('rs')) log('Encrypted: ' + b64e(encrypted)) decrypted = ece.decrypt(encrypted, salt=decryptParams.get('salt'), key=decryptParams.get('key'), keyid=decryptParams.get('keyid'), dh=decryptParams.get('dh'), rs=decryptParams.get('rs')) log('Decrypted: ' + b64e(decrypted)) assert input == decrypted log("----- OK");