# HG changeset patch # User Sebastien Decugis # Date 1259299601 -32400 # Node ID 5719368fe1ff8667120c6a0da70aeaeacaf2ddf8 # Parent 7ecc7152123b98837c099a8959152def8c583b56 Simplified structure diff -r 7ecc7152123b -r 5719368fe1ff contrib/ca_script2/Makefile --- a/contrib/ca_script2/Makefile Thu Nov 26 18:31:48 2009 +0900 +++ b/contrib/ca_script2/Makefile Fri Nov 27 14:26:41 2009 +0900 @@ -2,15 +2,23 @@ # # 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 all: help @@ -21,16 +29,14 @@ Available commands:\n\ 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\ "; @@ -45,86 +51,99 @@ structure: @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: - - - -############ -# 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 + @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 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) +# 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 -# 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... diff -r 7ecc7152123b -r 5719368fe1ff contrib/ca_script2/openssl.cnf --- a/contrib/ca_script2/openssl.cnf Thu Nov 26 18:31:48 2009 +0900 +++ b/contrib/ca_script2/openssl.cnf Fri Nov 27 14:26:41 2009 +0900 @@ -59,17 +59,17 @@ [ CA_default ] 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 # overwrite with -extensions