Exemple #1
0
    def proof_equal_logs(self, v):
        r = bytes_to_long(RNG.read(192))
        temp1 = pow(self.g1, r, DH1536_MODULUS)
        temp2 = pow(self.qab, r, DH1536_MODULUS)

        cb = SHA256(struct.pack(b'B', v) + pack_mpi(temp1) + pack_mpi(temp2))
        c = bytes_to_long(cb)
        temp1 = self.x3 * c % SM_ORDER
        d = (r - temp1) % SM_ORDER
        return c, d
Exemple #2
0
    def gotSecret(self, secret, question=None, appdata=None):
        ourFP = self.crypto.ctx.user.getPrivkey().fingerprint()
        if self.state == 1:
            # first secret -> SMP1TLV
            combSecret = SHA256(b'\1' + ourFP +
                    self.crypto.theirPubkey.fingerprint() +
                    self.crypto.sessionId + secret)

            self.secret = bytes_to_long(combSecret)

            self.x2 = randrange(2, DH_MAX)
            self.x3 = randrange(2, DH_MAX)

            msg = [pow(self.g1, self.x2, DH_MODULUS)]
            msg += proof_known_log(self.g1, self.x2, 1)
            msg.append(pow(self.g1, self.x3, DH_MODULUS))
            msg += proof_known_log(self.g1, self.x3, 2)

            self.prog = SMPPROG_OK
            self.state = 2
            if question is None:
                self.sendTLV(proto.SMP1TLV(msg), appdata=appdata)
            else:
                self.sendTLV(proto.SMP1QTLV(question, msg), appdata=appdata)
        if self.state == 0:
            # response secret -> SMP2TLV
            combSecret = SHA256(b'\1' + self.crypto.theirPubkey.fingerprint() +
                    ourFP + self.crypto.sessionId + secret)

            self.secret = bytes_to_long(combSecret)

            msg = [pow(self.g1, self.x2, DH_MODULUS)]
            msg += proof_known_log(self.g1, self.x2, 3)
            msg.append(pow(self.g1, self.x3, DH_MODULUS))
            msg += proof_known_log(self.g1, self.x3, 4)

            r = randrange(2, DH_MAX)

            self.p = pow(self.g3, r, DH_MODULUS)
            msg.append(self.p)

            qb1 = pow(self.g1, r, DH_MODULUS)
            qb2 = pow(self.g2, self.secret, DH_MODULUS)
            self.q = qb1 * qb2 % DH_MODULUS
            msg.append(self.q)

            msg += self.proof_equal_coords(r, 5)

            self.state = 3
            self.sendTLV(proto.SMP2TLV(msg), appdata=appdata)
Exemple #3
0
	def gotSecret(self, secret, question=None, appdata=None):
		ourFP = self.crypto.ctx.user.getPrivkey().fingerprint()
		if self.state == 1:
			# first secret -> SMP1TLV
			combSecret = HASH(b'\1' + ourFP +
					self.crypto.theirPubkey.fingerprint() +
					self.crypto.sessionId + secret)

			self.secret = bytes_to_long(combSecret)

			self.x2 = random.randrange(2, DH_MAX)
			self.x3 = random.randrange(2, DH_MAX)

			msg = [pow(self.g1, self.x2, DH_MODULUS)]
			msg += proof_known_log(self.g1, self.x2, 1)
			msg.append(pow(self.g1, self.x3, DH_MODULUS))
			msg += proof_known_log(self.g1, self.x3, 2)

			self.prog = SMPPROG_OK
			self.state = 2
			if question is None:
				self.sendTLV(proto.SMP1TLV(msg), appdata=appdata)
			else:
				self.sendTLV(proto.SMP1QTLV(question, msg), appdata=appdata)
		if self.state == 0:
			# response secret -> SMP2TLV
			combSecret = HASH(b'\1' + self.crypto.theirPubkey.fingerprint() +
					ourFP + self.crypto.sessionId + secret)

			self.secret = bytes_to_long(combSecret)

			msg = [pow(self.g1, self.x2, DH_MODULUS)]
			msg += proof_known_log(self.g1, self.x2, 3)
			msg.append(pow(self.g1, self.x3, DH_MODULUS))
			msg += proof_known_log(self.g1, self.x3, 4)

			r = random.randrange(2, DH_MAX)

			self.p = pow(self.g3, r, DH_MODULUS)
			msg.append(self.p)

			qb1 = pow(self.g1, r, DH_MODULUS)
			qb2 = pow(self.g2, self.secret, DH_MODULUS)
			self.q = qb1 * qb2 % DH_MODULUS
			msg.append(self.q)

			msg += self.proof_equal_coords(r, 5)

			self.state = 3
			self.sendTLV(proto.SMP2TLV(msg), appdata=appdata)
def parse(filename):
    """parse the otr.private_key S-Expression and return an OTR dict"""
    with open(filename, 'r') as f:
        data = ''.join(line for line in f.readlines())

    sexplist = parse_sexp(data)
    keydict = dict()
    for sexpkey in sexplist:
        if sexpkey[0] == "account":
            key = dict()
            name = ''
            for element in sexpkey:
                # 'name' must be the first element in the sexp or BOOM!
                if element[0] == "name":
                    if element[1].find('/') > -1:
                        name, resource = element[1].split('/')
                    else:
                        name = element[1].strip()
                        resource = ''
                    key = dict()
                    key['name'] = name.strip()
                    key['resource'] = resource.strip()
                elif element[0] == "protocol":
                    key['protocol'] = element[1]
                elif element[0] == "private-key":
                    if element[1][0] == 'dsa':
                        key['type'] = 'dsa'
                        for num in element[1][1:6]:
                            key[num[0]] = num[1]
            keytuple = (key['y'], key['g'], key['p'], key['q'], key['x'])
            key['dsakey'] = DSAKey(keytuple, private=True)
            key['fingerprint'] = '{0:040x}'.format(bytes_to_long(key['dsakey'].fingerprint()))
            keydict[name] = key
    return keydict
Exemple #5
0
    def handleDHKey(self, msg):
        if self.state == STATE_AWAITING_DHKEY:
            self.gy = bytes_to_long(msg.gy)

            # check 2 <= g**y <= p-2
            if not check_group(self.gy):
                logger.error("Invalid g**y received: %r", self.gy)
                return

            self.createAuthKeys()

            aesxb = self.calculatePubkeyAuth(self.enc_c, self.mac_m1)

            self.state = STATE_AWAITING_SIG

            self.lastmsg = proto.RevealSig(self.r, aesxb, b"")
            self.lastmsg.mac = SHA256HMAC160(self.mac_m2, self.lastmsg.getMacedData())
            return self.lastmsg

        elif self.state == STATE_AWAITING_SIG:
            logger.info("received DHKey while not awaiting DHKEY")
            if msg.gy == self.gy:
                logger.info("resending revealsig")
                return self.lastmsg
        else:
            logger.info("bad state for DHKey")
Exemple #6
0
    def proof_equal_coords(self, r, v):
        r1 = bytes_to_long(RNG.read(192))
        r2 = bytes_to_long(RNG.read(192))
        temp2 = pow(self.g1, r1, DH1536_MODULUS) \
                * pow(self.g2, r2, DH1536_MODULUS) % DH1536_MODULUS
        temp1 = pow(self.g3, r1, DH1536_MODULUS)

        cb = SHA256(struct.pack(b'B', v) + pack_mpi(temp1) + pack_mpi(temp2))
        c = bytes_to_long(cb)

        temp1 = r * c % SM_ORDER
        d1 = (r1-temp1) % SM_ORDER

        temp1 = self.secret * c % SM_ORDER
        d2 = (r2 - temp1) % SM_ORDER
        return c, d1, d2
Exemple #7
0
    def handleDHKey(self, msg):
        if self.state == STATE_AWAITING_DHKEY:
            self.gy = bytes_to_long(msg.gy)

            # check 2 <= g**y <= p-2
            if not check_group(self.gy):
                logger.error('Invalid g**y received: %r', self.gy)
                return

            self.createAuthKeys()

            aesxb = self.calculatePubkeyAuth(self.enc_c, self.mac_m1)

            self.state = STATE_AWAITING_SIG

            self.lastmsg = proto.RevealSig(self.r, aesxb, b'')
            self.lastmsg.mac = SHA256HMAC160(self.mac_m2,
                    self.lastmsg.getMacedData())
            return self.lastmsg

        elif self.state == STATE_AWAITING_SIG:
            logger.info('received DHKey while not awaiting DHKEY')
            if msg.gy == self.gy:
                logger.info('resending revealsig')
                return self.lastmsg
        else:
            logger.info('bad state for DHKey')
Exemple #8
0
	def handleDHKey(self, msg):
	
		if self.state == STATE_AWAITING_DHKEY:
			self.gy = bytes_to_long(msg.gy)

			# check 2 <= g**y <= p-2
			if not check_group(self.gy):
				logger.error('Invalid g**y received: %r', self.gy)
				return

			# Création de toutes les clés
			self.createAuthKeys()

			aesxb = self.calculatePubkeyAuth(self.enc_c, self.mac_m1)

			self.state = STATE_AWAITING_SIG

			self.lastmsg = proto.RevealSig(self.r, aesxb, b'')
			self.lastmsg.mac = SHA256HMAC160(self.mac_m2,
					self.lastmsg.getMacedData())
					
			# Message envoyé : (r, AES(Xb), MAC(AES(XB)))
			return self.lastmsg

		elif self.state == STATE_AWAITING_SIG:
			logger.info('received DHKey while not awaiting DHKEY')
			if msg.gy == self.gy:
				logger.info('resending revealsig')
				return self.lastmsg
		else:
			logger.info('bad state for DHKey')
Exemple #9
0
    def proof_equal_logs(self, v):
        r = randrange(2, DH_MAX)
        temp1 = pow(self.g1, r, DH_MODULUS)
        temp2 = pow(self.qab, r, DH_MODULUS)

        cb = SHA256(struct.pack(b'B', v) + pack_mpi(temp1) + pack_mpi(temp2))
        c = bytes_to_long(cb)
        temp1 = self.x3 * c % SM_ORDER
        d = (r - temp1) % SM_ORDER
        return c, d
Exemple #10
0
	def handleDataMessage(self, msg):
		if self.saneKeyIds(msg) is False:
			raise InvalidParameterError

		sesskey = self.sessionkeys[self.ourKeyid - msg.rkeyid] \
				[self.theirKeyid - msg.skeyid]

		logger.debug('sesskeys: {0!r}, our={1}, r={2}, their={3}, s={4}' \
				.format(self.sessionkeys, self.ourKeyid, msg.rkeyid,
						self.theirKeyid, msg.skeyid))

		if msg.mac != SHA1HMAC(sesskey.rcvmac, msg.getMacedData()):
			logger.error('HMACs don\'t match')
			raise InvalidParameterError
		sesskey.rcvmacused = True

		newCtrPrefix = bytes_to_long(msg.ctr)
		if newCtrPrefix <= sesskey.rcvctr.prefix:
			logger.error('CTR must increase (old %r, new %r)',
					sesskey.rcvctr.prefix, newCtrPrefix)
			raise InvalidParameterError

		sesskey.rcvctr.prefix = newCtrPrefix

		logger.debug('handle: enc={0!r} mac={1!r} ctr={2!r}' \
				.format(sesskey.rcvenc, sesskey.rcvmac, sesskey.rcvctr))

		plaintextData = AESCTR(sesskey.rcvenc, sesskey.rcvctr) \
				.decrypt(msg.encmsg)

		if b'\0' in plaintextData:
			plaintext, tlvData = plaintextData.split(b'\0', 1)
			tlvs = proto.TLV.parse(tlvData)
		else:
			plaintext = plaintextData
			tlvs = []

		if msg.rkeyid == self.ourKeyid:
			self.rotateDHKeys()
		if msg.skeyid == self.theirKeyid:
			self.rotateYKeys(bytes_to_long(msg.dhy))

		return plaintext, tlvs
Exemple #11
0
	def proof_equal_logs(self, v):
		r = random.randrange(2, DH_MAX)
		temp1 = pow(self.g1, r, DH_MODULUS)
		temp2 = pow(self.qab, r, DH_MODULUS)

		cb = HASH(struct.pack(b'B', v) + pack_mpi(temp1) + pack_mpi(temp2))
		c = bytes_to_long(cb)
		temp1 = self.x3 * c % SM_ORDER
		d = (r - temp1) % SM_ORDER
		return c, d
Exemple #12
0
    def handleDataMessage(self, msg):
        if self.saneKeyIds(msg) is False:
            raise InvalidParameterError

        sesskey = self.sessionkeys[self.ourKeyid - msg.rkeyid] \
                [self.theirKeyid - msg.skeyid]

        logger.debug('sesskeys: {0!r}, our={1}, r={2}, their={3}, s={4}' \
                .format(self.sessionkeys, self.ourKeyid, msg.rkeyid,
                        self.theirKeyid, msg.skeyid))

        if msg.mac != SHA1HMAC(sesskey.rcvmac, msg.getMacedData()):
            logger.error('HMACs don\'t match')
            raise InvalidParameterError
        sesskey.rcvmacused = True

        newCtrPrefix = bytes_to_long(msg.ctr)
        if newCtrPrefix <= sesskey.rcvctr.prefix:
            logger.error('CTR must increase (old %r, new %r)',
                    sesskey.rcvctr.prefix, newCtrPrefix)
            raise InvalidParameterError

        sesskey.rcvctr.prefix = newCtrPrefix

        logger.debug('handle: enc={0!r} mac={1!r} ctr={2!r}' \
                .format(sesskey.rcvenc, sesskey.rcvmac, sesskey.rcvctr))

        plaintextData = AESCTR(sesskey.rcvenc, sesskey.rcvctr) \
                .decrypt(msg.encmsg)

        if b'\0' in plaintextData:
            plaintext, tlvData = plaintextData.split(b'\0', 1)
            tlvs = proto.TLV.parse(tlvData)
        else:
            plaintext = plaintextData
            tlvs = []

        if msg.rkeyid == self.ourKeyid:
            self.rotateDHKeys()
        if msg.skeyid == self.theirKeyid:
            self.rotateYKeys(bytes_to_long(msg.dhy))

        return plaintext, tlvs
Exemple #13
0
    def proof_equal_coords(self, r, v):
        r1 = random.randrange(2, DH_MAX)
        r2 = random.randrange(2, DH_MAX)
        temp2 = pow(self.g1, r1, DH_MODULUS) * pow(self.g2, r2, DH_MODULUS) % DH_MODULUS
        temp1 = pow(self.g3, r1, DH_MODULUS)

        cb = SHA256(struct.pack(b"B", v) + pack_mpi(temp1) + pack_mpi(temp2))
        c = bytes_to_long(cb)

        temp1 = r * c % SM_ORDER
        d1 = (r1 - temp1) % SM_ORDER

        temp1 = self.secret * c % SM_ORDER
        d2 = (r2 - temp1) % SM_ORDER
        return c, d1, d2
Exemple #14
0
    def proof_equal_coords(self, r, v):
        r1 = randrange(2, DH_MAX)
        r2 = randrange(2, DH_MAX)
        temp2 = pow(self.g1, r1, DH_MODULUS) \
                * pow(self.g2, r2, DH_MODULUS) % DH_MODULUS
        temp1 = pow(self.g3, r1, DH_MODULUS)

        cb = SHA256(struct.pack(b'B', v) + pack_mpi(temp1) + pack_mpi(temp2))
        c = bytes_to_long(cb)

        temp1 = r * c % SM_ORDER
        d1 = (r1-temp1) % SM_ORDER

        temp1 = self.secret * c % SM_ORDER
        d2 = (r2 - temp1) % SM_ORDER
        return c, d1, d2
Exemple #15
0
def fingerprint(key):
    '''generate the human readable form of the fingerprint as used in OTR'''
    return '{0:040x}'.format(bytes_to_long(DSAKey(key).fingerprint()))
Exemple #16
0
 def cfingerprint(self):
     return '{0:040x}'.format(bytes_to_long(self.fingerprint()))
Exemple #17
0
def fingerprint(key):
    '''generate the human readable form of the fingerprint as used in OTR'''
    return '{0:040x}'.format(bytes_to_long(DSAKey(key).fingerprint()))
Exemple #18
0
 def verify(self, data, sig):
     r, s = bytes_to_long(sig[:20]), bytes_to_long(sig[20:])
     return self.pub.verify(data, (r, s))
Exemple #19
0
 def __hash__(self):
     return bytes_to_long(self.fingerprint())
Exemple #20
0
def proof_known_log(g, x, v):
    r = bytes_to_long(RNG.read(192))
    c = bytes_to_long(SHA256(struct.pack(b'B', v) + pack_mpi(pow(g, r, DH1536_MODULUS))))
    temp = x * c % SM_ORDER
    return c, (r-temp) % SM_ORDER
Exemple #21
0
 def sign(self, data):
     # 2 <= K <= q = 160bit = 20 byte
     K = bytes_to_long(RNG.read(19)) + 2
     r, s = self.priv.sign(data, K)
     return long_to_bytes(r) + long_to_bytes(s)
Exemple #22
0
def proof_known_log(g, x, v):
    r = randrange(2, DH_MAX)
    c = bytes_to_long(SHA256(struct.pack(b'B', v) + pack_mpi(pow(g, r, DH_MODULUS))))
    temp = x * c % SM_ORDER
    return c, (r-temp) % SM_ORDER
Exemple #23
0
 def cfingerprint(self):
     return '{0:040x}'.format(bytes_to_long(self.fingerprint()))
Exemple #24
0
 def verify(self, data, sig):
     r, s = bytes_to_long(sig[:20]), bytes_to_long(sig[20:])
     return self.pub.verify(data, (r, s))
Exemple #25
0
def proof_known_log(g, x, v):
	r = random.randrange(2, DH_MAX)
	c = bytes_to_long(HASH(struct.pack(b'B', v) + pack_mpi(pow(g, r, DH_MODULUS))))
	temp = x * c % SM_ORDER
	return c, (r-temp) % SM_ORDER
Exemple #26
0
    def handle(self, tlv, appdata=None):
        logger.debug('handling TLV {0.__class__.__name__}'.format(tlv))
        self.prog = SMPPROG_CHEATED
        if isinstance(tlv, proto.SMPABORTTLV):
            self.state = 1
            return
        is1qTlv = isinstance(tlv, proto.SMP1QTLV)
        if isinstance(tlv, proto.SMP1TLV) or is1qTlv:
            if self.state != 1:
                self.abort(appdata=appdata)
                return

            msg = tlv.mpis

            if not check_group(msg[0]) or not check_group(msg[3]) \
                    or not check_exp(msg[2]) or not check_exp(msg[5]) \
                    or not check_known_log(msg[1], msg[2], self.g1, msg[0], 1) \
                    or not check_known_log(msg[4], msg[5], self.g1, msg[3], 2):
                logger.error('invalid SMP1TLV received')
                self.abort(appdata=appdata)
                return

            self.questionReceived = is1qTlv

            self.g3o = msg[3]

            self.x2 = bytes_to_long(RNG.read(192))
            self.x3 = bytes_to_long(RNG.read(192))

            self.g2 = pow(msg[0], self.x2, DH1536_MODULUS)
            self.g3 = pow(msg[3], self.x3, DH1536_MODULUS)

            self.prog = SMPPROG_OK
            self.state = 0
            return
        if isinstance(tlv, proto.SMP2TLV):
            if self.state != 2:
                self.abort(appdata=appdata)
                return

            msg = tlv.mpis
            mp = msg[6]
            mq = msg[7]

            if not check_group(msg[0]) or not check_group(msg[3]) \
                    or not check_group(msg[6]) or not check_group(msg[7]) \
                    or not check_exp(msg[2]) or not check_exp(msg[5]) \
                    or not check_exp(msg[9]) or not check_exp(msg[10]) \
                    or not check_known_log(msg[1], msg[2], self.g1, msg[0], 3) \
                    or not check_known_log(msg[4], msg[5], self.g1, msg[3], 4):
                logger.error('invalid SMP2TLV received')
                self.abort(appdata=appdata)
                return

            self.g3o = msg[3]
            self.g2 = pow(msg[0], self.x2, DH1536_MODULUS)
            self.g3 = pow(msg[3], self.x3, DH1536_MODULUS)

            if not self.check_equal_coords(msg[6:11], 5):
                logger.error('invalid SMP2TLV received')
                self.abort(appdata=appdata)
                return

            r = bytes_to_long(RNG.read(192))
            self.p = pow(self.g3, r, DH1536_MODULUS)
            msg = [self.p]
            qa1 = pow(self.g1, r, DH1536_MODULUS)
            qa2 = pow(self.g2, self.secret, DH1536_MODULUS)
            self.q = qa1*qa2 % DH1536_MODULUS
            msg.append(self.q)
            msg += self.proof_equal_coords(r, 6)

            inv = invMod(mp)
            self.pab = self.p * inv % DH1536_MODULUS
            inv = invMod(mq)
            self.qab = self.q * inv % DH1536_MODULUS

            msg.append(pow(self.qab, self.x3, DH1536_MODULUS))
            msg += self.proof_equal_logs(7)

            self.state = 4
            self.prog = SMPPROG_OK
            self.sendTLV(proto.SMP3TLV(msg), appdata=appdata)
            return
        if isinstance(tlv, proto.SMP3TLV):
            if self.state != 3:
                self.abort(appdata=appdata)
                return

            msg = tlv.mpis

            if not check_group(msg[0]) or not check_group(msg[1]) \
                    or not check_group(msg[5]) or not check_exp(msg[3]) \
                    or not check_exp(msg[4]) or not check_exp(msg[7]) \
                    or not self.check_equal_coords(msg[:5], 6):
                logger.error('invalid SMP3TLV received')
                self.abort(appdata=appdata)
                return

            inv = invMod(self.p)
            self.pab = msg[0] * inv % DH1536_MODULUS
            inv = invMod(self.q)
            self.qab = msg[1] * inv % DH1536_MODULUS

            if not self.check_equal_logs(msg[5:8], 7):
                logger.error('invalid SMP3TLV received')
                self.abort(appdata=appdata)
                return

            md = msg[5]
            msg = [pow(self.qab, self.x3, DH1536_MODULUS)]
            msg += self.proof_equal_logs(8)

            rab = pow(md, self.x3, DH1536_MODULUS)
            self.prog = SMPPROG_SUCCEEDED if self.pab == rab else SMPPROG_FAILED

            if self.prog != SMPPROG_SUCCEEDED:
                logger.error('secrets don\'t match')
                self.abort(appdata=appdata)
                self.crypto.ctx.setCurrentTrust('')
                return

            logger.info('secrets matched')
            if not self.questionReceived:
                self.crypto.ctx.setCurrentTrust('smp')
            self.state = 1
            self.sendTLV(proto.SMP4TLV(msg), appdata=appdata)
            return
        if isinstance(tlv, proto.SMP4TLV):
            if self.state != 4:
                self.abort(appdata=appdata)
                return

            msg = tlv.mpis

            if not check_group(msg[0]) or not check_exp(msg[2]) \
                    or not self.check_equal_logs(msg[:3], 8):
                logger.error('invalid SMP4TLV received')
                self.abort(appdata=appdata)
                return

            rab = pow(msg[0], self.x3, DH1536_MODULUS)

            self.prog = SMPPROG_SUCCEEDED if self.pab == rab else SMPPROG_FAILED

            if self.prog != SMPPROG_SUCCEEDED:
                logger.error('secrets don\'t match')
                self.abort(appdata=appdata)
                self.crypto.ctx.setCurrentTrust('')
                return

            logger.info('secrets matched')
            self.crypto.ctx.setCurrentTrust('smp')
            self.state = 1
            return
Exemple #27
0
	def __hash__(self):
		return bytes_to_long(self.fingerprint())
Exemple #28
0
 def __init__(self):
     self.priv = bytes_to_long(RNG.read(40))
     self.pub = pow(self.gen, self.priv, self.prime)