def negotiate_e2e(self, sigmai): self.negotiated = {} request = xmpp.Message() feature = request.NT.feature feature.setNamespace(xmpp.NS_FEATURE) x = xmpp.DataForm(typ="form") x.addChild(node=xmpp.DataField(name="FORM_TYPE", value="urn:xmpp:ssn", typ="hidden")) x.addChild(node=xmpp.DataField(name="accept", value="1", typ="boolean", required=True)) # this field is incorrectly called 'otr' in XEPs 0116 and 0217 x.addChild( node=xmpp.DataField(name="logging", typ="list-single", options=self.logging_preference(), required=True) ) # unsupported options: 'disabled', 'enabled' x.addChild(node=xmpp.DataField(name="disclosure", typ="list-single", options=["never"], required=True)) x.addChild(node=xmpp.DataField(name="security", typ="list-single", options=["e2e"], required=True)) x.addChild(node=xmpp.DataField(name="crypt_algs", value="aes128-ctr", typ="hidden")) x.addChild(node=xmpp.DataField(name="hash_algs", value="sha256", typ="hidden")) x.addChild(node=xmpp.DataField(name="compress", value="none", typ="hidden")) # unsupported options: 'iq', 'presence' x.addChild(node=xmpp.DataField(name="stanzas", typ="list-multi", options=["message"])) x.addChild(node=xmpp.DataField(name="init_pubkey", options=["none", "key", "hash"], typ="list-single")) # XXX store key, use hash x.addChild(node=xmpp.DataField(name="resp_pubkey", options=["none", "key"], typ="list-single")) x.addChild(node=xmpp.DataField(name="ver", value="1.0", typ="hidden")) x.addChild(node=xmpp.DataField(name="rekey_freq", value="4294967295", typ="hidden")) x.addChild(node=xmpp.DataField(name="sas_algs", value="sas28x5", typ="hidden")) x.addChild( node=xmpp.DataField(name="sign_algs", value="http://www.w3.org/2000/09/xmldsig#rsa-sha256", typ="hidden") ) self.n_s = crypto.generate_nonce() x.addChild(node=xmpp.DataField(name="my_nonce", value=base64.b64encode(self.n_s), typ="hidden")) modp_options = [int(g) for g in gajim.config.get("esession_modp").split(",")] x.addChild(node=xmpp.DataField(name="modp", typ="list-single", options=map(lambda x: [None, x], modp_options))) x.addChild(node=self.make_dhfield(modp_options, sigmai)) self.sigmai = sigmai self.form_s = "".join(map(lambda el: xmpp.c14n.c14n(el), x.getChildren())) feature.addChild(node=x) self.status = "requested-e2e" self.send(request)
def respond_e2e_bob(self, form, negotiated, not_acceptable): response = xmpp.Message() feature = response.NT.feature feature.setNamespace(xmpp.NS_FEATURE) x = xmpp.DataForm(typ='submit') x.addChild(node=xmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn')) x.addChild(node=xmpp.DataField(name='accept', value='true')) for name in negotiated: # some fields are internal and should not be sent if not name in ('send_pubkey', 'recv_pubkey'): x.addChild( node=xmpp.DataField(name=name, value=negotiated[name])) self.negotiated = negotiated # the offset of the group we chose (need it to match up with the dhhash) group_order = 0 self.modp = int(form.getField('modp').getOptions()[group_order][1]) x.addChild(node=xmpp.DataField(name='modp', value=self.modp)) g = dh.generators[self.modp] p = dh.primes[self.modp] self.n_o = base64.b64decode(form['my_nonce']) dhhashes = form.getField('dhhashes').getValues() self.negotiated['He'] = base64.b64decode( dhhashes[group_order].encode('utf8')) bytes = int(self.n / 8) self.n_s = crypto.generate_nonce() # n-bit random number self.c_o = crypto.decode_mpi(crypto.random_bytes(bytes)) self.c_s = self.c_o ^ (2**(self.n - 1)) self.y = crypto.srand(2**(2 * self.n - 1), p - 1) self.d = crypto.powmod(g, self.y, p) to_add = { 'my_nonce': self.n_s, 'dhkeys': crypto.encode_mpi(self.d), 'counter': crypto.encode_mpi(self.c_o), 'nonce': self.n_o } for name in to_add: b64ed = base64.b64encode(to_add[name]) x.addChild(node=xmpp.DataField(name=name, value=b64ed)) self.form_o = ''.join( map(lambda el: xmpp.c14n.c14n(el), form.getChildren())) self.form_s = ''.join( map(lambda el: xmpp.c14n.c14n(el), x.getChildren())) self.status = 'responded-e2e' feature.addChild(node=x) if not_acceptable: response = xmpp.Error(response, xmpp.ERR_NOT_ACCEPTABLE) feature = xmpp.Node(xmpp.NS_FEATURE + ' feature') for f in not_acceptable: n = xmpp.Node('field') n['var'] = f feature.addChild(node=n) response.T.error.addChild(node=feature) self.send(response)
def negotiate_e2e(self, sigmai): self.negotiated = {} request = xmpp.Message() feature = request.NT.feature feature.setNamespace(xmpp.NS_FEATURE) x = xmpp.DataForm(typ='form') x.addChild(node=xmpp.DataField( name='FORM_TYPE', value='urn:xmpp:ssn', typ='hidden')) x.addChild(node=xmpp.DataField( name='accept', value='1', typ='boolean', required=True)) # this field is incorrectly called 'otr' in XEPs 0116 and 0217 x.addChild(node=xmpp.DataField(name='logging', typ='list-single', options=self.logging_preference(), required=True)) # unsupported options: 'disabled', 'enabled' x.addChild(node=xmpp.DataField(name='disclosure', typ='list-single', options=['never'], required=True)) x.addChild(node=xmpp.DataField( name='security', typ='list-single', options=['e2e' ], required=True)) x.addChild(node=xmpp.DataField( name='crypt_algs', value='aes128-ctr', typ='hidden')) x.addChild(node=xmpp.DataField( name='hash_algs', value='sha256', typ='hidden')) x.addChild( node=xmpp.DataField(name='compress', value='none', typ='hidden')) # unsupported options: 'iq', 'presence' x.addChild(node=xmpp.DataField( name='stanzas', typ='list-multi', options=['message'])) x.addChild(node=xmpp.DataField(name='init_pubkey', options=['none', 'key', 'hash'], typ='list-single')) # XXX store key, use hash x.addChild(node=xmpp.DataField( name='resp_pubkey', options=['none', 'key'], typ='list-single')) x.addChild(node=xmpp.DataField(name='ver', value='1.0', typ='hidden')) x.addChild(node=xmpp.DataField( name='rekey_freq', value='4294967295', typ='hidden')) x.addChild(node=xmpp.DataField( name='sas_algs', value='sas28x5', typ='hidden')) x.addChild(node=xmpp.DataField( name='sign_algs', value='http://www.w3.org/2000/09/xmldsig#rsa-sha256', typ='hidden')) self.n_s = crypto.generate_nonce() x.addChild(node=xmpp.DataField( name='my_nonce', value=base64.b64encode(self.n_s), typ='hidden')) modp_options = [ int(g) for g in gajim.config.get('esession_modp').split(',') ] x.addChild(node=xmpp.DataField(name='modp', typ='list-single', options=map(lambda x: [None, x], modp_options))) x.addChild(node=self.make_dhfield(modp_options, sigmai)) self.sigmai = sigmai self.form_s = ''.join( map(lambda el: xmpp.c14n.c14n(el), x.getChildren())) feature.addChild(node=x) self.status = 'requested-e2e' self.send(request)
def respond_e2e_bob(self, form, negotiated, not_acceptable): """ 4.3 esession response (bob) """ response = nbxmpp.Message() feature = response.NT.feature feature.setNamespace(nbxmpp.NS_FEATURE) x = nbxmpp.DataForm(typ='submit') x.addChild(node=nbxmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn')) x.addChild(node=nbxmpp.DataField(name='accept', value='true')) for name in negotiated: # some fields are internal and should not be sent if not name in ('send_pubkey', 'recv_pubkey'): x.addChild(node=nbxmpp.DataField(name=name, value=negotiated[name])) self.negotiated = negotiated # the offset of the group we chose (need it to match up with the dhhash) group_order = 0 modp_f = form.getField('modp') if not modp_f: return self.modp = int(modp_f.getOptions()[group_order][1]) x.addChild(node=nbxmpp.DataField(name='modp', value=self.modp)) g = dh.generators[self.modp] p = dh.primes[self.modp] self.n_o = base64.b64decode(form['my_nonce']) dhhashes_f = form.getField('dhhashes') if not dhhashes_f: return dhhashes = dhhashes_f.getValues() self.negotiated['He'] = base64.b64decode(dhhashes[group_order].encode( 'utf8')) bytes = int(self.n / 8) self.n_s = crypto.generate_nonce() # n-bit random number self.c_o = crypto.decode_mpi(crypto.random_bytes(bytes)) self.c_s = self.c_o ^ (2 ** (self.n - 1)) self.y = crypto.srand(2 ** (2 * self.n - 1), p - 1) self.d = crypto.powmod(g, self.y, p) to_add = {'my_nonce': self.n_s, 'dhkeys': crypto.encode_mpi(self.d), 'counter': crypto.encode_mpi(self.c_o), 'nonce': self.n_o} for name in to_add: b64ed = base64.b64encode(to_add[name]) x.addChild(node=nbxmpp.DataField(name=name, value=b64ed)) self.form_o = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for \ el in form.getChildren()) self.form_s = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for \ el in x.getChildren()) self.status = 'responded-e2e' feature.addChild(node=x) if not_acceptable: response = nbxmpp.Error(response, nbxmpp.ERR_NOT_ACCEPTABLE) feature = nbxmpp.Node(nbxmpp.NS_FEATURE + ' feature') for f in not_acceptable: n = nbxmpp.Node('field') n['var'] = f feature.addChild(node=n) response.T.error.addChild(node=feature) self.send(response)
def negotiate_e2e(self, sigmai): self.negotiated = {} request = nbxmpp.Message() feature = request.NT.feature feature.setNamespace(nbxmpp.NS_FEATURE) x = nbxmpp.DataForm(typ='form') x.addChild(node=nbxmpp.DataField(name='FORM_TYPE', value='urn:xmpp:ssn', typ='hidden')) x.addChild(node=nbxmpp.DataField(name='accept', value='1', typ='boolean', required=True)) # this field is incorrectly called 'otr' in XEPs 0116 and 0217 x.addChild(node=nbxmpp.DataField(name='logging', typ='list-single', options=self.logging_preference(), required=True)) # unsupported options: 'disabled', 'enabled' x.addChild(node=nbxmpp.DataField(name='disclosure', typ='list-single', options=['never'], required=True)) x.addChild(node=nbxmpp.DataField(name='security', typ='list-single', options=['e2e'], required=True)) x.addChild(node=nbxmpp.DataField(name='crypt_algs', value='aes128-ctr', typ='hidden')) x.addChild(node=nbxmpp.DataField(name='hash_algs', value='sha256', typ='hidden')) x.addChild(node=nbxmpp.DataField(name='compress', value='none', typ='hidden')) # unsupported options: 'iq', 'presence' x.addChild(node=nbxmpp.DataField(name='stanzas', typ='list-multi', options=['message'])) x.addChild(node=nbxmpp.DataField(name='init_pubkey', options=['none', 'key', 'hash'], typ='list-single')) # FIXME store key, use hash x.addChild(node=nbxmpp.DataField(name='resp_pubkey', options=['none', 'key'], typ='list-single')) x.addChild(node=nbxmpp.DataField(name='ver', value='1.0', typ='hidden')) x.addChild(node=nbxmpp.DataField(name='rekey_freq', value='4294967295', typ='hidden')) x.addChild(node=nbxmpp.DataField(name='sas_algs', value='sas28x5', typ='hidden')) x.addChild(node=nbxmpp.DataField(name='sign_algs', value='http://www.w3.org/2000/09/xmldsig#rsa-sha256', typ='hidden')) self.n_s = crypto.generate_nonce() x.addChild(node=nbxmpp.DataField(name='my_nonce', value=base64.b64encode(self.n_s), typ='hidden')) modp_options = [ int(g) for g in gajim.config.get('esession_modp').split( ',') ] x.addChild(node=nbxmpp.DataField(name='modp', typ='list-single', options=[[None, y] for y in modp_options])) x.addChild(node=self.make_dhfield(modp_options, sigmai)) self.sigmai = sigmai self.form_s = ''.join(nbxmpp.c14n.c14n(el, self._is_buggy_gajim()) for \ el in x.getChildren()) feature.addChild(node=x) self.status = 'requested-e2e' self.send(request)
def respond_e2e_bob(self, form, negotiated, not_acceptable): response = xmpp.Message() feature = response.NT.feature feature.setNamespace(xmpp.NS_FEATURE) x = xmpp.DataForm(typ="submit") x.addChild(node=xmpp.DataField(name="FORM_TYPE", value="urn:xmpp:ssn")) x.addChild(node=xmpp.DataField(name="accept", value="true")) for name in negotiated: # some fields are internal and should not be sent if not name in ("send_pubkey", "recv_pubkey"): x.addChild(node=xmpp.DataField(name=name, value=negotiated[name])) self.negotiated = negotiated # the offset of the group we chose (need it to match up with the dhhash) group_order = 0 self.modp = int(form.getField("modp").getOptions()[group_order][1]) x.addChild(node=xmpp.DataField(name="modp", value=self.modp)) g = dh.generators[self.modp] p = dh.primes[self.modp] self.n_o = base64.b64decode(form["my_nonce"]) dhhashes = form.getField("dhhashes").getValues() self.negotiated["He"] = base64.b64decode(dhhashes[group_order].encode("utf8")) bytes = int(self.n / 8) self.n_s = crypto.generate_nonce() # n-bit random number self.c_o = crypto.decode_mpi(crypto.random_bytes(bytes)) self.c_s = self.c_o ^ (2 ** (self.n - 1)) self.y = crypto.srand(2 ** (2 * self.n - 1), p - 1) self.d = crypto.powmod(g, self.y, p) to_add = { "my_nonce": self.n_s, "dhkeys": crypto.encode_mpi(self.d), "counter": crypto.encode_mpi(self.c_o), "nonce": self.n_o, } for name in to_add: b64ed = base64.b64encode(to_add[name]) x.addChild(node=xmpp.DataField(name=name, value=b64ed)) self.form_o = "".join(map(lambda el: xmpp.c14n.c14n(el), form.getChildren())) self.form_s = "".join(map(lambda el: xmpp.c14n.c14n(el), x.getChildren())) self.status = "responded-e2e" feature.addChild(node=x) if not_acceptable: response = xmpp.Error(response, xmpp.ERR_NOT_ACCEPTABLE) feature = xmpp.Node(xmpp.NS_FEATURE + " feature") for f in not_acceptable: n = xmpp.Node("field") n["var"] = f feature.addChild(node=n) response.T.error.addChild(node=feature) self.send(response)