From: Scott Baker Date: Wed, 3 Sep 2008 16:55:12 +0000 (+0000) Subject: certificate.verify_chain() generates exceps rather than returning true/false X-Git-Tag: sfa-0.9-0@14641~857 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=d1909b69ef871f5a9a821bdc39fbcc1d6f1100f3;p=sfa.git certificate.verify_chain() generates exceps rather than returning true/false --- diff --git a/util/cert.py b/util/cert.py index 10be6013..1397a599 100644 --- a/util/cert.py +++ b/util/cert.py @@ -7,6 +7,8 @@ # are being used due to lack of functionality in pyOpenSSL and some apparant # bugs in M2Crypto +import os +import tempfile from OpenSSL import crypto import M2Crypto from M2Crypto import X509 @@ -43,6 +45,41 @@ class Keypair: self.key = crypto.load_privatekey(crypto.FILETYPE_PEM, string) self.m2key = M2Crypto.EVP.load_key_string(string) + def load_pubkey_from_file(self, filename): + # load the m2 public key + m2rsakey = M2Crypto.RSA.load_pub_key(filename) + self.m2key = M2Crypto.EVP.PKey() + self.m2key.assign_rsa(m2rsakey) + + # create an m2 x509 cert + m2name = M2Crypto.X509.X509_Name() + m2name.add_entry_by_txt(field="CN", type=0x1001, entry="junk", len=-1, loc=-1, set=0) + m2x509 = M2Crypto.X509.X509() + m2x509.set_pubkey(self.m2key) + m2x509.set_serial_number(0) + m2x509.set_issuer_name(m2name) + m2x509.set_subject_name(m2name) + ASN1 = M2Crypto.ASN1.ASN1_UTCTIME() + ASN1.set_time(500) + m2x509.set_not_before(ASN1) + m2x509.set_not_after(ASN1) + junk_key = Keypair(create=True) + m2x509.sign(pkey=junk_key.get_m2_pkey(), md="sha1") + + # convert the m2 x509 cert to a pyopenssl x509 + m2pem = m2x509.as_pem() + pyx509 = crypto.load_certificate(crypto.FILETYPE_PEM, m2pem) + + # get the pyopenssl pkey from the pyopenssl x509 + self.key = pyx509.get_pubkey() + + def load_pubkey_from_string(self, string): + (f, fn) = tempfile.mkstemp() + os.write(f, string) + os.close(f) + self.load_pubkey_from_file(fn) + os.remove(fn) + def as_pem(self): return crypto.dump_privatekey(crypto.FILETYPE_PEM, self.key) @@ -254,21 +291,19 @@ class Certificate: # TODO: verify expiration of trusted_cert ? if self.is_signed_by_cert(trusted_cert): #print self.get_subject(), "is signed by a root" - return True + return # if there is no parent, then no way to verify the chain if not self.parent: #print self.get_subject(), "has no parent" - return False + raise MissingParent(self.get_subject()) # if it wasn't signed by the parent... if not self.is_signed_by_cert(self.parent): #print self.get_subject(), "is not signed by parent" - return False + return NotSignedByParent(self.get_subject()) # if the parent isn't verified... - if not self.parent.verify_chain(trusted_certs): - #print self.get_subject(), "parent does not verify" - return False + self.parent.verify_chain(trusted_certs) - return True + return diff --git a/util/credential.py b/util/credential.py index f5016f0e..7419076c 100644 --- a/util/credential.py +++ b/util/credential.py @@ -18,9 +18,6 @@ import xmlrpclib # to perform this encoding. class Credential(Certificate): - uuid = None - hrn = None - gidCaller = None gidObject = None lifeTime = None @@ -124,17 +121,34 @@ class Credential(Certificate): def verify_chain(self, trusted_certs = None): # do the normal certificate verification stuff - if not Certificate.verify_chain(self, trusted_certs): - return False + Certificate.verify_chain(self, trusted_certs) if parent: # make sure the parent delegated rights to the child if not parent.delegate: - return False + raise MissingDelegateBit(self.get_subject()) # XXX todo: make sure child rights are a subset of parent rights - return True + return + + def dump(self): + print "CREDENTIAL", self.get_subject() + + print " privs:", self.get_privileges().save_to_string() + + print " gidCaller:" + gidCaller = self.get_gid_caller() + if gidCaller: + gidCaller.dump(indent=8) + + print " gidObject:" + gidObject = self.get_gid_object() + if gidObject: + gidObject.dump(indent=8) + + print " delegate:", self.get_delegate() + diff --git a/util/excep.py b/util/excep.py index 67d89117..0555709c 100644 --- a/util/excep.py +++ b/util/excep.py @@ -72,3 +72,39 @@ class MissingAuthority(Exception): self.value = value def __str__(self): return repr(self.value) + +class PlanetLabRecordDoesNotExist(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class PermissionError(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class InsufficientRights(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class MissingDelegateBit(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class MissingParent(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +class NotSignedByParent(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) diff --git a/util/gid.py b/util/gid.py index 3f449c69..7701e87f 100644 --- a/util/gid.py +++ b/util/gid.py @@ -55,17 +55,12 @@ class GID(Certificate): self.uuid = dict.get("uuid", None) self.hrn = dict.get("hrn", None) - # XXX: I may have decided not to use this - def get_cache_key(self): - return self.get_cache_uuid() + self.get_cache_name() + def dump(self, indent=0): + # TODO: implement indent + print " "*indent, " hrn:", self.get_hrn() + print " "*indent, "uuid:", self.get_uuid() - # XXX: I may have decided not to use this - def get_cache_uuid(self): - return self.get_uuid() - # XXX: I may have decided not to use this - def get_cache_name(self): - return self.get_name() diff --git a/util/hierarchy.py b/util/hierarchy.py index 738171f4..f76f8191 100644 --- a/util/hierarchy.py +++ b/util/hierarchy.py @@ -10,6 +10,7 @@ # *.DBINFO - database info import os +import report from cert import * from gid import * from misc import * @@ -62,7 +63,14 @@ class Hierarchy(): os.path.exists(privkey_filename) and \ os.path.exists(dbinfo_filename) - def create_auth(self, hrn): + def create_auth(self, hrn, create_parents=False): + report.trace("Hierarchy: creating authority: " + hrn) + + # create the parent authority if necessary + parent_hrn = get_authority(hrn) + if (parent_hrn) and (not self.auth_exists(parent_hrn)) and (create_parents): + self.create_auth(parent_hrn, create_parents) + (directory, gid_filename, privkey_filename, dbinfo_filename) = \ self.get_auth_filenames(hrn) @@ -87,12 +95,11 @@ class Hierarchy(): dbinfo_file.write(str(dbinfo)) dbinfo_file.close() - def get_auth_info(self, hrn, can_create=True): - if not self.auth_exists(hrn): - if not can_create: - return MissingAuthority(hrn) + def get_auth_info(self, hrn): + #report.trace("Hierarchy: getting authority: " + hrn) - self.create_auth(hrn) + if not self.auth_exists(hrn): + raise MissingAuthority(hrn) (directory, gid_filename, privkey_filename, dbinfo_filename) = \ self.get_auth_filenames(hrn) @@ -104,7 +111,7 @@ class Hierarchy(): def create_gid(self, hrn, uuid, pkey): parent_hrn = get_authority(hrn) - gid = GID(subject=hrn, uuid=uuid) + gid = GID(subject=hrn, uuid=uuid, hrn=hrn) if not parent_hrn: # if there is no parent hrn, then it must be self-signed. this @@ -117,6 +124,7 @@ class Hierarchy(): gid.set_parent(parent_auth_info.get_gid_object()) gid.set_pubkey(pkey) + gid.encode() gid.sign() return gid