sfa client bootstrap library has a new 'my_pkcs12' feature, and this is now invoked...
authorThierry Parmentelat <thierry.parmentelat@inria.fr>
Fri, 25 Oct 2013 16:29:02 +0000 (18:29 +0200)
committerThierry Parmentelat <thierry.parmentelat@inria.fr>
Fri, 25 Oct 2013 16:29:32 +0000 (18:29 +0200)
sfa/client/sfaclientlib.py
sfa/client/sfi.py

index 2f4cda4..f4fe3a8 100644 (file)
@@ -9,6 +9,7 @@
 
 import sys
 import os,os.path
+import subprocess
 from datetime import datetime
 from sfa.util.xrn import Xrn
 
@@ -24,7 +25,7 @@ from sfa.trust.certificate import Keypair, Certificate
 from sfa.trust.credential import Credential
 from sfa.trust.gid import GID
 ########## 
-# a helper class to implement the bootstrapping of crypto. material
+# a helper class to implement the bootstrapping of cryptoa. material
 # assuming we are starting from scratch on the client side 
 # what's needed to complete a full slice creation cycle
 # (**) prerequisites: 
@@ -52,7 +53,11 @@ from sfa.trust.gid import GID
 #      obtained at the registry with Resolve
 #      using the (step2) user-credential as credential
 #      default filename is <hrn>.<type>.cred
-
+#
+# (**) additionnally, it might make sense to upgrade a GID file 
+# into a pkcs12 certificate usable in a browser
+# this bundled format allows for embedding the private key
+# 
 
 ########## Implementation notes
 #
@@ -88,6 +93,11 @@ from sfa.trust.gid import GID
 # for Java is documented below
 # http://nam.ece.upatras.gr/fstoolkit/trac/wiki/JavaSFAClient
 #
+# (*) pkcs12
+# 
+# the implementation of the pkcs12 wrapping, which is a late addition,
+# is done through direct calls to openssl
+#
 ####################
 
 class SfaClientException (Exception): pass
@@ -194,6 +204,22 @@ class SfaClientBootstrap:
         return output
 
 
+# http://trac.myslice.info/wiki/MySlice/Developer/SFALogin
+### produce a pkcs12 bundled certificate from GID and private key
+# xxx for now we put a hard-wired password that's just, well, 'password'
+# when leaving this empty on the mac, result can't seem to be loaded in keychain..
+    def my_pkcs12_produce (self, filename):
+        password=raw_input("Enter password for p12 certificate: ")
+        openssl_command=['openssl', 'pkcs12', "-export"]
+        openssl_command += [ "-password", "pass:%s"%password ]
+        openssl_command += [ "-inkey", self.private_key_filename()]
+        openssl_command += [ "-in",    self.my_gid_filename()]
+        openssl_command += [ "-out",   filename ]
+        if subprocess.call(openssl_command) ==0:
+            print "Successfully created %s"%filename
+        else:
+            print "Failed to create %s"%filename
+
     # Returns True if credential file is valid. Otherwise return false.
     def validate_credential(self, filename):
         valid = True
@@ -260,7 +286,8 @@ class SfaClientBootstrap:
         return self.gid_filename (self.hrn, "user")
     def gid_filename (self, hrn, type): 
         return self.fullpath ("%s.%s.gid"%(hrn,type))
-    
+    def my_pkcs12_filename (self):
+        return self.fullpath ("%s.p12"%self.hrn)
 
 # optimizing dependencies
 # originally we used classes GID or Credential or Certificate 
@@ -327,6 +354,9 @@ class SfaClientBootstrap:
     @get_or_produce (my_gid_filename, my_gid_produce)
     def my_gid (self): pass
 
+    @get_or_produce (my_pkcs12_filename, my_pkcs12_produce)
+    def my_pkcs12 (self): pass
+
     @get_or_produce (credential_filename, credential_produce, validate_credential)
     def credential (self, hrn, type): pass
 
index 213f755..2f8a2a8 100644 (file)
@@ -1513,6 +1513,9 @@ $ sfi m
         # enable info by default
         self.logger.setLevelFromOptVerbose(self.options.verbose+1)
         ### the rough sketch goes like this
+        # (0) produce a p12 file
+        self.client_bootstrap.my_pkcs12()
+
         # (a) rain check for sufficient config in sfi_config
         myslice_dict={}
         myslice_keys=['backend', 'delegate', 'platform', 'username']
@@ -1597,8 +1600,8 @@ $ sfi m
             if uploader.upload(delegated_credential,message=message):
                 count_success+=1
             count_all+=1
-
         self.logger.info("Successfully uploaded %d/%d credentials"%(count_success,count_all))
+
         # at first I thought we would want to save these,
         # like 'sfi delegate does' but on second thought
         # it is probably not helpful as people would not