Index: contrib/ca_script2/Makefile
===================================================================
--- contrib/ca_script2/Makefile	(revision 45)
+++ contrib/ca_script2/Makefile	(revision 46)
@@ -3,13 +3,21 @@
 # This file is inspired from freeDiameter's contrib/ca_script and
 # improved to handle multiple CA in a hierarchical fashion.
+# Warning: the directory structure is flat, does not reflect the CA hierarchy
 
 SCRIPT_DIR = .
+DATA_DIR = ./ca_data
+
 CONFIG = -config $(SCRIPT_DIR)/openssl.cnf
 REMAKE = $(MAKE) -f $(SCRIPT_DIR)/Makefile
-DATA_DIR = ./test
 
-#Disable "make destroy"
+#Disable "make destroy" -- overwrite on command line
 force = 
 
+#RSA key sizes, can be overwritten on command line
+cakeysize = 2048
+keysize = 1024
+
+# Save current date
+DATE=`date +%Y%m%d-%H%M%S`
 
 # Default: print the help
@@ -22,14 +30,12 @@
    make init topca=name\n\
        Creates the initial top-level CA structure\n\
-   make new_ca name=caname\n\
+   make newca name=newcaname ca=parentca\n\
        Creates a new sub-CA that can be used for certificates later.\n\
-   make newcsr name=foo ca=bar\n\
-       Create private key and csr in clients subdir (named foo.*)\n\
-   make cert name=foo ca=bar\n\
-       Signs the CSR foo.csr and creates the certificate foo.cert (signed by bar).\n\
-   make revoke name=foo ca=bar\n\
-       Revokes the certificate foo.cert issued by bar and regenerates the CRL.\n\
-   make gencrl ca=bar\n\
-       Regenerates the CRL for CA bar. Should be run at least once a month.\n\
+   make newcert name=foo ca=parentca\n\
+       Create private key and csr, then issue the certificate (named foo.*)\n\
+   make revoke name=foo ca=parentca\n\
+       Revokes the certificate foo.cert issued by parentca and regenerates the CRL.\n\
+   make gencrl ca=caname\n\
+       Regenerates the CRL of CA caname. Should be run periodically.\n\
 \n\
 ";
@@ -46,85 +52,98 @@
 	@if [ -z "$(caname)" ]; then echo "Internal error: caname is missing"; exit 1; fi
 	@if [ -d $(DATA_DIR)/$(caname) ]; then echo "CA $(caname) already exists."; exit 1; fi
-	@echo "Creating CA structure..."
-	@mkdir $(DATA_DIR)/$(caname)/crl
-	@mkdir $(DATA_DIR)/$(caname)/certs
-	@mkdir $(DATA_DIR)/$(caname)/newcerts
-	@mkdir $(DATA_DIR)/$(caname)/public-www
+	# Creating CA structure
+	@mkdir -p $(DATA_DIR)/$(caname)
+	@mkdir $(DATA_DIR)/$(caname)/public
 	@mkdir $(DATA_DIR)/$(caname)/private
 	@chmod 700 $(DATA_DIR)/$(caname)/private
 	@mkdir $(DATA_DIR)/$(caname)/clients
-	@mkdir $(DATA_DIR)/$(caname)/clients/privkeys
-	@mkdir $(DATA_DIR)/$(caname)/clients/csr
-	@mkdir $(DATA_DIR)/$(caname)/clients/certs
 	@echo "01" > $(DATA_DIR)/$(caname)/serial
+	@echo "01" > $(DATA_DIR)/$(caname)/crlnumber
 	@touch $(DATA_DIR)/$(caname)/index.txt
 	
 # Initialize the top-level CA structure and keys.
 init:
-	@if [ -z "$(topca)" ]; then echo "Please specify the name of the CA in as topca=name.testbed.aaa"; exit 1; fi
+	@if [ -z "$(topca)" ]; then echo "Please specify the name of the root CA. Ex: make init topca=rootca.testbed.aaa"; exit 1; fi
 	# Create the folder hierarchy
 	@$(REMAKE) structure caname=$(topca)
 	# Generate the self-signed certificate
-	@CA_ROOT_DIR=$(DATA_DIR)/$(topca) openssl req $(CONFIG) -new -batch -x509 -nodes -newkey rsa:2048 -out $(DATA_DIR)/$(topca)/public-www/cacert.pem \
+	@CA_ROOT_DIR=$(DATA_DIR)/$(topca) openssl req $(CONFIG) -new -batch -x509 -nodes -newkey rsa:$(cakeysize) -out $(DATA_DIR)/$(topca)/public/cacert.pem \
 		-keyout $(DATA_DIR)/$(topca)/private/cakey.pem -subj /CN=$(topca)
-	# Add the certificate hash
-	@ln -s $(DATA_DIR)/$(topca)/public-www/cacert.pem $(DATA_DIR)/$(topca)/certs/`openssl x509 -noout -hash < $(DATA_DIR)/$(topca)/public-www/cacert.pem`.0
+	@ln -s cacert.pem $(DATA_DIR)/$(topca)/public/`openssl x509 -noout -hash < $(DATA_DIR)/$(topca)/public/cacert.pem`.0
+	@touch $(DATA_DIR)/$(topca)/public/parents.pem
 	@$(REMAKE) gencrl ca=$(topca)
 
 # Create a secondary CA
 newca:
+	@if [ -z "$(name)" -o -z "$(ca)" ]; then echo "Missing parameter. Ex: make newca name=subca.testbed.aaa ca=rootca.testbed.aaa"; exit 1; fi
+	@if [ ! -e $(DATA_DIR)/$(ca)/private/cakey.pem ]; then echo "The parent CA $(ca) does not exist."; exit 1; fi
+	@if [ ! -d $(DATA_DIR)/$(name) ]; then $(REMAKE) structure caname=$(name); fi
+	# Generate the private key and CSR for the new CA if needed
+	@if [ ! -e $(DATA_DIR)/$(name)/private/cakey.pem ]; then \
+		openssl genrsa -out $(DATA_DIR)/$(name)/private/cakey.pem $(cakeysize) ; fi
+	@if [ ! -e $(DATA_DIR)/$(name)/private/cacsr.pem ]; then \
+		CA_ROOT_DIR=$(DATA_DIR)/$(name) openssl req $(CONFIG) -new -batch -out $(DATA_DIR)/$(name)/private/cacsr.pem \
+			-key $(DATA_DIR)/$(name)/private/cakey.pem \
+			-subj /CN=$(name) -reqexts v3_req_ca; fi
+	# Revoke a previous certificate for this CA if any
+	@if [ -e $(DATA_DIR)/$(name)/public/cacert.pem ]; then \
+		echo "Revoking previous certificate ..."; \
+		$(REMAKE) revoke name=$(name) ca=$(ca); \
+		mv $(DATA_DIR)/$(name)/public/cacert.pem $(DATA_DIR)/$(name)/public/cacert-$(DATE).pem; fi
+	# Issue the new CA certificate
+	@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -in $(DATA_DIR)/$(name)/private/cacsr.pem \
+		-out $(DATA_DIR)/$(name)/public/cacert.pem \
+		-batch -extensions ca_cert
+	# Hash and link to parent
+	@ln -s cacert.pem $(DATA_DIR)/$(ca)/public/`openssl x509 -noout -hash < $(DATA_DIR)/$(name)/public/cacert.pem`.0
+	@rm -f $(DATA_DIR)/$(name)/parent
+	@ln -s ../$(ca) $(DATA_DIR)/$(name)/parent
+	@cat $(DATA_DIR)/$(ca)/public/parents.pem $(DATA_DIR)/$(ca)/public/cacert.pem > $(DATA_DIR)/$(name)/public/parents.pem
 
+# Create a new certificate for use in TLS communications and other terminal usages
+newcert:
+	@if [ -z "$(name)" -o -z "$(ca)" ]; then echo "Missing parameter. Ex: make newcert name=service.testbed.aaa ca=ca.testbed.aaa"; exit 1; fi
+	@if [ ! -e $(DATA_DIR)/$(ca)/private/cakey.pem ]; then echo "The parent CA $(ca) does not exist."; exit 1; fi
+	@if [ ! -d $(DATA_DIR)/$(ca)/clients/$(name) ]; then mkdir $(DATA_DIR)/$(ca)/clients/$(name); fi
+	# Create a private key if needed
+	@if [ ! -e $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem ]; then \
+		openssl genrsa -out $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem $(keysize); fi
+	# Create a CSR if needed
+	@if [ ! -e $(DATA_DIR)/$(ca)/clients/$(name)/csr.pem ]; then \
+		CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl req $(CONFIG) -new -batch -out $(DATA_DIR)/$(ca)/clients/$(name)/csr.pem \
+			-key $(DATA_DIR)/$(ca)/clients/$(name)/privkey.pem \
+			-subj /CN=$(name); fi
+	# Revoke a previous certificate if any
+	@if [ -e $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem ]; then \
+		$(REMAKE) revoke name=$(name) ca=$(ca); \
+		mv $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem $(DATA_DIR)/$(ca)/clients/$(name)/cert-$(DATE).pem; fi
+	# Now sign the new certificate with the CA key
+	@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -in $(DATA_DIR)/$(ca)/clients/$(name)/csr.pem \
+		-out $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem \
+		-batch
+	# Hash
+	@ln -sf `cat $(DATA_DIR)/$(ca)/serial.old`.pem $(DATA_DIR)/$(ca)/public/`openssl x509 -noout -hash < $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem`.0
+	# Compiled informations for the client
+	@cat $(DATA_DIR)/$(ca)/public/parents.pem $(DATA_DIR)/$(ca)/public/cacert.pem > $(DATA_DIR)/$(ca)/clients/$(name)/ca.pem
+	@ln -sf ../../public/crl.pem $(DATA_DIR)/$(ca)/clients/$(name)/crl.pem
 
-
-############
-# En dessous ce n est pas fini...
-
-
-
-# Regenerate the Certificate Revocation List.
-# This list should be available publicly
-gencrl:
-	@openssl ca $(CONFIG) -gencrl -out $(DIR)/public-www/crl.pem
-	@ln -sf $(DIR)/public-www/crl.pem $(DIR)/crl/`openssl crl -noout -hash < $(DIR)/public-www/crl.pem`.r0
-
-# Create a new private key and a CSR, in case the client does not provide the CSR by another mean.
-# Usage is: make newcsr name=peer.client.fqdn email=admin@client.fqdn
-newcsr:
-	@if [ -z "$(name)" -o -z "$(email)" ]; then echo "Please provide certificate name and email address: make newcsr name=mn.nautilus.org email=you@mail.com"; exit 1; fi
-	@if [ -e $(DIR)/clients/csr/$(name).csr ]; then echo "There is already a pending csr for this name."; exit 1; fi
-	@if [ ! -e $(DIR)/clients/privkeys/$(name).key.pem ]; \
-		then echo "Generating a private key for $(name) ..."; \
-		openssl genrsa -out $(DIR)/clients/privkeys/$(name).key.pem 1024; \
-		fi;
-	@echo "Creating the CSR in $(DIR)/clients/csr/$(name).csr";
-	@openssl req $(CONFIG) -new -batch -out $(DIR)/clients/csr/$(name).csr \
-		-key $(DIR)/clients/privkeys/$(name).key.pem \
-		-subj /C=$(C)/ST=$(ST)/L=$(L)/O=$(O)/OU=$(OU)/CN=$(name)/emailAddress=$(email)
-
-# Process a CSR to create a x509 certificate. The certificate is valid for 1 year. 
-# It should be sent to the client by any mean.
-cert:
-	@if [ -z "$(name)" ]; then echo "name must be provided: make cert name=mn.n6.org"; exit 1; fi
-	@if [ ! -e $(DIR)/clients/csr/$(name).csr ]; then echo "Could not find CSR in $(DIR)/clients/csr/$(name).csr."; exit 1; fi
-	@if [ -e $(DIR)/clients/certs/$(name).cert ]; \
-		then echo "Revoking old certificate..."; \
-		$(MAKE) revoke name=$(name); \
-		fi;
-	@openssl ca $(CONFIG) -in $(DIR)/clients/csr/$(name).csr \
-		-out $(DIR)/clients/certs/$(name).cert \
-		-days $(DAYS) \
-		-batch
-	@ln -s $(DIR)/clients/certs/$(name).cert $(DIR)/certs/`openssl x509 -noout -hash < $(DIR)/clients/certs/$(name).cert`.0
-
-# Revoke a certificate.
+# Revoke a certificate
 revoke:
-	@if [ -z "$(name)" ]; then echo "name must be provided: make revoke name=mn.n6.org"; exit 1; fi
-	@if [ ! -e $(DIR)/clients/certs/$(name).cert ]; \
-		then echo "$(DIR)/clients/certs/$(name).cert not found"; \
+	@if [ -z "$(name)" -o -z "$(ca)" ]; then echo "Missing parameter. Ex: make revoke name=service.testbed.aaa ca=ca.testbed.aaa"; exit 1; fi
+	@if [ ! -e $(DATA_DIR)/$(ca)/private/cakey.pem ]; then echo "The parent CA $(ca) does not exist."; exit 1; fi
+	@if [ ! -e $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem ]; \
+		then echo "$(DATA_DIR)/$(ca)/clients/$(name)/cert.pem not found"; \
 		exit 1; \
 		fi;
-	@openssl ca $(CONFIG) -revoke $(DIR)/clients/certs/$(name).cert;
-	@rm -f $(DIR)/certs/`openssl x509 -noout -hash < $(DIR)/clients/certs/$(name).cert`.0
-	@$(MAKE) gencrl
+	# Revoke the certificate
+	@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -revoke $(DATA_DIR)/$(ca)/clients/$(name)/cert.pem;
+	@$(REMAKE) gencrl ca=$(ca)
 	
+# Regenerate the Certificate Revocation List.
+gencrl:
+	@if [ -z "$(ca)" ]; then echo "Missing parameter. Ex: make gencrl ca=ca.testbed.aaa"; exit 1; fi
+	# Create the CRL (keep the old one?)
+	@CA_ROOT_DIR=$(DATA_DIR)/$(ca) openssl ca $(CONFIG) -gencrl -out $(DATA_DIR)/$(ca)/public/crl.pem
+	@ln -s crl.pem $(DATA_DIR)/$(ca)/public/`openssl crl -noout -hash < $(DATA_DIR)/$(ca)/public/crl.pem`.r0
+
 # End of file...
Index: contrib/ca_script2/openssl.cnf
===================================================================
--- contrib/ca_script2/openssl.cnf	(revision 45)
+++ contrib/ca_script2/openssl.cnf	(revision 46)
@@ -60,15 +60,15 @@
 
 dir		= $ENV::CA_ROOT_DIR	# Where everything is kept
-certs		= $dir/certs		# Where the issued certs are kept
-crl_dir		= $dir/crl		# Where the issued crl are kept
+certs		= $dir/public		# Where the issued certs are kept
+crl_dir		= $dir/public		# Where the issued crl are kept
 database	= $dir/index.txt	# database index file.
 #unique_subject	= no			# Set to 'no' to allow creation of
 					# several ctificates with same subject.
-new_certs_dir	= $dir/newcerts		# default place for new certs.
+new_certs_dir	= $dir/public		# default place for new certs.
 
-certificate	= $dir/public-www/cacert.pem 	# The CA certificate
+certificate	= $dir/public/cacert.pem 	# The CA certificate
 serial		= $dir/serial 		# The current serial number
 crlnumber	= $dir/crlnumber	# the current crl number
-crl		= $dir/public-www/crl.pem 		# The current CRL
+crl		= $dir/public/crl.pem 		# The current CRL
 private_key	= $dir/private/cakey.pem	# The private key
 x509_extensions	= usr_cert		# The extentions to add to the cert
