From: Josh Karlin Date: Tue, 13 Apr 2010 16:30:04 +0000 (+0000) Subject: chained certs now included in credential signature X-Git-Tag: geni-apiv1-totrunk~66 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=4c69b830f8a2055c4ee8dd027280ad8a5a14d934;hp=b51f82d3b954dac1dcaaaa3930f826b085331d60;p=sfa.git chained certs now included in credential signature --- diff --git a/sfa/trust/certificate.py b/sfa/trust/certificate.py index ce64dbe7..c0d1a078 100644 --- a/sfa/trust/certificate.py +++ b/sfa/trust/certificate.py @@ -23,6 +23,7 @@ from OpenSSL import crypto import M2Crypto from M2Crypto import X509 from M2Crypto import EVP +from random import randint from sfa.util.faults import * @@ -309,10 +310,16 @@ class Certificate: # Save the certificate to a file. # @param save_parents If save_parents==True, then also save the parent certificates. - def save_to_file(self, filename, save_parents=False): + def save_to_file(self, filename, save_parents=True): string = self.save_to_string(save_parents=save_parents) open(filename, 'w').write(string) - + ## + # Save the certificate to a random file in /tmp/ + # @param save_parents If save_parents==True, then also save the parent certificates. + def save_to_random_tmp_file(self, save_parents=True): + filename = "/tmp/cert_%d" % randint(0,999999999) + self.save_to_file(filename, save_parents) + return filename ## # Sets the issuer private key and name # @param key Keypair object containing the private key of the issuer diff --git a/sfa/trust/credential.py b/sfa/trust/credential.py index b55c6b47..ed1d5855 100644 --- a/sfa/trust/credential.py +++ b/sfa/trust/credential.py @@ -8,9 +8,10 @@ ### $URL$ import xmlrpclib -import random import os import datetime +from random import randint + from xml.dom.minidom import Document, parseString from sfa.trust.credential_legacy import CredentialLegacy @@ -19,6 +20,8 @@ from sfa.trust.rights import * from sfa.trust.gid import * from sfa.util.faults import * from sfa.util.sfalogging import logger +from lxml import etree + # Two years, in minutes @@ -380,7 +383,7 @@ class Credential(object): def save_to_random_tmp_file(self): - filename = "/tmp/cred_%d" % random.randint(0,999999999) + filename = "/tmp/cred_%d" % randint(0,999999999) self.save_to_file(filename) return filename @@ -457,11 +460,23 @@ class Credential(object): self.xml = doc.toxml() + + # Split the issuer GID into multiple certificates if it's a chain + chain = GID(filename=self.issuer_gid) + gid_files = [] + while chain: + gid_files.append(chain.save_to_random_tmp_file(False)) + if chain.get_parent(): + chain = chain.get_parent() + else: + chain = None + + # Call out to xmlsec1 to sign it ref = 'Sig_%s' % self.get_refid() filename = self.save_to_random_tmp_file() signed = os.popen('/usr/bin/xmlsec1 --sign --node-id "%s" --privkey-pem %s,%s %s' \ - % (ref, self.issuer_privkey, self.issuer_gid, filename)).read() + % (ref, self.issuer_privkey, ",".join(gid_files), filename)).read() os.remove(filename) self.xml = signed @@ -545,6 +560,7 @@ class Credential(object): # Verify that: # . All of the signatures are valid and that the issuers trace back # to trusted roots (performed by xmlsec1) + # . The XML matches the credential schema # . That the issuer of the credential is the authority in the target's urn # . In the case of a delegated credential, this must be true of the root # . That all of the gids presented in the credential are valid @@ -566,6 +582,10 @@ class Credential(object): if not self.xml: self.decode() + # Check for schema conformance + + + trusted_cert_objects = [GID(filename=f) for f in trusted_certs] # Use legacy verification if this is a legacy credential diff --git a/tests/testCred.py b/tests/testCred.py index 74201897..2a694b53 100755 --- a/tests/testCred.py +++ b/tests/testCred.py @@ -52,6 +52,7 @@ class TestCred(unittest.TestCase): self.assertEqual(cred2.get_privileges().save_to_string(), rights) + def createSignedGID(self, subject, urn, issuer_pkey = None, issuer_gid = None): gid = GID(subject=subject, uuid=1, urn=urn) keys = Keypair(create=True) @@ -65,7 +66,7 @@ class TestCred(unittest.TestCase): gid.sign() return gid, keys - + def testDelegationAndVerification(self):