Commit 2e9a1e86 authored by Sebastien Decugis's avatar Sebastien Decugis
Browse files

Added CA helper script

parent 5ad04672
......@@ -17,7 +17,7 @@ or edit the CCmakeCache.txt file directly.
Note that there are dependencies on external tools that may not be enforced by the configure script.
On Ubuntu Intrepid, the following packages were required (aptitude install ...):
gcc make flex bison libsctp1 libsctp-dev cmake
gcc make flex bison libsctp1 libsctp-dev cmake libgnutls-dev libgcrypt-dev
On FreeBSD the following packages were required:
cmake flex bison
......
#!/usr/bin/make -s
#
# This file is designed to automatize the CA tasks such as:
# -> init : create the initial CA tree and the CA root certificate.
# -> newcsr: create a new private key and csr. $name and $email must be set. C, ST, L, O, OU may be overwitten (exemple: make newcsr C=FR)
# -> cert : sign a pending CSR and generate the certificate. $name must be provided.
# -> revoke: revoke a certificate. $name must be provided.
# -> gencrl: update/create the CRL.
#
# The file should be located in the directory STATIC_DIR as defined below.
# The DIR directory will contain the data of the CA. It might be placed in /var.
# The DIR should also be configured in openssl.cnf file under [ CA_default ]->dir.
#
# Here are the steps to install the CA scripts in default environment:
## mkdir /etc/openssl-ca.static
## cp Makefile openssl.cnf /etc/openssl-ca.static
# ( configure the default parameters of your CA in /etc/openssl-ca/openssl.cnf ) ##
## mkdir /etc/openssl-ca
## make -f /etc/openssl-ca.static/Makefile destroy force=y
## cd /etc/openssl-ca
## make init
## make help
DIR = /etc/openssl-ca
STATIC_DIR = /etc/openssl-ca.static
CONFIG = -config $(DIR)/openssl.cnf
#Defaults for new CSR
C = JP
ST = Tokyo
L = Koganei
O = WIDE
OU = "AAA WG"
#Values for the CA
CA_CN = chavroux.cowaddict.org
CA_mail = sdecugis@nict.go.jp
#Disable "make destroy"
force =
# Default: print the help
all: help
# Help message
help:
@echo "\n\
Default values (can be overwritten on command-line):\n\
[C=$(C)] [ST=$(ST)] [L=$(L)] [O=$(O)] [OU=$(OU)]\n\
[CA_CN=$(CA_CN)] [CA_mail=$(CA_mail)]\n\n\
Available commands:\n\
make init\n\
Creates the initial CA structure in $(DIR)\n\
make gencrl\n\
Regenerates the CRL. Should be run at least once a month.\n\
make newcsr name=foo email=b@r\n\
Create private key and csr in clients subdir (named foo.*)\n\
make cert name=foo\n\
Signs the CSR foo.csr and creates the certificate foo.cert.\n\
make revoke name=foo\n\
Revokes the certificate foo.cert and regenerates the CRL.\n\
\n\
Notes:\n\
Content from public-www should be available from Internet. \n\
The URL to CRL should be set in openssl.cnf.\n\
A cron job should execute make gencrl once a month.\n\
";
# Destroy the CA completly. Use with care.
destroy:
@if [ -z "$(force)" ]; then echo "Restart disabled, use: make destroy force=y"; exit 1; fi
@if [ ! -d $(STATIC_DIR) ]; then echo "Error in setup"; exit 1; fi
@echo "Removing everything (for debug purpose)..."
@rm -rf $(DIR)/*
@ln -sf $(STATIC_DIR)/Makefile $(DIR)
@ln -sf $(STATIC_DIR)/openssl.cnf $(DIR)
# Initialize the CA structure and keys.
init:
@if [ -d $(DIR)/private ]; then echo "CA already initialized."; exit 1; fi
@echo "Creating CA structure..."
@mkdir $(DIR)/crl
@mkdir $(DIR)/certs
@mkdir $(DIR)/newcerts
@mkdir $(DIR)/public-www
@mkdir $(DIR)/private
@chmod 700 $(DIR)/private
@mkdir $(DIR)/clients
@mkdir $(DIR)/clients/privkeys
@mkdir $(DIR)/clients/csr
@mkdir $(DIR)/clients/certs
@echo "01" > $(DIR)/serial
@touch $(DIR)/index.txt
@openssl req $(CONFIG) -new -batch -x509 -days 3650 -nodes -newkey rsa:2048 -out $(DIR)/public-www/cacert.pem \
-keyout $(DIR)/private/cakey.pem -subj /C=$(C)/ST=$(ST)/L=$(L)/O=$(O)/OU=$(OU)/CN=$(CA_CN)/emailAddress=$(CA_mail)
@ln -s $(DIR)/public-www/cacert.pem $(DIR)/certs/`openssl x509 -noout -hash < $(DIR)/public-www/cacert.pem`.0
@$(MAKE) -f $(DIR)/Makefile gencrl
# 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 \
-batch
@ln -s $(DIR)/clients/certs/$(name).cert $(DIR)/certs/`openssl x509 -noout -hash < $(DIR)/clients/certs/$(name).cert`.0
# 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 ]; \
echo "$(DIR)/clients/certs/$(name).cert 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
# End of file...
#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#
# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)
[ new_oids ]
# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /etc/openssl-ca # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # 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.
certificate = $dir/public-www/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
# crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/public-www/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extentions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha1 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
# policy = policy_match
policy = policy_anything
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
# Passwords for private keys if not present they will be prompted for
# input_password = haikusecret
# output_password = haikusecret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr
# req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = JP
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Kanagawa
localityName = Locality Name (eg, city)
localityName_default = Shin-Kawasaki
0.organizationName = Organization Name (eg, company)
0.organizationName_default = WIDE
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Nautilus6 WG
commonName = Common Name (i.e. Home Agent hostname)
commonName_max = 64
emailAddress = Email Address (i.e. HA administrator)
emailAddress_max = 64
# SET-ex3 = SET extension number 3
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 0
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always
[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
......@@ -66,6 +66,53 @@
#ListenOn = "202.249.37.5";
#ListenOn = "2001:200:903:2::202:1";
##############################################################
## TLS Configuration
# TLS is managed by the GNUTLS library in the freeDiameter daemon.
# You may find more information about parameters and special behaviors
# in the relevant documentation.
# http://www.gnu.org/software/gnutls/manual/
# Credentials of the local peer
# The X509 certificate and private key file to use for the local peer.
# The files must contain PKCS-1 encoded RSA key, in PEM format.
# (These parameters are passed to gnutls_certificate_set_x509_key_file function)
# Default : NO DEFAULT
#TLS_Cred = "<x509 certif file.PEM>" , "<x509 private key file.PEM>";
# Certificate authority / trust anchors
# The file containing the list of trusted Certificate Authorities (PEM list)
# (This parameter is passed to gnutls_certificate_set_x509_trust_file function)
# The directive can appear several times to specify several files.
# Default : GNUTLS default behavior
#TLS_CA = "<file.PEM>";
# Certificate Revocation List file
# The information about revoked certificates.
# The file contains a list of trusted CRLs in PEM format. They should have been verified before.
# (This parameter is passed to gnutls_certificate_set_x509_crl_file function)
# Default : GNUTLS default behavior
#TLS_CRL = "<file.PEM>";
# GNU TLS Priority string
# This string allows to configure the behavior of GNUTLS key exchanges
# algorithms. See gnutls_priority_init function documentation for information.
# You should also refer to the Diameter required TLS support here:
# http://tools.ietf.org/html/draft-ietf-dime-rfc3588bis-18#section-13.1
# Default : "NORMAL"
# Example: TLS_Prio = "NONE:+VERS-TLS1.1:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL";
#TLS_Prio = "NORMAL";
# Diffie-Hellman parameters size
# Set the number of bits for generated DH parameters
# Valid value should be 768, 1024, 2048, 3072 or 4096.
# (This parameter is passed to gnutls_dh_params_generate2 function,
# it usually should match RSA key size)
# Default : 1024
#TLS_DH_Bits = 1024;
##############################################################
## Timers configuration
......
......@@ -37,6 +37,13 @@
/* Configuration management */
#ifndef GNUTLS_DEFAULT_PRIORITY
# define GNUTLS_DEFAULT_PRIORITY "NORMAL"
#endif /* GNUTLS_DEFAULT_PRIORITY */
#ifndef GNUTLS_DEFAULT_DHBITS
# define GNUTLS_DEFAULT_DHBITS 1024
#endif /* GNUTLS_DEFAULT_DHBITS */
/* Initialize the fd_g_config structure to default values */
int fd_conf_init()
{
......@@ -62,6 +69,10 @@ int fd_conf_init()
CHECK_FCT( fd_dict_init(&fd_g_config->cnf_dict) );
CHECK_FCT( fd_fifo_new(&fd_g_config->cnf_main_ev) );
/* TLS parameters */
CHECK_GNUTLS_DO( gnutls_certificate_allocate_credentials (&fd_g_config->cnf_sec_data.credentials), return ENOMEM );
CHECK_GNUTLS_DO( gnutls_dh_params_init (&fd_g_config->cnf_sec_data.dh_cache), return ENOMEM );
return 0;
}
......@@ -110,6 +121,7 @@ void fd_conf_dump()
li = li->next;
}
}
fd_log_debug(" Flags : - IP ........... : %s\n", fd_g_config->cnf_flags.no_ip4 ? "DISABLED" : "Enabled");
fd_log_debug(" - IPv6 ......... : %s\n", fd_g_config->cnf_flags.no_ip6 ? "DISABLED" : "Enabled");
fd_log_debug(" - Relay app .... : %s\n", fd_g_config->cnf_flags.no_fwd ? "DISABLED" : "Enabled");
......@@ -121,11 +133,14 @@ void fd_conf_dump()
#endif /* DISABLE_SCTP */
fd_log_debug(" - Pref. proto .. : %s\n", fd_g_config->cnf_flags.pr_tcp ? "TCP" : "SCTP");
fd_log_debug(" - TLS method ... : %s\n", fd_g_config->cnf_flags.tls_alg ? "INBAND" : "Separate port");
fd_log_debug(" TLS : - Certificate .. : %s\n", fd_g_config->cnf_sec_data.cert_file ?: "(none)");
fd_log_debug(" - Private key .. : %s\n", fd_g_config->cnf_sec_data.key_file ?: "(none)");
fd_log_debug(" - CA ........... : %s\n", fd_g_config->cnf_sec_data.ca_file ?: "(none)");
fd_log_debug(" TLS : - Certificate .. : %s\n", fd_g_config->cnf_sec_data.cert_file ?: "(NONE)");
fd_log_debug(" - Private key .. : %s\n", fd_g_config->cnf_sec_data.key_file ?: "(NONE)");
fd_log_debug(" - CA (trust) ... : %s\n", fd_g_config->cnf_sec_data.ca_file ?: "(none)");
fd_log_debug(" - CRL .......... : %s\n", fd_g_config->cnf_sec_data.crl_file ?: "(none)");
fd_log_debug(" - Priority ..... : %s\n", fd_g_config->cnf_sec_data.prio_string ?: "(default)");
fd_log_debug(" - Priority ..... : %s\n", fd_g_config->cnf_sec_data.prio_string ?: "(default: '" GNUTLS_DEFAULT_PRIORITY "')");
fd_log_debug(" - DH bits ...... : %d\n", fd_g_config->cnf_sec_data.dh_bits ?: GNUTLS_DEFAULT_DHBITS);
fd_log_debug(" Origin-State-Id ........ : %u\n", fd_g_config->cnf_orstateid);
}
......@@ -149,6 +164,12 @@ int fd_conf_parse()
/* close the file */
fclose(fddin);
/* Check that TLS private key was given */
if (! fd_g_config->cnf_sec_data.key_file) {
fprintf(stderr, "Missing private key configuration for TLS. Please provide the TLS_cred configuration directive.\n");
return EINVAL;
}
/* Resolve hostname if not provided */
if (fd_g_config->cnf_diamid == NULL) {
#ifndef HOST_NAME_MAX
......@@ -207,11 +228,22 @@ int fd_conf_parse()
return EINVAL;
}
/* TLS parameters */
CHECK_GNUTLS_DO( gnutls_certificate_allocate_credentials (&fd_g_config->cnf_sec_data.credentials), return ENOMEM );
/* Configure TLS default parameters */
if (! fd_g_config->cnf_sec_data.prio_string) {
const char * err_pos = NULL;
CHECK_GNUTLS_DO( gnutls_priority_init(
&fd_g_config->cnf_sec_data.prio_cache,
GNUTLS_DEFAULT_PRIORITY,
&err_pos),
{ TRACE_DEBUG(INFO, "Error in priority string at position : %s", err_pos); return EINVAL; } );
}
if (! fd_g_config->cnf_sec_data.dh_bits) {
CHECK_GNUTLS_DO( gnutls_dh_params_generate2(
fd_g_config->cnf_sec_data.dh_cache,
GNUTLS_DEFAULT_DHBITS),
{ TRACE_DEBUG(INFO, "Error in DH bits value : %d", GNUTLS_DEFAULT_DHBITS); return EINVAL; } );
}
CHECK_GNUTLS_DO( gnutls_dh_params_init (&fd_g_config->cnf_sec_data.dh_cache), return ENOMEM );
return 0;
}
......@@ -130,6 +130,11 @@ qstring \"[^\"\n]*\"
(?i:"ConnectPeer") { return CONNPEER; }
(?i:"ConnectTo") { return CONNTO; }
(?i:"No_TLS") { return NOTLS; }
(?i:"TLS_Cred") { return TLS_CRED; }
(?i:"TLS_CA") { return TLS_CA; }
(?i:"TLS_CRL") { return TLS_CRL; }
(?i:"TLS_Prio") { return TLS_PRIO; }
(?i:"TLS_DH_bits") { return TLS_DH_BITS; }
/* Valid single characters for yyparse */
......
......@@ -111,13 +111,18 @@ struct peer_info fddpi;
%token LOADEXT
%token CONNPEER
%token CONNTO
%token TLS_CRED
%token TLS_CA
%token TLS_CRL