##
## crypt.py -- Cryptography wrappers.
##
## Copyleft 1998 Teemu Kalvas <chery@s2.org>,
##          1995-1997 Timo J. Rinne <tri@iki.fi>
##

import regex
import time

import config
import idea

encmsg_re = regex.compile('|\*E\*|\([^|]*\)|\([0-9]+\)\.\([0-9]+\)|' +
			  '\([^|]*\)|\([^|]*\)|')
dec_re = regex.compile('\([^\001]+\)\001\([^\001]+\)\001\(.*\)')

def get_decryption_key(fingerprint):
    if config.known_key.has_key(fingerprint):
	return config.known_key[fingerprint]
    else:
	return ()

def get_encryption_key(address, version = 0):
    for k in config.default_key:
	if k[0].match(address):
            if len(k) > 4:
                vers = k[4]
            elif version:
                vers = version
            else:
                vers = config.idea_default_version
            return k[vers]
    return ()

def make_encrypted_message(message, key):
    version = idea.key_version(key)
    return '|*E*|IDEA|' + str(version) + '.0|' + idea.key_fingerprint(key) \
           + '|' + idea.cbc_encrypt_string(message, key) + '|'

def valid_version_p(method, major, minor):
    return method == 'IDEA' and major >= 1 and major <= 3 and minor >= 0

def gen_hex_time():
    return hex(int(time.time()))[2:]

def encrypt_message(nick, message, address, no_clear = 0):
    key = get_encryption_key(address)
    if no_clear and not key:
	return ()
    if not key:
	return message
    else:
	return make_encrypted_message(nick + '\001' + gen_hex_time() + '\001' +
				      message, key)

def decrypt_message(message):
    if encmsg_re.match(message) > 0:
	method, major, minor, fingerprint, msg = encmsg_re.group(1, 2, 3, 4, 5)
	if valid_version_p(method, int(major), int(minor)):
	    key = get_decryption_key(fingerprint)
	    if key:
		r = idea.cbc_decrypt_string(msg, key)
		if r:
		    if dec_re.match(r) > 0:
			nick, time, msg = dec_re.group(1, 2, 3)
			return [1, msg, nick, time, fingerprint]
		    else:
			return [0, 'Invalid cleartext format.']
		else:
		    return [0, 'Decryption failed.']
	    else:
		return [0, 'No key,']
	else:
	    return [0, 'Unknown version.']
    else:
	return [-1, message]

## End. ##
