Index: fedd/access_to_abac.py
===================================================================
--- fedd/access_to_abac.py	(revision 3ff5e2a076bf693b1f92a26571a58e4da398adcb)
+++ fedd/access_to_abac.py	(revision 353db8cf818f61d7d34c74ad0449f921d11ffa52)
@@ -51,5 +51,5 @@
 	    return "%s.%s <- %s" % (self.principal, self.attr, self.req)
 
-# Mappinng generation functiona and the access parser throw these when there is
+# Mappinng generation function and the access parser throw these when there is
 # a parsing problem.
 class parse_error(RuntimeError): pass
Index: fedd/creddy_split.py
===================================================================
--- fedd/creddy_split.py	(revision 3ff5e2a076bf693b1f92a26571a58e4da398adcb)
+++ fedd/creddy_split.py	(revision 353db8cf818f61d7d34c74ad0449f921d11ffa52)
@@ -6,4 +6,5 @@
 
 from optparse import OptionParser
+from federation.util import abac_split_cert, abac_pem_type
 
 # Options
@@ -20,14 +21,4 @@
 			'default: [%default]'))
 
-class diversion:
-    '''
-    Wraps up the reqular expression to start and end a diversion, as well as
-    the open file that gets the lines.
-    '''
-    def __init__(self, start, end, fn):
-	self.start = re.compile(start)
-	self.end = re.compile(end)
-	self.f = open(fn, 'w')
-
 # Option validation
 parser = Parser()
@@ -40,40 +31,15 @@
     sys.exit('\nMust have one file argument')
 
-if not opts.force:
-    for fn in (opts.cert, opts.key):
-	if os.access(fn, os.F_OK):
-	    sys.exit('%s exists.  --force to overwite it' % fn)
+for fn in (opts.cert, opts.key):
+    if os.access(fn, os.F_OK):
+	if opts.force: os.unlink(fn)
+	else: sys.exit('%s exists.  --force to overwite it' % fn)
 
 try:
-    # Initialize the diversions
-    divs = [diversion(s, e, fn) for s, e,fn in (
-	('\s*-----BEGIN RSA PRIVATE KEY-----$', 
-	    '\s*-----END RSA PRIVATE KEY-----$',
-	    opts.key),
-	('\s*-----BEGIN CERTIFICATE-----$', 
-	    '\s*-----END CERTIFICATE-----$',
-	    opts.cert))]
-
-    # walk through the file, beginning a diversion when a start regexp matches
-    # until the end regexp matches.  While in the two regexps, print each line
-    # to the ipen diversion file (including the two matches).
-    active = None
-    f = open(combo, 'r')
-    for l in f:
-	if active:
-	    if active.end.match(l):
-		print >>active.f, l,
-		active = None
-	else:
-	    for d in divs:
-		if d.start.match(l):
-		    active = d
-		    break
-	if active: print >>active.f, l,
-
-# This clause catches all file opening problems, including the diversion opens
+    type = abac_pem_type(combo)
+    if type == 'both':
+	abac_split_cert(combo, opts.key, opts.cert)
+    else:
+	sys.exit('Cannot split %s as it is a %s' % (combo, type or 'dunno'));
 except EnvironmentError, e:
     sys.exit("%s: %s" % (e.strerror, e.filename or '?!'))
-
-# This is probably unnecessary.  Close all the diversion files.
-for d in divs: d.f.close()
Index: fedd/fedd_create.py
===================================================================
--- fedd/fedd_create.py	(revision 3ff5e2a076bf693b1f92a26571a58e4da398adcb)
+++ fedd/fedd_create.py	(revision 353db8cf818f61d7d34c74ad0449f921d11ffa52)
@@ -6,5 +6,7 @@
 from federation.remote_service import service_caller
 from federation.client_lib import client_opts, exit_with_fault, RPCException, \
-	wrangle_standard_options, do_rpc, get_experiment_names, save_certfile
+	wrangle_standard_options, do_rpc, get_experiment_names, save_certfile,
+	get_abac_certs
+from federation.util import abac_split_cert
 
 class fedd_create_opts(client_opts):
@@ -32,4 +34,13 @@
 		help="Explicit map from testbed label to URI - " + \
 			"deter:https://users.isi.deterlab/net:13232")
+	self.add_option('--gen_cert', action='store_true', dest='gen_cert',
+		default=False,
+		help='generate a cert to which to delegate rights')
+	self.add_option('--delegate', action='store_true', dest='generate',
+		help='Delegate rights to a generated cert (default)')
+	self.add_option('--no-delegate', action='store_true', dest='generate',
+		help='Do not delegate rights to a generated cert')
+
+	self.set_defaults('delegate'=True)
 
 def parse_service(svc):
@@ -78,4 +89,40 @@
 	    }
 
+def delegate(fedid, cert, dir, name=None, debug=False, 
+	creddy='/usr/local/bin/creddy'):
+    '''
+    Make the creddy call to create an attribute delegating rights to the new
+    experiment.  The cert parameter points to a conventional cert & key combo,
+    which we split out into tempfiles, which we delete on return.  The return
+    value if the filename in which the certificate was stored.
+    '''
+
+    certfile = keyfile = None
+    expid = "%s" % fedid
+
+    # Trim the "fedid:"
+    if expid.startswith("fedid:"): expid = expid[6:]
+
+    try:
+	keyfile, certfile = abac_split(cert)
+
+	rv = 0
+	if name: fn = '%s/%s_attr.der' % (dir, name)
+	else: fn = '%s/%s_attr.der' % (dir, expid)
+
+	cmd = [creddy, '--attribute', '--issuer=%s' % certfile, 
+		'--key=%s' % keyfile,
+		'--role=acting_for', '--subject-id=%s' % expid, 
+		'--out=%s' % fn ]
+	if debug:
+	    print join(cmd)
+	    return fn
+	else:
+	    if subprocess.call(cmd) == 0: return fn
+	    else: return None
+    finally:
+	if keyfile: os.unlink(keyfile)
+	if certfile: os.unlink(certfile)
+
 # Main line
 service_re = re.compile('^\\s*#\\s*SERVICE:\\s*([\\S]+)')
@@ -83,5 +130,5 @@
 (opts, args) = parser.parse_args()
 
-
+# Option processing
 cert, fid, url = wrangle_standard_options(opts)
 
@@ -97,4 +144,16 @@
 out_certfile = opts.out_certfile
 
+# If there is no abac directory in which to store a delegated credential, don't
+# delegate.
+if not opts.abac_dir and opts.delegate:
+    opts.delegate = False
+
+# Load ABAC certs
+if opts.abac_dir:
+    try:
+	acerts = get_abac_certs(opts.abac_dir)
+    except EnvironmentError, e:
+	sys.exit('%s: %s' % (e.filename, e.strerror))
+
 # Fill in services
 svcs = []
@@ -102,4 +161,5 @@
     svcs.append(project_export_service(opts.master, opts.project))
 svcs.extend([ parse_service(s) for s in opts.service])
+
 # Parse all the strings that we can pull out of the file using the service_re.
 svcs.extend([parse_service(service_re.match(l).group(1)) \
@@ -117,12 +177,24 @@
     print >>sys.stderr, "Warning:Neither master/project nor services requested"
 
-
+# Construct the New experiment request
 msg = { }
+
+
+# Generate a certificate if requested and put it into the message
+if opts.gen_cert:
+    expid, expcert = generate_fedid(opts.exp_name or 'dummy')
+    msg['experimentAccess'] = { 'X509': expcert }
+else:
+    expid = expcert = None
 
 if opts.exp_name:
     msg['experimentID'] = { 'localname': opts.exp_name }
 
+if acerts:
+    msg['credential'] = acerts
+
 if opts.debug > 1: print >>sys.stderr, msg
 
+# The New call
 try:
     resp_dict = do_rpc(msg, 
@@ -138,4 +210,5 @@
 if opts.debug > 1: print >>sys.stderr, resp_dict
 
+# Save the experiment ID certificate if we need it
 try:
     save_certfile(opts.out_certfile, resp_dict.get('experimentAccess', None))
@@ -147,4 +220,21 @@
     e_local = "serialize"
 
+# If delegation is requested and we have a target, make the delegation, and add
+# the credential to acerts.
+if e_fedid and opts.delegate:
+    new_cert_fn = delegate(e_fedid, cert, key, dir, opts.exp_name)
+    if new_cert_fn is not None:
+	try:
+	    f = open(new_cert_fn, 'r')
+	    acerts.add(f.read())
+	    f.close()
+	except EnvironmentError, e:
+	    sys.exit("Cannot read delegation cert in %s: %s" % \
+		    (e.filename, e.strerror));
+    else:
+	sys.exit("Cannot delegate rights to new experiment: %s/%s" %\
+		(expid, opts.exp_name))
+
+# Construct the Create message
 msg = { 'experimentdescription': { 'ns2description': exp_desc }, }
 
@@ -159,4 +249,7 @@
     sys.exit("New did not return an experiment ID??")
 
+if acerts:
+    msg['credential'] = acerts
+
 if tbmap:
     msg['testbedmap'] = [ { 'testbed': t, 'uri': u } for t, u in tbmap.items() ]
@@ -164,4 +257,5 @@
 if opts.debug > 1: print >>sys.stderr, msg
 
+# make the call
 try:
     resp_dict = do_rpc(msg, 
@@ -177,4 +271,5 @@
 if opts.debug > 1: print >>sys.stderr, resp_dict
 
+# output
 e_fedid, e_local = get_experiment_names(resp_dict.get('experimentID', None))
 st = resp_dict.get('experimentStatus', None)
Index: fedd/fedd_new.py
===================================================================
--- fedd/fedd_new.py	(revision 3ff5e2a076bf693b1f92a26571a58e4da398adcb)
+++ fedd/fedd_new.py	(revision 353db8cf818f61d7d34c74ad0449f921d11ffa52)
@@ -17,5 +17,5 @@
         self.add_option("--experiment_name", dest="exp_name",
                 type="string", help="Suggested experiment name")
-	self.add_option('--gen-cert', action='store_true', dest='gen_cert',
+	self.add_option('--gen_cert', action='store_true', dest='gen_cert',
 		default=False,
 		help='generate a cert to which to delegate rights')
Index: fedd/federation/authorizer.py
===================================================================
--- fedd/federation/authorizer.py	(revision 3ff5e2a076bf693b1f92a26571a58e4da398adcb)
+++ fedd/federation/authorizer.py	(revision 353db8cf818f61d7d34c74ad0449f921d11ffa52)
@@ -11,4 +11,5 @@
 from remote_service import service_caller
 from service_error import service_error
+from util import abac_pem_type, abac_split_cert
 
 
@@ -192,11 +193,24 @@
     attribute_error = authorizer_base.attribute_error
     class no_file(RuntimeError): pass
-
-    def __init__(self, certs=None, me=None, key=None, load=None):
+    class bad_cert(RuntimeError): pass
+
+    def __init__(self, certs=None, me=None, key=None, load=None, save=None):
 	self.creddy = '/usr/local/bin/creddy'
 	self.globals = set()
 	self.lock = Lock()
 	self.me = me
-	self.key = key
+	self.save_dir = load or save
+	# If the me parameter is a combination certificate, split it into the
+	# abac_authorizer save directory (if any) for use with creddy.
+	if abac_pem_type(self.me) == 'both':
+	    if self.save_dir:
+		self.key, self.me = abac_split_cert(self.me,
+			keyfile="%s/key.pem" % self.save_dir, 
+			certfile = "%s/cert.pem" % self.save_dir)
+	    else:
+		raise abac_authorizer.bad_cert("Combination certificate " + \
+			"and nowhere to split it");
+	else:
+	    self.key = key
 	self.context = ABAC.Context()
 	if me:
@@ -216,8 +230,5 @@
 
 	if load:
-	    self.save_dir = load
 	    self.load(load)
-	else:
-	    self.save_dir = None
 
     @staticmethod
@@ -453,5 +464,5 @@
 		st = pickle.load(f)
 		f.close()
-		# Cpoy the useful attributes from the pickled state
+		# Copy the useful attributes from the pickled state
 		for a in ('globals', 'key', 'me', 'cert', 'fedid'):
 		    setattr(self, a, getattr(st, a, None))
Index: fedd/federation/util.py
===================================================================
--- fedd/federation/util.py	(revision 3ff5e2a076bf693b1f92a26571a58e4da398adcb)
+++ fedd/federation/util.py	(revision 353db8cf818f61d7d34c74ad0449f921d11ffa52)
@@ -2,4 +2,5 @@
 
 import re
+import os
 import string
 import logging
@@ -262,4 +263,83 @@
 	    return base
 
+def abac_pem_type(cert):
+    key_re = re.compile('\s*-----BEGIN RSA PRIVATE KEY-----$')
+    cert_re = re.compile('\s*-----BEGIN CERTIFICATE-----$') 
+    type = None
+    f = open(cert, 'r')
+    for line in f:
+	if key_re.match(line):
+	    if type is None: type = 'key'
+	    elif type == 'cert': type = 'both'
+	elif cert_re.match(line):
+	    if type is None: type = 'cert'
+	    elif type == 'key': type = 'both'
+	if type == 'both': break
+    f.close()
+    return type
+
+def abac_split_cert(cert, keyfile=None, certfile=None):
+    """
+    Split the certificate file in cert into a certificate file and a key file
+    in cf and kf respectively.  The ABAC tools generally cannot handle combined
+    certificates/keys.  If kf anc cf are given, they are used, otherwise tmp
+    files are created.  Created tmp files must be deleted.  Problems opening or
+    writing files will cause exceptions.
+    """
+    class diversion:
+	'''
+	Wraps up the reqular expression to start and end a diversion, as well as
+	the open file that gets the lines.
+	'''
+	def __init__(self, start, end, fn):
+	    self.start = re.compile(start)
+	    self.end = re.compile(end)
+	    # Open the file securely with minimal permissions. NB file cannot
+	    # exist before this call.
+	    self.f = os.fdopen(os.open(fn,
+		(os.O_WRONLY | os.O_CREAT | os.O_TRUNC | os.O_EXCL), 0600),
+		'w')
+
+	def close(self):
+	    self.f.close()
+
+    if not keyfile:
+	f, keyfile = mkstemp(suffix=".pem")
+	os.close(f);
+    if not certfile:
+	f, certfile = mkstemp(suffix=".pem")
+	os.close(f);
+
+    # Initialize the diversions
+    divs = [diversion(s, e, fn) for s, e,fn in (
+	('\s*-----BEGIN RSA PRIVATE KEY-----$', 
+	    '\s*-----END RSA PRIVATE KEY-----$',
+	    keyfile),
+	('\s*-----BEGIN CERTIFICATE-----$', 
+	    '\s*-----END CERTIFICATE-----$',
+	    certfile))]
+
+    # walk through the file, beginning a diversion when a start regexp
+    # matches until the end regexp matches.  While in the two regexps,
+    # print each line to the open diversion file (including the two
+    # matches).
+    active = None
+    f = open(cert, 'r')
+    for l in f:
+	if active:
+	    if active.end.match(l):
+		print >>active.f, l,
+		active = None
+	else:
+	    for d in divs:
+		if d.start.match(l):
+		    active = d
+		    break
+	if active: print >>active.f, l,
+
+    # This is probably unnecessary.  Close all the diversion files.
+    for d in divs: d.close()
+    return keyfile, certfile
+
 def find_pickle_problem(o, st=None):
     """
Index: fedd/init_abac_authorizer.py
===================================================================
--- fedd/init_abac_authorizer.py	(revision 3ff5e2a076bf693b1f92a26571a58e4da398adcb)
+++ fedd/init_abac_authorizer.py	(revision 353db8cf818f61d7d34c74ad0449f921d11ffa52)
@@ -1,3 +1,5 @@
 #!/usr/local/bin/python
+
+import sys
 
 from optparse import OptionParser
@@ -16,8 +18,13 @@
 opts, args = parser.parse_args()
 
-if any([ not x for x in (opts.key, opts.cert, opts.policy, opts.out_dir)]):
+if any([ not x for x in (opts.cert, opts.policy, opts.out_dir)]):
     parser.print_help()
     sys.exit(1)
-
-a = abac_authorizer(key=opts.key, me=opts.cert, certs=opts.policy)
-a.save(opts.out_dir)
+try:
+    a = abac_authorizer(key=opts.key, me=opts.cert, certs=opts.policy,
+	    save=opts.out_dir)
+    a.save(opts.out_dir)
+except EnvironmentError, e:
+    sys.exit("Can't create or write %s: %s" % (e.filename, e.strerror))
+except abac_authorizer.bad_cert, e:
+    sys.exit("Error creating authorizer: %s" % e)
