review logging again; code that runs in client and/or server now logs in the right...
[sfa.git] / sfa / trust / certificate.py
index 9fd58ed..466cec8 100644 (file)
@@ -1,3 +1,26 @@
+#----------------------------------------------------------------------
+# Copyright (c) 2008 Board of Trustees, Princeton University
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and/or hardware specification (the "Work") to
+# deal in the Work without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Work, and to permit persons to whom the Work
+# is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Work.
+#
+# THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+# OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS 
+# IN THE WORK.
+#----------------------------------------------------------------------
+
 ##
 # SFA uses two crypto libraries: pyOpenSSL and M2Crypto to implement
 # the necessary crypto functionality. Ideally just one of these libraries
@@ -19,16 +42,18 @@ import os
 import tempfile
 import base64
 import traceback
+from tempfile import mkstemp
+
 from OpenSSL import crypto
 import M2Crypto
 from M2Crypto import X509
-from tempfile import mkstemp
-from sfa.util.sfalogging import logger
+
+from sfa.util.sfalogging import sfa_logger
 from sfa.util.namespace import urn_to_hrn
 from sfa.util.faults import *
 
 def convert_public_key(key):
-    keyconvert_path = "/usr/bin/keyconvert"
+    keyconvert_path = "/usr/bin/keyconvert.py"
     if not os.path.isfile(keyconvert_path):
         raise IOError, "Could not find keyconvert in %s" % keyconvert_path
 
@@ -54,7 +79,7 @@ def convert_public_key(key):
     try:
         k.load_pubkey_from_file(ssl_fn)
     except:
-        traceback.print_exc()
+        sfa_logger().log_exc("convert_public_key caught exception")
         k = None
 
     # remove the temporary files
@@ -448,7 +473,7 @@ class Certificate:
         # pyOpenSSL only allows us to add extensions, so if we try to set the
         # same extension more than once, it will not work
         if self.data.has_key(field):
-            raise "cannot set ", field, " more than once"
+            raise "Cannot set ", field, " more than once"
         self.data[field] = str
         self.add_extension(field, 0, str)
 
@@ -471,6 +496,7 @@ class Certificate:
     # Sign the certificate using the issuer private key and issuer subject previous set with set_issuer().
 
     def sign(self):
+        sfa_logger().debug('certificate.sign')
         assert self.cert != None
         assert self.issuerSubject != None
         assert self.issuerKey != None
@@ -510,6 +536,7 @@ class Certificate:
     # @param cert certificate object
 
     def is_signed_by_cert(self, cert):
+        print 'is_signed_by_cert'
         k = cert.get_pubkey()
         result = self.verify(k)
         return result
@@ -553,29 +580,35 @@ class Certificate:
         # the public key contained in it's parent. The chain is recursed
         # until a certificate is found that is signed by a trusted root.
 
-        # TODO: verify expiration time
-        #print "====Verify Chain====="
+        # verify expiration time
+        if self.cert.has_expired():
+            sfa_logger().debug("verify_chain: our certificate has expired")
+            raise CertExpired(self.get_subject(), "client cert")   
+        
         # if this cert is signed by a trusted_cert, then we are set
         for trusted_cert in trusted_certs:
-            #print "***************"
-            # TODO: verify expiration of trusted_cert ?
-            #print "CLIENT CERT", self.dump()
-            #print "TRUSTED CERT", trusted_cert.dump()
-            #print "Client is signed by Trusted?", self.is_signed_by_cert(trusted_cert)
             if self.is_signed_by_cert(trusted_cert):
-                return trusted_cert
+                sfa_logger().debug("verify_chain: cert %s signed by trusted cert %s"%(
+                        self.get_subject(), trusted_cert.get_subject()))
+                # verify expiration of trusted_cert ?
+                if not trusted_cert.cert.has_expired():
+                    return trusted_cert
+                else:
+                    sfa_logger().debug("verify_chain: cert %s is signed by trusted_cert %s, but this is expired..."%(
+                            self.get_subject(),trusted_cert.get_subject()))
 
         # if there is no parent, then no way to verify the chain
         if not self.parent:
-            #print self.get_subject(), "has no parent"
+            sfa_logger().debug("verify_chain: %r has no parent"%self.get_subject())
             raise CertMissingParent(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"
+            sfa_logger().debug("verify_chain: %r is not signed by parent"%self.get_subject())
             return CertNotSignedByParent(self.get_subject())
 
         # if the parent isn't verified...
+        sfa_logger().debug("verify_chain: with subject=%r, referring to parent, subj=%r",self.get_subject(),self.parent.get_subject())
         self.parent.verify_chain(trusted_certs)
 
         return