Ejemplo n.º 1
0
def import_pubkey(key, rsa):
        (magic, key) = gale_pack.pop_data(key, len(PRIVATE_MAGIC3))
	(namelen, key) = gale_pack.pop_int(key)
        (pubkeyname, key) = gale_pack.pop_string(key, namelen, chars=1)
	fraglist = gale_pack.group_to_FragList(key, 1)
	rsa.n = openssl.bn.bin2bn(fraglist.get_binary_first('rsa.modulus'))
	rsa.e = openssl.bn.bin2bn(fraglist.get_binary_first('rsa.exponent'))
	rsa.d = openssl.bn.bin2bn(fraglist.get_binary_first('rsa.private.exponent'))
	prime_data = fraglist.get_binary_first('rsa.private.prime')
	rsa.p = openssl.bn.bin2bn(prime_data[:GALE_RSA_PRIME_LEN])
	rsa.q = openssl.bn.bin2bn(prime_data[GALE_RSA_PRIME_LEN:])
	prime_data = fraglist.get_binary_first('rsa.private.prime.exponent')
	rsa.dmp1 = openssl.bn.bin2bn(prime_data[:GALE_RSA_PRIME_LEN])
	rsa.dmq1 = openssl.bn.bin2bn(prime_data[GALE_RSA_PRIME_LEN:])
	rsa.iqmp = openssl.bn.bin2bn(fraglist.get_binary_first('rsa.private.coefficient'))
Ejemplo n.º 2
0
def import_pubkey(keyobj, callback, trust=0):
	if DEBUG > 2: print '--> Starting import_pubkey'
	keydata = keyobj.data()
	# _ga_import_pub
	# Back up the key to verify its signature, later
	save = keydata
	(magic, keydata) = gale_pack.pop_data(keydata, len(KEY_MAGIC))
	if KEY_MAGIC == magic:
		version = 1
	elif KEY_MAGIC2 == magic:
		version = 2
	elif KEY_MAGIC3 == magic:
		(subversion, keydata) = gale_pack.pop_data(keydata,
			len(SUBVERSION))
		if SUBVERSION == subversion:
			version = 3
		else:
			pygale.call_error_handler('Unsupported version 3 key format')
			keyobj.setpublic(None)
			keyobj.set_verified(0)
			callback(keyobj)
			return
	else:
		pygale.call_error_handler('Unsupported public key (bad magic)')
		keyobj.setpublic(None)
		keyobj.set_verified(0)
		callback(keyobj)
		return
	# version must be <= 3 at this point
	if DEBUG >= 3: print 'Public key version:', version

	if version > 1:
		(namelen, keydata) = gale_pack.pop_int(keydata)
		(pubkeyname, keydata) = gale_pack.pop_string(keydata, namelen,
			chars=1)
	else:	# version == 1
		(pubkeyname, keydata) = gale_pack.pop_nulltermstr(keydata)
	pubkeyname = flip_local_key_part(pubkeyname)
	if DEBUG > 2: print 'Unpacking public key named:', pubkeyname
	keyobj.setname(pubkeyname)
	if DEBUG > 2: print 'Setting name in %s to %s' % (`keyobj`, pubkeyname)
	keyobj.settrusted(trust)

	if len(keydata) == 0:
		if DEBUG: print 'Found stub key for', pubkeyname
		keyobj.setpublic(None)
		callback(keyobj)
		return

	# Otherwise, deal with a non-stub key
	# Special-case for different version keys.  Version 3 is the key with
	# fragments in it, which Dan introduced in 0.91b.
	if version == 3:
		fraglist = gale_pack.group_to_FragList(keydata, DAN_IS_STOOPID=1)

		# Verify key if it's signed
		if fraglist.has_key('security/signature'):
			# deal with only the first security/signature fragment
			sig = fraglist.get_binary_first('security/signature')
			(sig_len, sig) = gale_pack.pop_int(sig)
			(signature, sig) = gale_pack.pop_data(sig, sig_len)
			msg_data = sig
			new_fragments = gale_pack.group_to_FragList(sig)
			fraglist.update(new_fragments)
		else:
			signature = ''
			# TODO
			# This hacky setting of msg_data is to fix the bug later on
			# where we try to call decode_sig with msg_data.  I need to
			# dig into key formats more to find the right thing to do.
			msg_data = ''

		# TODO dangermouse
		# Redirects should not be handled here since the field contains
		# a *location* and not a key name
		if fraglist.get_text('key.redirect'):
			# Handle a key redirection: the field contains a *location*
			keyobj.set_redirect(fraglist.get_text_first('key.redirect'))

		# Use only the first instance of each fragment if it exists
		comment = fraglist.get_text_first('key.owner', 'Unspecified owner')
		time_sign = fraglist.get_time_first('key.signed', 0)
		time_expire = fraglist.get_time_first('key.expires', 0)
		rsa_keybits = fraglist.get_int_first('rsa.bits', 0)
		rsa_modulus = fraglist.get_binary_first('rsa.modulus', '')
		rsa_exponent = fraglist.get_binary_first('rsa.exponent', '')

		# Set the list of key members but do not look them up at this
		# point
		if fraglist.has_key('key.member'):
			keyobj.set_members(fraglist.get_text('key.member'))
		# Done unpacking version 3 key

	# Version 1 or 2 keys are packed binary data.
	elif version == 1 or version == 2:
		if version == 2:
			(comment, keydata) = gale_pack.pop_lenstr(keydata, chars=1)
		else:
			(comment, keydata) = gale_pack.pop_nulltermstr(keydata)
		if DEBUG > 2: print 'Found comment:', comment

		(rsa_keybits, keydata) = gale_pack.pop_int(keydata)
		(rsa_modulus, keydata) = gale_pack.pop_rle(keydata,
			GALE_RSA_MODULUS_LEN)
		(rsa_exponent, keydata) = gale_pack.pop_rle(keydata,
			GALE_RSA_MODULUS_LEN)
		if rsa_keybits > GALE_RSA_MODULUS_BITS:
			pygale.call_error_handler(
				'bad public key bit size %i' % rsa_keybits)
			keyobj.setpublic(None)
			keyobj.set_verified(0)
			callback(keyobj)
			return

		if version > 1 and keydata:
			(time_sign, keydata) = gale_pack.pop_time(keydata)
			(time_expire, keydata) = gale_pack.pop_time(keydata)
			if DEBUG > 2: print 'Key signed at:', time_sign.ctime()
			if DEBUG > 2: print 'Key expires at:', time_expire.ctime()
#			if time_expire <= time.time():
#				pygale.call_error_handler('found expired key for %s' %
#					pubkeyname)
#				callback(None)
#				return
		else:
			# no key timestamp checking in version 1
			pass
		signature = keydata

		# Done unpacking version 1 or version 2 key
	else:
		# unsupported version
		pygale.call_error_handler('unsupported key version: %i' %
			version)
		keyobj.setpublic(None)
		keyobj.set_verified(0)
		callback(keyobj)
		return
	
	# TODO: check for expired keys

	keyobj.setcomment(comment)
	if rsa_keybits:
		pubkey = openssl.evp.PKEY()
		pubkey.assign_RSA(openssl.rsa.RSA())
		pubkey.pkey.rsa.n = openssl.bn.bin2bn(rsa_modulus)
		pubkey.pkey.rsa.e = openssl.bn.bin2bn(rsa_exponent)
		keyobj.setpublic(pubkey)
	else:
		# No public key bits in this key
		keyobj.setpublic(None)

	# Import and validate the signature on this public key
	if not keyobj.trusted():
		if DEBUG > 2: print 'import_pubkey: Verifying sig'
		if version < 3:
			msg_data = save[:-len(keydata)]
		if not signature or not msg_data:
			pygale.call_error_handler('unsigned key %s' % keyobj.name())
			keyobj.setpublic(None)
			keyobj.set_verified(0)
			callback(keyobj)
			return
		decode_sig(signature, msg_data, lambda k, u=keyobj, c=callback:
			decode_done(k, u, c))

	else:
		if DEBUG: print 'Key is trusted; not verifying'
		keyobj.set_verified(1)
		callback(keyobj)
		return