Commit 6376f720 authored by Lucas Carvalho's avatar Lucas Carvalho

Allows to check multi trusted certificates.

Actually, the user can configure the buildout.cfg and set multiples
certificates files.

It means that libnetworkcache must be able to check if the signature
which comes from shadir is trustable or not, based on these certificates.

A given signature can not appear twice in the same directory-key, if it
happens a DiretoryNotFound error must be raised.
parent c6f62c94
......@@ -24,7 +24,7 @@ import urlparse
import M2Crypto
_MARKER = (None, '')
_MARKER = ([], [''], None, '')
class NetworkcacheClient(object):
......@@ -53,7 +53,8 @@ class NetworkcacheClient(object):
return return_dict
def __init__(self, shacache, shadir,
signature_private_file=None, signature_public_file=None):
signature_private_key_file=None,
signature_certificate_file_list=None):
''' Set the initial values. '''
# ShaCache Properties
for k, v in self.parseUrl(shacache).iteritems():
......@@ -64,8 +65,8 @@ class NetworkcacheClient(object):
for k, v in self.parseUrl(shadir).iteritems():
setattr(self, 'shadir_%s' % k, v)
self.signature_private_file = signature_private_file
self.signature_public_file = signature_public_file
self.signature_private_key_file = signature_private_key_file
self.signature_certificate_file_list = signature_certificate_file_list
def upload(self, file_descriptor, directory_key=None, **kw):
''' Upload the file to the server.
......@@ -163,52 +164,56 @@ class NetworkcacheClient(object):
if result.status != 200:
raise DirectoryNotFound(result.read())
# Filtering...
data_list = json.loads(data)
if len(data_list) > 1 and self.signature_public_file in _MARKER:
if len(data_list) > 1 and self.signature_certificate_file_list in _MARKER:
raise DirectoryNotFound('Too many entries for a given directory. ' \
'Directory: %s. Entries: %s.' % (directory_key, str(data_list)))
sha512 = None
if self.signature_public_file not in _MARKER:
for information_dict, signature in data_list:
if self._verifySignature(signature):
sha512 = information_dict.get('sha512')
break
if sha512 is None:
if self.signature_certificate_file_list not in _MARKER:
method = self._verifySignatureInCertificateList
data_list = filter(lambda x: method(x[1]), data_list)
if len(data_list) > 1:
raise DirectoryNotFound('Too many entries for a given key. ' \
'Directory: %s. Entries: %s.' %(directory_key, str(data_list)))
if not data_list:
raise DirectoryNotFound('Could not find a trustable entry.')
else:
information_dict, signature = data_list[0]
sha512 = information_dict.get('sha512')
return self.download(sha512)
def _getSignatureString(self):
"""
Return the signature based on certification file.
"""
if self.signature_private_file in _MARKER:
if self.signature_private_key_file in _MARKER:
return ''
SignEVP = M2Crypto.EVP.load_key(self.signature_private_file)
SignEVP = M2Crypto.EVP.load_key(self.signature_private_key_file)
SignEVP.sign_init()
SignEVP.sign_update('')
StringSignature = SignEVP.sign_final()
return StringSignature.encode('base64')
def _verifySignature(self, signature_string):
def _verifySignatureInCertificateList(self, signature_string):
"""
Check if the signature is valid.
Returns true if it can find any valid certificate.
"""
if self.signature_public_file in _MARKER:
if self.signature_certificate_file_list in _MARKER:
return 0
PubKey = M2Crypto.X509.load_cert(self.signature_public_file)
for certificate_path in self.signature_certificate_file_list:
PubKey = M2Crypto.X509.load_cert(certificate_path)
VerifyEVP = M2Crypto.EVP.PKey()
VerifyEVP.assign_rsa(PubKey.get_pubkey().get_rsa())
VerifyEVP.verify_init()
VerifyEVP.verify_update('')
return VerifyEVP.verify_final(signature_string.decode('base64'))
if VerifyEVP.verify_final(signature_string.decode('base64')):
return True
return False
class DirectoryNotFound(Exception):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment