From 521c7f6b2b4cd186795c948cccf6349a20e2a561 Mon Sep 17 00:00:00 2001 From: Sergii Ovcharenko Date: Mon, 25 Dec 2017 17:09:58 +0000 Subject: [PATCH 1/8] Makefile fixes --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c3ef381..dd589b1 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ PKG_NAME=$(NAME)_$(VERSION) PKG=$(PKG_DIR)/$(PKG_NAME).tar.gz SIG=$(PKG_DIR)/$(PKG_NAME).asc -PREFIX?=/opt/$(NAME) +PREFIX?=/usr/local/$(NAME) DOC_DIR=$(PREFIX)/doc #DOC_DIR=$(PREFIX)/share/doc/$(PKG_NAME) @@ -42,21 +42,21 @@ tag: release: $(PKG) $(SIG) tag -install: +install: for dir in $(INSTALL_DIRS); do mkdir -p $(PREFIX)/$$dir; done for file in $(INSTALL_FILES); do cp $$file $(PREFIX)/$$file; done mkdir -p $(DOC_DIR) cp -r $(DOC_FILES) $(DOC_DIR)/ symlinks: - for link in $(SCRIPTS); do ln -s $(PREFIX)/bin/$$link /usr/local/bin/$$link + for link in $(SCRIPTS); do ln -s $(PREFIX)/bin/$$link /usr/local/bin/$$link; done uninstall: for file in $(INSTALL_FILES); do rm -f $(PREFIX)/$$file; done rm -rf $(DOC_DIR) rmsymlinks: - for link in $(SCRIPTS); do rm -f /usr/local/bin/$$link + for link in $(SCRIPTS); do rm -f /usr/local/bin/$$link; done .PHONY: build sign clean test tag release install uninstall all From 3520e41449dd09e3c54efd9f5a98afb1ccd145f6 Mon Sep 17 00:00:00 2001 From: Sergii Ovcharenko Date: Mon, 25 Dec 2017 17:14:55 +0000 Subject: [PATCH 2/8] MacOS support --- README.md | 11 +++++++++++ bin/ca-create-cert | 8 ++++++++ bin/ca-init | 8 ++++++++ bin/ca-list-certs | 8 ++++++++ bin/ca-renew-cert | 8 ++++++++ bin/ca-revoke-cert | 8 ++++++++ 6 files changed, 51 insertions(+) diff --git a/README.md b/README.md index 9c32510..1fb7dd2 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,17 @@ This will by default install to `/usr/local`, either `export PREFIX=/path` or `make PREFIX=/path; sudo make PREFIX=/path install` to change this to an alternative location. +MacOS note +------------ + +To make ca-scripts work on MacOS you have to install the following + +``` +brew install coreutils +brew install gnu-getopt +brew install gnu-sed +``` + Creating a Certificate Authority -------------------------------- diff --git a/bin/ca-create-cert b/bin/ca-create-cert index 841074e..1e014aa 100755 --- a/bin/ca-create-cert +++ b/bin/ca-create-cert @@ -1,5 +1,13 @@ #!/bin/bash set -e + +#Add GNU tools to path for MacOS +if [ "Darwin" = `uname -s` ]; then + export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" + export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" +fi + source $(dirname $(readlink -f $0))/../lib/ca-functions ALT_NAMES=() diff --git a/bin/ca-init b/bin/ca-init index 96b8454..ddcd29d 100755 --- a/bin/ca-init +++ b/bin/ca-init @@ -1,5 +1,13 @@ #!/bin/bash set -e + +#Add GNU tools to path for MacOS +if [ "Darwin" = `uname -s` ]; then + export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" + export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" +fi + source $(dirname $(readlink -f $0))/../lib/ca-functions # XXX: Add an interactive mode to this script to obviate the need for a diff --git a/bin/ca-list-certs b/bin/ca-list-certs index acef2a6..006de9d 100755 --- a/bin/ca-list-certs +++ b/bin/ca-list-certs @@ -1,5 +1,13 @@ #!/bin/bash set -e + +#Add GNU tools to path for MacOS +if [ "Darwin" = `uname -s` ]; then + export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" + export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" +fi + source $(dirname $(readlink -f $0))/../lib/ca-functions usage() { diff --git a/bin/ca-renew-cert b/bin/ca-renew-cert index 1ca943f..d6ed522 100755 --- a/bin/ca-renew-cert +++ b/bin/ca-renew-cert @@ -1,5 +1,13 @@ #!/bin/bash set -e + +#Add GNU tools to path for MacOS +if [ "Darwin" = `uname -s` ]; then + export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" + export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" +fi + source $(dirname $(readlink -f $0))/../lib/ca-functions usage() { diff --git a/bin/ca-revoke-cert b/bin/ca-revoke-cert index 63c7f8c..82d974e 100755 --- a/bin/ca-revoke-cert +++ b/bin/ca-revoke-cert @@ -1,5 +1,13 @@ #!/bin/bash set -e + +#Add GNU tools to path for MacOS +if [ "Darwin" = `uname -s` ]; then + export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" + export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" +fi + source $(dirname $(readlink -f $0))/../lib/ca-functions usage() { From 5d8ea3c8e9ca9f26ceb9362058df142b25add3cc Mon Sep 17 00:00:00 2001 From: Sergii Ovcharenko Date: Mon, 25 Dec 2017 16:16:47 +0000 Subject: [PATCH 3/8] Support for local config files --- ca-scripts.conf | 1 + lib/ca-functions | 33 +++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/ca-scripts.conf b/ca-scripts.conf index 3d2d6de..4ec9dd1 100644 --- a/ca-scripts.conf +++ b/ca-scripts.conf @@ -3,6 +3,7 @@ # REQUIRED: CA_HOME provides the path to the root of the CA directory tree # this directory must exist and be writeable +# OPTIONAL for local configurations. Will be defaulted to current dir. #CA_HOME="/etc/ssl/ca-scripts" CA_HOME="/tmp/ca" diff --git a/lib/ca-functions b/lib/ca-functions index 7c9b0af..59193d3 100644 --- a/lib/ca-functions +++ b/lib/ca-functions @@ -2,7 +2,6 @@ # Common functions for ca-scripts. PROGNAME=$( basename $0 ) -CONFFILE="/etc/ca-scripts.conf" OVERRIDE_FILE=/tmp/$$ca_overrides.conf SHAREDIR=$(dirname $(readlink -f $0))/../tpl CRYPTKEY="-nodes" @@ -54,25 +53,31 @@ ca_set_default() { ca_load_conf() { local varname vartest varerr vardef error ca_name - if [ -r "$HOME/.ca-scripts.conf" ]; then - # Does a system-wide config exist? If so load it first. - if [ -r "$CONFFILE" ]; then - source "$CONFFILE" + + if [ -z "$CONFFILECLI" ]; then + # Load system config, user config, local config + if ! [ -r "/etc/ca-scripts.conf" ] && ! [ -r "$HOME/.ca-scripts.conf" ] && ! [ -r "$(pwd)/ca-scripts.conf" ]; then + error "Default configuratation is not set. You can define default configuration at the following locations\n /etc/ca-scripts.conf (System)\n $HOME/.ca-scripts.conf (User)\n $(pwd)/ca-scripts.conf (Local)" fi - # Override system configuration with local values. - # If manually set on command-line, don't load. - if [ -z "$CONFFILECLI" ]; then + + if [ -r "/etc/ca-scripts.conf" ]; then + source "/etc/ca-scripts.conf" + fi + if [ -r "$HOME/.ca-scripts.conf" ]; then source "$HOME/.ca-scripts.conf" + fi + if [ -r "$(pwd)/ca-scripts.conf" ]; then + source "$(pwd)/ca-scripts.conf" + ca_set_default CA_HOME "$(pwd)" fi - elif [ -r "$CONFFILE" ]; then - source "$CONFFILE" - else - if [ -n "$CONFFILECLI" ]; then - error "Unable to load $HOME/.ca-scripts.conf or $CONFFILE" + else + if [ -r "$CONFFILE" ]; then + source "$CONFFILE" else error "Unable to load $CONFFILE" fi - fi + + fi # TODO: Refactored config loader with error fallback, allowing local overrides. #if [ ! -r "$CONFFILE" ]; then From dada56d649ff0a034679498154aa25b06af1c842 Mon Sep 17 00:00:00 2001 From: Sergii Ovcharenko Date: Mon, 25 Dec 2017 14:33:32 +0000 Subject: [PATCH 4/8] Making CA_CRT_TYPE trully optional --- lib/ca-functions | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/ca-functions b/lib/ca-functions index 59193d3..bf3b34f 100644 --- a/lib/ca-functions +++ b/lib/ca-functions @@ -120,12 +120,7 @@ __TESTS__ # the file is created if any USER_CA.* variables are set [ -f $OVERRIDE_FILE ] && source $OVERRIDE_FILE # remove file after sourcing it - [ -f $OVERRIDE_FILE ] && rm -rf $OVERRIDE_FILE - # XXX: and this alternative should probably have better validation ;-) - case "$CA_CRT_TYPE" in - server|client|user) :;; - *) error "Unrecognised certificate type '$CA_CRT_TYPE'!";; - esac + [ -f $OVERRIDE_FILE ] && rm -rf $OVERRIDE_FILE # we need to do these first to use them in other default defs # NOTE: bash's here-string syntax appends \n which tr turns to _ :( @@ -153,6 +148,12 @@ CA_CRT_OU $CA_DN_OU CA_CRT_E $CA_EMAIL CA_DEFAULT_MD sha256 __DEFAULTS__ + +# XXX: and this alternative should probably have better validation ;-) + case "$CA_CRT_TYPE" in + server|client|user) :;; + *) error "Unrecognised certificate type '$CA_CRT_TYPE'!";; + esac } # TODO: Remove this, as it's no longer used. From 3c90c9e28241cc80ea3f13c9b9bf20fbf9ca6bc2 Mon Sep 17 00:00:00 2001 From: Sergii Ovcharenko Date: Mon, 25 Dec 2017 20:24:04 +0000 Subject: [PATCH 5/8] utf-8 by default --- tpl/ca-config.tpl | 3 ++- tpl/req-config.tpl | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tpl/ca-config.tpl b/tpl/ca-config.tpl index 1777dd5..e28ac6d 100644 --- a/tpl/ca-config.tpl +++ b/tpl/ca-config.tpl @@ -146,8 +146,9 @@ default_md = sha1 distinguished_name = ca_req_dn x509_extensions = ca_x509_extensions req_extensions = ca_req_extensions -string_mask = nombstr prompt = no +string_mask = utf8only +utf8 = yes # ---------------------------------------------------------------------------- # # This defines the DN of the CA certificate. diff --git a/tpl/req-config.tpl b/tpl/req-config.tpl index a2312c4..cc3b11d 100644 --- a/tpl/req-config.tpl +++ b/tpl/req-config.tpl @@ -3,8 +3,9 @@ default_bits = %CA_CRT_BITS% default_md = sha1 distinguished_name = req_dn req_extensions = req_%CA_CRT_TYPE%_extensions -string_mask = nombstr prompt = no +string_mask = utf8only +utf8 = yes [ req_dn ] C = %CA_CRT_C% From d8e5d3fb0ebc9b194919c6877dd07a76d7fa8cf3 Mon Sep 17 00:00:00 2001 From: Sergii Ovcharenko Date: Mon, 25 Dec 2017 22:19:22 +0000 Subject: [PATCH 6/8] Rename to tiny-ca Copy templates to CA_HOME Removing docs and tests. I won't be maintaining them anyway... --- Makefile | 13 +- README.md | 156 ++------------- bin/ca-create-cert | 9 +- bin/ca-init | 24 +-- bin/ca-list-certs | 9 +- bin/ca-renew-cert | 9 +- bin/ca-revoke-cert | 9 +- bin/tiny-ca | 38 ++++ ca-scripts.spec | 34 ---- doc/ca-create-cert.pod | 345 -------------------------------- doc/ca-init.pod | 175 ---------------- doc/ca-renew-cert.pod | 95 --------- doc/ca-revoke-cert.pod | 102 ---------- doc/ca-scripts.conf.pod | 223 --------------------- lib/ca-functions | 28 ++- ca-scripts.conf => tiny-ca.conf | 0 vims | 2 +- 17 files changed, 88 insertions(+), 1183 deletions(-) create mode 100755 bin/tiny-ca delete mode 100644 ca-scripts.spec delete mode 100755 doc/ca-create-cert.pod delete mode 100755 doc/ca-init.pod delete mode 100755 doc/ca-renew-cert.pod delete mode 100755 doc/ca-revoke-cert.pod delete mode 100755 doc/ca-scripts.conf.pod rename ca-scripts.conf => tiny-ca.conf (100%) diff --git a/Makefile b/Makefile index dd589b1..b2af50a 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,18 @@ -NAME=ca-scripts +NAME=tiny-ca VERSION=0.9.0 DIRS=bin lib tpl INSTALL_DIRS=`find $(DIRS) -type d 2>/dev/null` INSTALL_FILES=`find $(DIRS) -type f 2>/dev/null` DOC_FILES=*.conf *.md doc/*.pod -SCRIPTS=ca-create-cert ca-init ca-list-certs ca-renew-cert ca-revoke-cert +SCRIPTS=tiny-ca -PKG_DIR=ca-scripts +PKG_DIR=tiny-ca PKG_NAME=$(NAME)_$(VERSION) PKG=$(PKG_DIR)/$(PKG_NAME).tar.gz SIG=$(PKG_DIR)/$(PKG_NAME).asc PREFIX?=/usr/local/$(NAME) -DOC_DIR=$(PREFIX)/doc -#DOC_DIR=$(PREFIX)/share/doc/$(PKG_NAME) pkg: mkdir -p $(PKG_DIR) @@ -45,15 +43,12 @@ release: $(PKG) $(SIG) tag install: for dir in $(INSTALL_DIRS); do mkdir -p $(PREFIX)/$$dir; done for file in $(INSTALL_FILES); do cp $$file $(PREFIX)/$$file; done - mkdir -p $(DOC_DIR) - cp -r $(DOC_FILES) $(DOC_DIR)/ symlinks: for link in $(SCRIPTS); do ln -s $(PREFIX)/bin/$$link /usr/local/bin/$$link; done uninstall: - for file in $(INSTALL_FILES); do rm -f $(PREFIX)/$$file; done - rm -rf $(DOC_DIR) + for file in $(INSTALL_FILES); do rm -f $(PREFIX)/$$file; done rmsymlinks: for link in $(SCRIPTS); do rm -f /usr/local/bin/$$link; done diff --git a/README.md b/README.md index 1fb7dd2..e39e510 100644 --- a/README.md +++ b/README.md @@ -1,153 +1,29 @@ -ca-scripts +tiny-ca ========== -A set of **bash**(1) scripts for working with SSL Certificate Authorities. +tiny-ca is forked from awesome [ca-scripts](https://github.com/fluffle/ca-scripts). It's pretty much the same scripts, but with a few tweaks/changes that doesn't make sense to merge into main repo. -These scripts are designed to provide a configurable wrapping layer around -[**openssl**(1)](http://www.openssl.org/), similar to CA.pl. They're potentially -a little heavyweight if you just need a single self-signed certificate to secure -an HTTPs webserver, but they may come in handy if you want to: +The main differences from ca-scripts are - * Generate multiple service certificates signed by a single authority - * Provide signed client certificates to end users for authentication purposes - * Provide client certificates for S/MIME encrypted e-mail or code signing - * Easily set extensions such as x509v3 subjectAltName in your certificates - -Portability ------------ - -Currently, these scripts are limited to systems with a recent install of -**openssl**(1), GNU **date**(1) -- sorry BSD folks; patches welcome -- and -version 3 or greater of **bash**(1). +* MacOS support +* UTF-8 is default encoding. +* Per directory configuration (in addition to /etc/tiny-ca.conf and $HOME/.tiny-ca.cong) +* Openssl config templates are now copied to CA home to allow their customization on per CA basis. Installation ------------- - -There aren't any tarballs as yet. Nor will the `make` command below work until -I've written a Makefile. It's coming, sometime. Sorry ;-) - - $ git clone git://github.com/fluffle/ca-scripts - $ cd ca-scripts - $ make; sudo make install - -This will by default install to `/usr/local`, either `export PREFIX=/path` or -`make PREFIX=/path; sudo make PREFIX=/path install` to change this to an -alternative location. +========== +``` +git clone http://github.com/sovcharenko/tiny-ca +cd tiny-ca +[sudo] make install +[sudo] make symlinks +``` MacOS note ------------- - -To make ca-scripts work on MacOS you have to install the following - +========== +tiny-ca requires the following brew packages installed ``` brew install coreutils brew install gnu-getopt brew install gnu-sed ``` - -Creating a Certificate Authority --------------------------------- - - Before running **ca-init**(1), a configuration file for the CA scripts must be -created. This configuration file sets up some templating variables that will -be present in certificates created for this CA, such as the domain, CA name, -and the root directory which will be populated with the generated certificates. -An example configuration file is provided with the scripts, and the comments -should be self-explanatory. - - By default the CA scripts will read `/etc/ca-scripts.conf`. This is fine for -creating a single CA serving a single domain with no intermediary certificates, -but for a more complex setup a directory of configuration files will probably -be needed. Some settings are required, namely the **CA\_HOME**, **CA\_DOMAIN**, -and **CA\_DN\_\*** variables, while others can be inferred from these or have -sensible defaults set. See **ca-scripts.conf**(5) for more detail on these. - - Once the configuration has been created the initial CA setup can be performed -with **ca-init(1)**, but please note that the path set in **CA\_HOME** must exist -and be writeable before it will run correctly. It is recommended (but not in an -way required) to create an unprivileged "ssl" user to run all the scripts as, so -the permissions are correctly set. A number of subdirectories will be set -up underneath this root, and an openssl configuration file, certificate and -private key will be generated. This key can be 3DES encrypted for security. - - Optionally, it is possible to split the initial setup process so that the -directory structure and openssl configuration generation can be done in a -seperate step to the generation of the CA certificates, so that the config can -be manually edited. To fully understand it's contents you're unfortunately -going to need to read the following: - - * [**ca**(1ssl)](http://www.openssl.org/docs/apps/ca.html) - * [**req**(1ssl)](http://www.openssl.org/docs/apps/req.html) - * [**x509**(1ssl)](http://www.openssl.org/docs/apps/x509.html) - * [**config**(5ssl)](http://www.openssl.org/docs/apps/config.html) - * [**x509v3\_config**(5ssl)](http://www.openssl.org/docs/apps/x509v3_config.html) - -Particularly important are the x509v3 extensions present in the certificate, -which are defined in the "ca\_x509\_extensions" section of the config file. - -Creating a certificate ----------------------- - - The **ca-create-cert**(1) script can generate three "types" of certificate: -*server* certificates for securing a service with SSL/TLS; *client* certificates -for authenticating a client to these services; and *user* certificates for -authentication, S/MIME e-mail signing or encryption, and code signing. There -are minor but important differences in the key usage extensions present in -these different certificate types, details can be found in the documentation -for **ca-create-cert**(1). In each case, a Common Name must be provided to give -a unique name for the certificate. - - **ca-create-cert**(1) takes a number of options to customise the generated -certificate. The **--type** option defaults to creating *server* certs. It is -likely that the **--alt-name** option (which sets X.509v3 subjectAltName DNS -records for other hostnames for the server) will be useful; it may also be used -when creating *client* certs. Both the server hostname and any alternative -names will be fully-qualified to **CA\_DOMAIN** if they do not contain any dots -unless the **--no-qualify** option is used. If unqualified names are passed in -they are preserved as alternative DNS names in the certificate. The private key -may be encrypted with 3DES using the **--encrypt** option, and the certificate, -key, and CA certificate can be bundled together into a PKCS#12 format -certificate archive by passing **--pkcs12**. By default certificates are valid -for 365 days from signing, but this may be changed with the **--days** option. - - The certificate's DN can be completely changed from the defaults provided by -**ca-scripts.conf**(5), but be wary as by default the generated openssl config -file requires that the country (C) and organisation (O) fields match those of -the CA certificate. A comment may also be set that will show up in user browsers -when they click on their padlock icons to examine the certificate's properties. -As with the CA setup, the steps to generate the certificate can be split up so -that configurations that are created from templates can be edited beforehand. - -Renewing a certificate ----------------------- - - Certificates are renewed using **ca-renew-cert**(1). This script currently -does some painful certificate manipulation that is not strictly necessary in -most cases, and may in fact decrease SSL security slightly. This is done because -the normal renewal process re-generates the certificate signing request and -thus creates a new public/private keypair. If the certificates are used for -S/MIME encryption or code signing, this renders all the encrypted e-mail -unreadable and requires you to re-sign the code with your new private key. - - To avoid this, **ca-renew-cert**(1) re-signs the old certificate request with -a new expiry date using the extensions generated when the old certificate was -signed. In the future it is possible (even likely) that this renewal method -will only be used on *user* type certificates, and the *server* and *client* -types will be renewed normally. If the current renewal method doesn't provide -sufficient security, the current certificate should be revoked and a new one -generated that is valid for the correct period of time using the **--days** -option to **ca-create-cert**(1). - - As with the certificate creation script a Common Name can be passed to -identify the certificate to renew; alternatively the path to a previously -created certificate can be given. Internally these will be both be resolved to -the correct information required for certificate renewal. - -Revoking a certificate ----------------------- - - To revoke a certificate and re-generate the CA certficate revocation list in -both PEM and DER encodings, invoke **ca-revoke-cert**(1), again providing a -Common Name or the path to the certificate to be revoked. Along with -**ca-init**(1) this script can optionally generate a basic HTML template to -serve the CA certificate and CRL with verifiable MD5 and SHA1 checksums. diff --git a/bin/ca-create-cert b/bin/ca-create-cert index 1e014aa..12d66e1 100755 --- a/bin/ca-create-cert +++ b/bin/ca-create-cert @@ -1,13 +1,6 @@ #!/bin/bash set -e -#Add GNU tools to path for MacOS -if [ "Darwin" = `uname -s` ]; then - export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" - export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" -fi - source $(dirname $(readlink -f $0))/../lib/ca-functions ALT_NAMES=() @@ -23,7 +16,7 @@ MAKE_P12=0 usage() { cat <<__EOT__ Usage: - $PROGNAME [options] + tiny-ca new [options] Options: -h, --help Print this helpful message! diff --git a/bin/ca-init b/bin/ca-init index ddcd29d..2033a9b 100755 --- a/bin/ca-init +++ b/bin/ca-init @@ -1,13 +1,6 @@ #!/bin/bash set -e -#Add GNU tools to path for MacOS -if [ "Darwin" = `uname -s` ]; then - export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" - export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" -fi - source $(dirname $(readlink -f $0))/../lib/ca-functions # XXX: Add an interactive mode to this script to obviate the need for a @@ -23,7 +16,7 @@ source $(dirname $(readlink -f $0))/../lib/ca-functions usage() { cat <<__EOT__ -Usage: $PROGNAME [options] +Usage: $PROGNAME init [options] Options: -h, --help Print this helpful message! @@ -79,23 +72,22 @@ fi if [ 1 -ne "$CRT_ONLY" ]; then # create the directory structure that'll be populated by the scripts - mkdir -p $CA_HOME/{cnf,crl,crt,csr,db,idx,key,p12} + mkdir -p $CA_HOME/{cnf,crl,crt,csr,db,idx,key,p12} echo "01" > $CA_HOME/db/crlnumber touch $CA_HOME/db/index.txt touch $CA_HOME/db/.rand - # generate an openssl configuration for this CA - ca_template ca-config "$CA_HOME/cnf/$CA_NAME.ca.cnf" + ca_init_templates fi if [ 1 -ne "$CNF_ONLY" ]; then - if [ ! -f "$CA_HOME/cnf/$CA_NAME.ca.cnf" ]; then - # looks like someone's running ca-init with -s without using -x first - error "Could not find CA config. Please run ca-init -x before using ca-init -s." - fi + # generate an openssl configuration for this CA + ca_template ca-config "$CA_HOME/cnf/$CA_NAME.ca.cnf" + # generate a self-signed cert that is valid for 10 years, with # ... the private key in $CA_HOME/key/$CA_NAME.ca.key # ... the certificate in $CA_HOME/crt/$CA_NAME.ca.crt - # ... using the config in $CA_HOME/cnf/$CA_NAME.ca.cnf + # ... using the config in $CA_HOME/cnf/$CA_NAME.ca.cnf + openssl req -new $CRYPTKEY -config "$CA_HOME/cnf/$CA_NAME.ca.cnf" \ -keyout "$CA_HOME/key/$CA_NAME.ca.key" \ -out "$CA_HOME/csr/$CA_NAME.ca.csr" diff --git a/bin/ca-list-certs b/bin/ca-list-certs index 006de9d..25a7ebf 100755 --- a/bin/ca-list-certs +++ b/bin/ca-list-certs @@ -1,18 +1,11 @@ #!/bin/bash set -e -#Add GNU tools to path for MacOS -if [ "Darwin" = `uname -s` ]; then - export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" - export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" -fi - source $(dirname $(readlink -f $0))/../lib/ca-functions usage() { cat <<__EOT__ -Usage: $PROGNAME [options] | +Usage: tiny-ca list [options] | Options: -h, --help Print this helpful message! diff --git a/bin/ca-renew-cert b/bin/ca-renew-cert index d6ed522..5138500 100755 --- a/bin/ca-renew-cert +++ b/bin/ca-renew-cert @@ -1,18 +1,11 @@ #!/bin/bash set -e -#Add GNU tools to path for MacOS -if [ "Darwin" = `uname -s` ]; then - export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" - export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" -fi - source $(dirname $(readlink -f $0))/../lib/ca-functions usage() { cat <<__EOT__ -Usage: $PROGNAME [options] | +Usage: tiny-ca renew [options] | Options: -h, --help Print this helpful message! diff --git a/bin/ca-revoke-cert b/bin/ca-revoke-cert index 82d974e..64b4dab 100755 --- a/bin/ca-revoke-cert +++ b/bin/ca-revoke-cert @@ -1,18 +1,11 @@ #!/bin/bash set -e -#Add GNU tools to path for MacOS -if [ "Darwin" = `uname -s` ]; then - export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" - export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" - export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" -fi - source $(dirname $(readlink -f $0))/../lib/ca-functions usage() { cat <<__EOT__ -Usage: $PROGNAME [options] | +Usage: tiny-ca revoke [options] | Options: -h, --help Print this helpful message! diff --git a/bin/tiny-ca b/bin/tiny-ca new file mode 100755 index 0000000..49b96ca --- /dev/null +++ b/bin/tiny-ca @@ -0,0 +1,38 @@ +#!/bin/bash +# set -e + +#Add GNU tools to path for MacOS +if [ "Darwin" = `uname -s` ]; then + export PATH="/usr/local/opt/gnu-getopt/bin:$PATH" + export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH" +fi + +scriptsDir=$(dirname $(readlink -f $0)) +script=$1 + +# shift + +usage() { + cat <<__EOT__ +Usage: tiny-ca subcommand [options] | + +Subcommands: + init + new + list + renew + revoke + +__EOT__ +} + +case "$script" in + "") usage; exit 1;; + init) $scriptsDir/ca-init $@;; + new) $scriptsDir/ca-create-cert $@;; + list) $scriptsDir/ca-list-certs $@;; + renew) $scriptsDir/ca-renew-cert $@;; + revoke) $scriptsDir/ca-revoke-cert $@;; + *) echo "Unknown subcomand '$1'"; usage; exit 1;; +esac \ No newline at end of file diff --git a/ca-scripts.spec b/ca-scripts.spec deleted file mode 100644 index 1ab31eb..0000000 --- a/ca-scripts.spec +++ /dev/null @@ -1,34 +0,0 @@ -Summary: SSL Certificate Authority Management Scripts -Name: ca-scripts -Version: 0.9.0 -Release: 1 -URL: https://github.com/erenfro/ca-scripts -License: GPL -Group: Applications/Internet -BuildRoot: ${_tmppath}/${name}-root -Requires: bash -BuildArch: noarch - -%description -SS Certificate Authority Management Scripts - -%prep -%setup -%build - -%install -rm -rf ${RPM_BUILD_ROOT} -mkdir -p ${RPM_BUILD_ROOT}/opt/ca-scripts -make install - -%clean -rm -rf ${RPM_BUILD_ROOT} - -%fils -%defattr(-,root,root) -%attr(755,root,root) ${RPM_BUILD_ROOT}/opt/${RPM_PACKAGE_NAME}/bin - -%changelog -* Thu Feb 19 2015 Eric Renfro -- Initial release. - diff --git a/doc/ca-create-cert.pod b/doc/ca-create-cert.pod deleted file mode 100755 index b9944c9..0000000 --- a/doc/ca-create-cert.pod +++ /dev/null @@ -1,345 +0,0 @@ -#! /bin/sh - -if [ -z "$1" -o "$1" == "man" ]; then - exec /usr/bin/pod2man -n CA-CREATE-CERT -s 1 -d "12 February 2010" \ - -r "ca-scripts version 0.9" -c "SSL Certificate Authority utilities" $0 -elif [ "$1" == "html" ]; then - exec /usr/bin/pod2html --title "ca-create-cert(1)" < $0 -elif [ "$1" == "text" ]; then - exec /usr/bin/pod2text -o $0 -fi -echo "Unrecognised output format '$1', try man, html, or text." -exit 1 - -=pod - -=head1 NAME - -ca-create-cert - generate a signed X.509 SSL certificate - -=head1 SYNOPSIS - -B [B<-cpqrsx>] [B<-f> I] [B<-t> I] [B<-d> I] -[B<-b> I] [B<-n> I] [I] - -B [B<-h>] | [B<--help>] - -=head1 DESCRIPTION - -B creates an openssl configuration necessary for generating a -signed X.509 SSL certificate, generates a certificate signing request using -these configuration files, and signs that request using the CA private key so -that it may be considered as trusted by anything that has imported the CA -certificate. - -=head1 OPTIONS - -=head2 The Common Name - -This argument to B is mandatory, and specifies the common name -of the certificate. Depending on the type of certificate being created, it is -interpreted as either a host name or a user name. - -=head2 General options - -=over - -=item B<-h>, B<--help> - -Prints out a short synopsis of the options to B. - -=item B<-t> I, B<--type> I - -B can create three types of X.509 certificate: I, -I, and I. The type can also be set using the config variable -B; it defaults to I in the absence of either the command -line or config variable being present. Certificate types differ in the X.509v3 -extensions present in the signed certificate, and in the uses the certificate -is trusted for. See x509(1ssl) and x509v3_config(5ssl) for more details about -X.509 extensions, and the B section of this manual for more -details on the exact differences between the certificate types. - -=item B<-c>, B<--encrypt> - -Encrypt the generated private key with 3DES. This is not recommended for -I or I type certificates, but is probably a good idea for -I certs. - -=item B<-f> I, B<--config> I - -Load the ca-scripts configuration from I instead of -I. - -=item B<-d> I, B<--days> I - -Sign the certificate to be valid for I days instead of the default -B set in the configuration file. - -=item B<-b> I, B<--bits> I - -Generate a I-bit certificate instead of the default B set in -the configuration file. Traditionally this is a power of two, e.g. 1024 or 2048. - -=item B<-n> I, B<--alt-name> I - -Only valid for I type certificates. Specifies an alternative host -name to add to the X.509v3 I extension field, which will -also be recognised as a valid host name for the certificate. May be provided -multiple times to add multiple host names. - -=item B<-p>, B<--pkcs12> - -Generate a PKCS#12 format certificate archive containing the new certificate -and private key along with the CA certificate. See pkcs12(1ssl) for more -details about PKCS#12 archives. - -=item B<-q>, B<--no-qualify> - -Disable qualifying of the certificate's common name (and alternative names) with -B. - -Host names for I and I certificates are treated as unqualified -if they do not contain any dots and qualified to I.B. -The unqualified name is preserved as an additional DNS name in the X.509v3 -I extension in this case. User names are treated as unqualified -if they do not contain an "@" symbol and are qualified to I@B. - -=item B<-r>, B<--req-only> - -Causes B to generate just the X.509 certificate signing -request (CSR) from a pre-existing openssl request configuration, without -signing it to create a valid certificate. When used in conjunction with -B<--cnf-only>, B only generates the openssl request -configuration, allowing the user to modify it before creating the CSR. -Mutually exclusive to B<--sign-only>. - -=item B<-s>, B<--sign-only> - -Causes B to sign a pre-existing CSR using a pre-existing -X.509 extensions configuration, creating a valid certificate. When used in -conjunction with B<--cnf-only>, B only generates the -X.509 extensions configuration, allowing the user to modify it before signing -the certificate. Mutually exclusive to B<--req-only>. - -=item B<-x>, B<--cnf-only> - -Causes B to generate the openssl request and X.509 -extensions configurations, without creating a CSR or signing it. When used in -conjunction with either of the previous two options, causes only one of the two -configuration files to be generated. - -=back - -=head2 Distinguished Name (DN) options - -These options allow the user to change the value of various DN fields. Be careful -about changing the C and O fields, as by default the CA configuration requires -these to match the fields in the CA certificate when the CSR is signed. By -default these values are taken from the ca-scripts configuration file, and will -match those of the CA certificate. The certificate's common name (CN) is set by -the mandatory host or user name parameter. - -=over - -=item B<--country> I<"STRING"> - -Sets the country (C) field of the DN. - -=item B<--state> I<"STRING"> - -Sets the state (ST) field of the DN. - -=item B<--loc> I<"STRING"> - -Sets the locality (L) field of the DN. - -=item B<--org> I<"STRING"> - -Sets the organization (O) field of the DN. - -=item B<--ounit> I<"STRING"> - -Sets the organizational unit (OU) field of the DN. - -=item B<--email> I<"STRING"> - -Sets the e-mail address (E) field of the DN. As per the X.509 spec, this field -is removed from the DN and placed in the X.509v3 I extension -when the certificate is signed. - -=item B<--comment> I<"STRING"> - -Sets the nsComment X.509 extension. - -=back - -=head1 CERTIFICATE TYPES - -B generates three types of certificates, differentiated by the -SSL extensions present in the signed cert. It will always generate X.509v3 -certificates; creating a v1 certificate is not supported. All certificate types -have the following extensions present: - -=over - -=item basicConstraints = critical, CA:FALSE - -Prevents the certificate from being used as a CA. - -=item nsRevocationUrl = B - -Points to the world-accessible CRL distribution point for the CA. - -=item issuerAltName = issuer:copy - -Records the issuing CA certificate's I extension as -I. - -=item subjectKeyIdentifier = hash - -Records the certificate's fingerprint as the information used to uniquely -identify the certificate. - -=item authorityKeyIdentifier = keyid;issuer:always - -Records the issuing CA certificate's fingerprint, DN, and serial for -verification purposes. - -=item authorityInfoAccess = caIssuers;URI:B - -Points to the world-accessible CA certificate distribution point. - -=item crlDistributionPoints = URI:B - -Points to the world-accessible CRL distribution point for the CA. - -=back - -=head2 Server certificates - -I certificates are used for securing SSL/TLS services, such as -TLS-encrypted LDAP connections or HTTPS. In this case the I argument -is used for the Common Name in the certificate, and any additional alternative -names supplied by B<-n> are added to the X.509v3 I extension -field. - -I certificates contain the following extensions: - -=over - -=item nsCertType = server - -Marks the certificate as valid for server authentication. This is the old -Netscape SSL extension, but many things still rely on it. - -=item keyUsage = critical, keyEncipherment, keyAgreement - -Allows the certificate to be used for key negotiation and encryption. - -=item extendedKeyUsage = serverAuth - -Marks the certificate as valid for server authentication. This is the newer -X.509v3 extension. - -=item subjectAltName = @server_altname - -Includes the templated [server_altname] extensions section as the X.509v3 -I. This extension contains alternate DNS entries for the server as -provided to the B<--alt-name> option, as well as the CA certificate URI and the -e-mail address provided to the B<--email> option. - -=back - -=head2 Client certificates - -I certificates are used for authenticating to SSL/TLS services. -For the most part they are intended to be used by automated systems to identify -and authenticate themselves to services they interact with. - -I certificates contain the following extensions: - -=over - -=item nsCertType = client - -Marks the certificate as valid for client authentication. This is the old -Netscape SSL extension, but many things still rely on it. - -=item keyUsage = critical, keyEncipherment, keyAgreement, digitalSignature - -Allows the certificate to be used for key negotiation, encryption and creating -digital signatures. The latter option is useful for e.g. automatically creating -signed tarballs for distribution. - -=item extendedKeyUsage = clientAuth, timeStamping - -Marks the certificate as valid for client authentication and digital time -stamping. This is the newer X.509v3 extension. - -=item subjectAltName = @client_altname - -Includes the templated [client_altname] extensions section as the X.509v3 -I. This extension contains the CA certificate URI and the e-mail -address provided to the B<--email> option. - -=back - -=head2 User certificates - -I certificates are for individuals to authenticate themselves to -SSL/TLS services in the same manner as client certificates, but they may also -be used for S/MIME e-mail encryption, data encryption and code signing. - -I certificates contain the following extensions: - -=over - -=item nsCertType = client - -Marks the certificate as valid for client authentication. This is the old -Netscape SSL extension, but many things still rely on it. - -=item keyUsage = critical, keyEncipherment, keyAgreement, digitalSignature, nonRepudiation, dataEncipherment - -Allows the certificate to be used for key negotiation and encryption; creating -digital signatures; validating the source of signed data; and encrypting data. - -=item extendedKeyUsage = clientAuth, codeSigning, emailProtection - -Marks the certificate as valid for client authentication, code signing, and -S/MIME e-mail encryption. This is the newer X.509v3 extension. - -=item subjectAltName = @user_altname - -Includes the templated [user_altname] extensions section as the X.509v3 -I. This extension contains the CA certificate URI and the e-mail -address provided to the B<--email> option. - -=back - -=head1 BUGS - -Probably. Of particular note is that the default openssl configuration file -requires the C (country) and O (organisation) fields of all generated -certificates to match those in the CA certificate, but B -allows these fields to be changed. - -=head1 AVAILABILITY - -New releases of the ca-scripts utilities can be found at -L. -A L -for development versions also exists. - -=head1 AUTHORS - -Copyright 2009, 2010 Alex Bramley a.bramley@gmail.com - -=head1 SEE ALSO - -ca-init(1), ca-renew-cert(1), ca-revoke-cert(1), ca-scripts.conf(5), -openssl(1ssl), ca(1ssl), req(1ssl), x509(1ssl), config(5ssl), and -x509v3_config(5ssl). - -=cut diff --git a/doc/ca-init.pod b/doc/ca-init.pod deleted file mode 100755 index 73fbff2..0000000 --- a/doc/ca-init.pod +++ /dev/null @@ -1,175 +0,0 @@ -#! /bin/sh - -if [ -z "$1" -o "$1" == "man" ]; then - exec /usr/bin/pod2man -n CA-INIT -s 1 -d "12 February 2010" \ - -r "ca-scripts version 0.9" -c "SSL Certificate Authority utilities" $0 -elif [ "$1" == "html" ]; then - exec /usr/bin/pod2html --title "ca-init(1)" < $0 -elif [ "$1" == "text" ]; then - exec /usr/bin/pod2text -o $0 -fi -echo "Unrecognised output format '$1', try man, html, or text." -exit 1 - -=pod - -=head1 NAME - -ca-init - initialise an X.509 SSL CA and generate CA certificate - -=head1 SYNOPSIS - -B [B<-csx>] [B<-f> I] [B<-d> I] [B<-l> I] -[B<-b> I] [B<-i> I