def setUp(self): self.con = Mock() self._method = SCRAM_SHA_1(self.con, None) self._method._client_nonce = 'fyko+d2lbbFgONRv9qkxdawL' self.maxDiff = None self._username = '******' self._password = '******' self.auth = '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="SCRAM-SHA-1">%s</auth>' % b64encode('n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL') self.challenge = b64encode('r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096') self.response = '<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">%s</response>' % b64encode('c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=') self.success = b64encode('v=rmF9pqV8S7suAoZWja4dJRkFsKQ=')
def create_omemo_message(stanza, omemo_message, store_hint=True, node_whitelist=None): ''' <message> <encrypted xmlns='eu.siacs.conversations.axolotl'> <header sid='27183'> <key rid='31415'>BASE64ENCODED...</key> <key prekey="true" rid='12321'>BASE64ENCODED...</key> <!-- ... --> <iv>BASE64ENCODED...</iv> </header> <payload>BASE64ENCODED</payload> </encrypted> <store xmlns='urn:xmpp:hints'/> </message> ''' if node_whitelist is not None: cleanup_stanza(stanza, node_whitelist) encrypted = Node('encrypted', attrs={'xmlns': Namespace.OMEMO_TEMP}) header = Node('header', attrs={'sid': omemo_message.sid}) for rid, (key, prekey) in omemo_message.keys.items(): attrs = {'rid': rid} if prekey: attrs['prekey'] = 'true' child = header.addChild('key', attrs=attrs) child.addData(b64encode(key)) header.addChild('iv').addData(b64encode(omemo_message.iv)) encrypted.addChild(node=header) payload = encrypted.addChild('payload') payload.addData(b64encode(omemo_message.payload)) stanza.addChild(node=encrypted) stanza.addChild(node=Node('encryption', attrs={ 'xmlns': Namespace.EME, 'name': 'OMEMO', 'namespace': Namespace.OMEMO_TEMP })) stanza.setBody("You received a message encrypted with " "OMEMO but your client doesn't support OMEMO.") if store_hint: stanza.addChild(node=Node('store', attrs={'xmlns': Namespace.HINTS}))
def _make_bundle(bundle): ''' <publish node='eu.siacs.conversations.axolotl.bundles:31415'> <item id='current'> <bundle xmlns='eu.siacs.conversations.axolotl'> <signedPreKeyPublic signedPreKeyId='1'> BASE64ENCODED... </signedPreKeyPublic> <signedPreKeySignature> BASE64ENCODED... </signedPreKeySignature> <identityKey> BASE64ENCODED... </identityKey> <prekeys> <preKeyPublic preKeyId='1'> BASE64ENCODED... </preKeyPublic> <preKeyPublic preKeyId='2'> BASE64ENCODED... </preKeyPublic> <preKeyPublic preKeyId='3'> BASE64ENCODED... </preKeyPublic> <!-- ... --> </prekeys> </bundle> </item> </publish> ''' bundle_node = Node('bundle', attrs={'xmlns': Namespace.OMEMO_TEMP}) prekey_pub_node = bundle_node.addChild( 'signedPreKeyPublic', attrs={'signedPreKeyId': bundle.spk['id']}) prekey_pub_node.addData(b64encode(bundle.spk['key'])) prekey_sig_node = bundle_node.addChild('signedPreKeySignature') prekey_sig_node.addData(b64encode(bundle.spk_signature)) identity_key_node = bundle_node.addChild('identityKey') identity_key_node.addData(b64encode(bundle.ik)) prekeys = bundle_node.addChild('prekeys') for key in bundle.otpks: pre_key_public = prekeys.addChild('preKeyPublic', attrs={'preKeyId': key['id']}) pre_key_public.addData(b64encode(key['key'])) return bundle_node
def get_key_transport_message(typ, jid, omemo_message): message = Message(typ=typ, to=jid) encrypted = Node('encrypted', attrs={'xmlns': Namespace.OMEMO_TEMP}) header = Node('header', attrs={'sid': omemo_message.sid}) for rid, (key, prekey) in omemo_message.keys.items(): attrs = {'rid': rid} if prekey: attrs['prekey'] = 'true' child = header.addChild('key', attrs=attrs) child.addData(b64encode(key)) header.addChild('iv').addData(b64encode(omemo_message.iv)) encrypted.addChild(node=header) message.addChild(node=encrypted) return message
def set_avatar(self, avatar, type_=None): avatar = b64encode(avatar) if 'PHOTO' not in self.data: self.data['PHOTO'] = {} self.data['PHOTO']['BINVAL'] = avatar if type_ is not None: self.data['PHOTO']['TYPE'] = type_
def initiate(self, username, server): payload = b64encode('%s@%s' % (username, server)) node = Node('auth', attrs={ 'xmlns': Namespace.SASL, 'mechanism': 'EXTERNAL' }, payload=[payload]) self._client.send_nonza(node)
def initiate(self, username, password): payload = b64encode('\x00%s\x00%s' % (username, password)) node = Node('auth', attrs={ 'xmlns': Namespace.SASL, 'mechanism': 'PLAIN' }, payload=[payload]) self._client.send_nonza(node)
def response(self, server_first_message): server_first_message = b64decode(server_first_message) challenge = self._scram_parse(server_first_message) client_nonce = challenge['r'][:self.nonce_length] if client_nonce != self._client_nonce: raise AuthFail('Invalid client nonce received from server') salt = b64decode(challenge['s'], bytes) iteration_count = int(challenge['i']) if iteration_count < 4096: raise AuthFail('Salt iteration count to low: %s' % iteration_count) salted_password = pbkdf2_hmac(self._hash_method, self._password.encode('utf8'), salt, iteration_count) client_final_message_wo_proof = 'c=%s,r=%s' % ( self._b64_channel_binding_data, challenge['r']) client_key = self._hmac(salted_password, 'Client Key') stored_key = self._h(client_key) auth_message = '%s,%s,%s' % (self._client_first_message_bare, server_first_message, client_final_message_wo_proof) client_signature = self._hmac(stored_key, auth_message) client_proof = self._xor(client_key, client_signature) client_finale_message = 'c=%s,r=%s,p=%s' % ( self._b64_channel_binding_data, challenge['r'], b64encode(client_proof)) server_key = self._hmac(salted_password, 'Server Key') self._server_signature = self._hmac(server_key, auth_message) payload = b64encode(client_finale_message) node = Node('response', attrs={'xmlns': Namespace.SASL}, payload=[payload]) self._client.send_nonza(node)
def initiate(self, username, password): self._password = password self._client_first_message_bare = 'n=%s,r=%s' % (username, self._client_nonce) client_first_message = '%s%s' % (self._channel_binding, self._client_first_message_bare) payload = b64encode(client_first_message) node = Node('auth', attrs={ 'xmlns': Namespace.SASL, 'mechanism': self._mechanism }, payload=[payload]) self._client.send_nonza(node)
def create_message_stanza(stanza, encrypted_payload, with_fallback_text): b64encoded_payload = b64encode(encrypted_payload) openpgp_node = Node('openpgp', attrs={'xmlns': Namespace.OPENPGP}) openpgp_node.addData(b64encoded_payload) stanza.addChild(node=openpgp_node) eme_node = Node('encryption', attrs={ 'xmlns': Namespace.EME, 'namespace': Namespace.OPENPGP }) stanza.addChild(node=eme_node) if with_fallback_text: stanza.setBody( '[This message is *encrypted* with OpenPGP (See :XEP:`0373`]')
def response(self, server_message, *args, **kwargs): server_message = b64decode(server_message, bytes) try: if not self.ctx.complete: output_token = self.ctx.step(server_message) else: result = self.ctx.unwrap(server_message) # TODO(jelmer): Log result.message data = b'\x00\x00\x00\x00' + bytes(self.ctx.initiator_name) output_token = self.ctx.wrap(data, False).message except (gssapi.exceptions.GeneralError, gssapi.raw.misc.GSSError) as e: raise AuthFail(e) response = b64encode(output_token) node = Node('response', attrs={'xmlns': Namespace.SASL}, payload=response) self._client.send_nonza(node)
def initiate(self, hostname): service = gssapi.Name('xmpp@%s' % hostname, name_type=gssapi.NameType.hostbased_service) try: self.ctx = gssapi.SecurityContext( name=service, usage="initiate", flags=gssapi.RequirementFlag.integrity) token = self.ctx.step() except (gssapi.exceptions.GeneralError, gssapi.raw.misc.GSSError) as e: raise AuthFail(e) node = Node('auth', attrs={ 'xmlns': Namespace.SASL, 'mechanism': 'GSSAPI' }, payload=b64encode(token)) self._client.send_nonza(node)
def _make_secret_key(secret_key): item = Node('secretkey', {'xmlns': Namespace.OPENPGP}) if secret_key is not None: item.setData(b64encode(secret_key)) return item
def _make_public_key(key, date): date = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(date)) item = Node('pubkey', attrs={'xmlns': Namespace.OPENPGP, 'date': date}) data = item.addChild('data') data.addData(b64encode(key)) return item
def _make_avatar_data_node(avatar): item = Node('data', attrs={'xmlns': Namespace.AVATAR_DATA}) item.setData(b64encode(avatar.data)) return item
def _b64_channel_binding_data(self): if self._mechanism.endswith('PLUS'): return b64encode( b'%s%s' % (self._channel_binding.encode(), self._channel_binding_data)) return b64encode(self._channel_binding)