diff --git a/diff_build/freebsd_port/Makefile b/diff_build/freebsd_port/Makefile new file mode 100644 index 0000000..ddace6b --- /dev/null +++ b/diff_build/freebsd_port/Makefile @@ -0,0 +1,27 @@ +# Ports collection makefile for: ssl-admin +# Date created: Thu Jan 14 10:38:23 CST 2010 +# Whom: Eric Crist +# +# $FreeBSD: ports/security/ssl-admin/Makefile,v 1.4 2008/07/27 19:05:31 beech Exp $ +# + +PORTNAME= ssl-admin +DISTVERSION= 1.0.3 +CATEGORIES= security +MASTER_SITES= ftp://ftp.secure-computing.net/pub/FreeBSD/ports/ssl-admin/ + +MAINTAINER= ecrist@secure-computing.net +COMMENT= OpenSSL certificate manager with OpenVPN support. + +RUN_DEPENDS= unzip:${PORTSDIR}/archivers/unzip \ + zip:${PORTSDIR}/archivers/zip + +USE_PERL5_RUN= YES +MAN1= ssl-admin.1 +MAN5= ssl-admin.conf.5 +SUB_FILES= pkg-message + +post-install: + ${CAT} ${PKGMESSAGE} + +.include diff --git a/diff_build/freebsd_port/distinfo b/diff_build/freebsd_port/distinfo new file mode 100644 index 0000000..9eada8b --- /dev/null +++ b/diff_build/freebsd_port/distinfo @@ -0,0 +1,3 @@ +MD5 (ssl-admin-1.0b1.2.tar.gz) = 5724066b6982d494ce57d436d1396d17 +SHA256 (ssl-admin-1.0b1.2.tar.gz) = b07b2a67d11ce3de3fb7867ea44539093dda42fdb2737216375a6c5f7e3c3b9f +SIZE (ssl-admin-1.0b1.2.tar.gz) = 8076 diff --git a/diff_build/freebsd_port/files/pkg-message.in b/diff_build/freebsd_port/files/pkg-message.in new file mode 100644 index 0000000..d2a7e2b --- /dev/null +++ b/diff_build/freebsd_port/files/pkg-message.in @@ -0,0 +1,6 @@ +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +Please edit the configuration file ssl-admin.conf before running +ssl-admin for the first time. + +You're now ready to manage your SSL certificates. +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/diff_build/freebsd_port/pkg-descr b/diff_build/freebsd_port/pkg-descr new file mode 100644 index 0000000..663fe3a --- /dev/null +++ b/diff_build/freebsd_port/pkg-descr @@ -0,0 +1,11 @@ +ssl-admin was designed to create a user-friendly, menu-driven interface +to the OpenSSL programs. + +ssl-admin will help you do the following tasks with SSL certificates: + * Create your own CA certificate. + * Create new Certificate Signing Requests + * Sign existing Certificate Signing Requests + * Manage Certificate Revokation Lists + * Export configurations and certificates for OpenVPN. + +WWW: http://www.secure-computing.net/ssl-admin/ diff --git a/diff_build/freebsd_port/pkg-plist b/diff_build/freebsd_port/pkg-plist new file mode 100644 index 0000000..d2b3c67 --- /dev/null +++ b/diff_build/freebsd_port/pkg-plist @@ -0,0 +1,5 @@ +bin/ssl-admin +etc/ssl-admin/ssl-admin.conf.default +@unexec if cmp -s %D/etc/ssl-admin/openssl.conf.default %D/etc/ssl-admin/openssl.conf; then rm -f %D/etc/ssl-admin/openssl.conf; fi +etc/ssl-admin/openssl.conf.default +@dirrmtry etc/ssl-admin diff --git a/diff_build/patch.diff.samp b/diff_build/patch.diff.samp new file mode 100644 index 0000000..c82c5f8 --- /dev/null +++ b/diff_build/patch.diff.samp @@ -0,0 +1,36 @@ +diff -urN ssl-admin_ports/Makefile ssl-admin/Makefile +--- ssl-admin_ports/Makefile 2009-01-19 14:39:36.000000000 -0600 ++++ ssl-admin/Makefile 2009-01-20 16:35:14.000000000 -0600 +@@ -1,17 +1,17 @@ +-# Ports collection makefile for:| ssl-admin ++# Ports collection makefile for: ssl-admin + # Date created: 21 July 2008 + # Whom: Eric Crist + # +-# $FreeBSD: ports/security/ssl-admin/Makefile,v 1.4 2008/07/27 19:05:31 beech Exp $ ++# $FreeBSD: ports/security/ssl-admin/Makefile,v 1.5 2008/12/06 15:18:06 miwi Exp $ + # + + PORTNAME= ssl-admin +-DISTVERSION= 1.0 ++DISTVERSION= 1.0.1 + CATEGORIES= security +-MASTER_SITES= ftp://ftp.secure-computing.net/pub/FreeBSD/ports/ ++MASTER_SITES= ftp://ftp.secure-computing.net/pub/FreeBSD/ports/ssl-admin/ + + MAINTAINER= ecrist@secure-computing.net +-COMMENT= OpenSSL certificate manager ++COMMENT= OpenSSL certificate manager with OpenVPN support. + + RUN_DEPENDS= unzip:${PORTSDIR}/archivers/zip \ + zip:${PORTSDIR}/archivers/unzip +diff -urN ssl-admin_ports/distinfo ssl-admin/distinfo +--- ssl-admin_ports/distinfo 2009-01-19 14:39:36.000000000 -0600 ++++ ssl-admin/distinfo 2009-01-20 16:45:30.000000000 -0600 +@@ -1,3 +1,3 @@ +-MD5 (ssl-admin-1.0.tar.gz) = ff42b5bc6286cbcb519bcb1783425af2 +-SHA256 (ssl-admin-1.0.tar.gz) = 10b03971356a998d90f30c3db98723db2cb859c52ec7330ae69581720783b84d +-SIZE (ssl-admin-1.0.tar.gz) = 9346 ++MD5 (ssl-admin-1.0.1.tar.gz) = e1625f39553166fa553450f142ecff05 ++SHA256 (ssl-admin-1.0.1.tar.gz) = 6d1a1b23d58ef5344b20aa8d0d76d583ae25a573b3a7661919b175e21ec7cc91 ++SIZE (ssl-admin-1.0.1.tar.gz) = 8554 diff --git a/diff_build/ssl-admin_ports/Makefile b/diff_build/ssl-admin_ports/Makefile new file mode 100644 index 0000000..1637490 --- /dev/null +++ b/diff_build/ssl-admin_ports/Makefile @@ -0,0 +1,27 @@ +# Ports collection makefile for: ssl-admin +# Date created: 21 July 2008 +# Whom: Eric Crist +# +# $FreeBSD: ports/security/ssl-admin/Makefile,v 1.7 2009/04/08 17:21:21 dhn Exp $ +# + +PORTNAME= ssl-admin +DISTVERSION= 1.0.2 +CATEGORIES= security +MASTER_SITES= ftp://ftp.secure-computing.net/pub/FreeBSD/ports/ssl-admin/ + +MAINTAINER= ecrist@secure-computing.net +COMMENT= OpenSSL certificate manager with OpenVPN support + +RUN_DEPENDS= unzip:${PORTSDIR}/archivers/zip \ + zip:${PORTSDIR}/archivers/unzip + +USE_PERL5_RUN= YES +MAN1= ssl-admin.1 +MAN5= ssl-admin.conf.5 +SUB_FILES= pkg-message + +post-install: + ${CAT} ${PKGMESSAGE} + +.include diff --git a/diff_build/ssl-admin_ports/distinfo b/diff_build/ssl-admin_ports/distinfo new file mode 100644 index 0000000..5179579 --- /dev/null +++ b/diff_build/ssl-admin_ports/distinfo @@ -0,0 +1,3 @@ +MD5 (ssl-admin-1.0.2.tar.gz) = 050ced81d9927185b8973bbbbb9297d5 +SHA256 (ssl-admin-1.0.2.tar.gz) = 6502c4b16ac893ffa88fdb549c28c501da1ab05c3f639f4377e8117ab4b7ed69 +SIZE (ssl-admin-1.0.2.tar.gz) = 8607 diff --git a/diff_build/ssl-admin_ports/files/pkg-message.in b/diff_build/ssl-admin_ports/files/pkg-message.in new file mode 100644 index 0000000..d2a7e2b --- /dev/null +++ b/diff_build/ssl-admin_ports/files/pkg-message.in @@ -0,0 +1,6 @@ +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +Please edit the configuration file ssl-admin.conf before running +ssl-admin for the first time. + +You're now ready to manage your SSL certificates. +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/diff_build/ssl-admin_ports/pkg-descr b/diff_build/ssl-admin_ports/pkg-descr new file mode 100644 index 0000000..663fe3a --- /dev/null +++ b/diff_build/ssl-admin_ports/pkg-descr @@ -0,0 +1,11 @@ +ssl-admin was designed to create a user-friendly, menu-driven interface +to the OpenSSL programs. + +ssl-admin will help you do the following tasks with SSL certificates: + * Create your own CA certificate. + * Create new Certificate Signing Requests + * Sign existing Certificate Signing Requests + * Manage Certificate Revokation Lists + * Export configurations and certificates for OpenVPN. + +WWW: http://www.secure-computing.net/ssl-admin/ diff --git a/diff_build/ssl-admin_ports/pkg-plist b/diff_build/ssl-admin_ports/pkg-plist new file mode 100644 index 0000000..d2b3c67 --- /dev/null +++ b/diff_build/ssl-admin_ports/pkg-plist @@ -0,0 +1,5 @@ +bin/ssl-admin +etc/ssl-admin/ssl-admin.conf.default +@unexec if cmp -s %D/etc/ssl-admin/openssl.conf.default %D/etc/ssl-admin/openssl.conf; then rm -f %D/etc/ssl-admin/openssl.conf; fi +etc/ssl-admin/openssl.conf.default +@dirrmtry etc/ssl-admin diff --git a/perl/Makefile b/perl/Makefile new file mode 100644 index 0000000..9d06660 --- /dev/null +++ b/perl/Makefile @@ -0,0 +1,31 @@ +# ssl-admin Makefile +# $Id: Makefile 366 2014-10-01 17:44:18Z ecrist $ + +ETCDIR?=VARETC +BINDIR?=VARBIN +MANDIR?=VARMAN +SED_CMD?=VARSED + +all: + +build-devel: + + [ -e "working-build/" ] || mkdir -p working-build/ssl-admin + ${SED_CMD} s+~~~ETCDIR~~~+${ETCDIR}+g man1/ssl-admin.1 > working-build/ssl-admin.1 + ${SED_CMD} s+~~~ETCDIR~~~+${ETCDIR}+g man5/ssl-admin.conf.5 > working-build/ssl-admin.conf.5 + install -c -m 0660 -S -v ssl-admin.conf working-build/ssl-admin/ssl-admin.conf + install -c -m 0660 -S -v openssl.conf working-build/ssl-admin/openssl.conf + ${SED_CMD} -e "s+~~~ETCDIR~~~+`pwd`/working-build+g" -e "s+~~~BUILD~~~+devel+g" ssl-admin > ssl-admin.mod + install -c -m 0755 -S -v ssl-admin.mod working-build/ssl-admin.test + +install: + + [ -e "${DESTDIR}/${ETCDIR}/ssl-admin" ] || mkdir -p ${DESTDIR}/${ETCDIR}/ssl-admin + ${SED_CMD} s+~~~ETCDIR~~~+${ETCDIR}+g man1/ssl-admin.1 > ${DESTDIR}/${MANDIR}/man1/ssl-admin.1 + ${SED_CMD} s+~~~ETCDIR~~~+${ETCDIR}+g man5/ssl-admin.conf.5 > ${DESTDIR}/${MANDIR}/man5/ssl-admin.conf.5 + install -c -m 0660 -S -v ssl-admin.conf ${DESTDIR}/${ETCDIR}/ssl-admin/ssl-admin.conf.sample + install -c -m 0660 -S -v openssl.conf ${DESTDIR}/${ETCDIR}/ssl-admin/openssl.conf.sample + install -c -m 0660 -S -v openssl.conf ${DESTDIR}/${ETCDIR}/ssl-admin/openssl.conf + ${SED_CMD} -e "s+~~~ETCDIR~~~+${ETCDIR}+g" -e "s+~~~BUILD~~~+prod+g" ssl-admin > ssl-admin.mod + install -c -m 0755 -S -v ssl-admin.mod ${DESTDIR}/${BINDIR}/ssl-admin + chmod 0444 ${DESTDIR}/${ETCDIR}/ssl-admin/*.conf.sample diff --git a/perl/Makefile.freebsd b/perl/Makefile.freebsd new file mode 100644 index 0000000..2d48ca9 --- /dev/null +++ b/perl/Makefile.freebsd @@ -0,0 +1,27 @@ +# Ports collection makefile for: ssl-admin +# Date created: Thu Jan 14 09:48:29 CST 2010 +# Whom: Eric Crist +# +# $FreeBSD: ports/security/ssl-admin/Makefile,v 1.4 2008/07/27 19:05:31 beech Exp $ +# + +PORTNAME= ssl-admin +DISTVERSION= ~~~VERSION~~~ +CATEGORIES= security +MASTER_SITES= ftp://ftp.secure-computing.net/pub/FreeBSD/ports/ssl-admin/ + +MAINTAINER= ecrist@secure-computing.net +COMMENT= OpenSSL certificate manager with OpenVPN support. + +RUN_DEPENDS= unzip:${PORTSDIR}/archivers/zip \ + zip:${PORTSDIR}/archivers/unzip + +USE_PERL5_RUN= YES +MAN1= ssl-admin.1 +MAN5= ssl-admin.conf.5 +SUB_FILES= pkg-message + +post-install: + ${CAT} ${PKGMESSAGE} + +.include diff --git a/perl/Makefile.orig b/perl/Makefile.orig new file mode 100644 index 0000000..58dbc8f --- /dev/null +++ b/perl/Makefile.orig @@ -0,0 +1,20 @@ +# ssl-admin Makefile +# $Id: Makefile 338 2013-07-24 12:16:48Z ecrist $ + +ETCDIR?=VARETC +BINDIR?=VARBIN +MANDIR?=VARMAN + +all: + +install: + + [ -e "${ETCDIR}/ssl-admin" ] || mkdir -p ${ETCDIR}/ssl-admin + sed s+~~~ETCDIR~~~+${ETCDIR}+g man1/ssl-admin.1 > ${MANDIR}/man1/ssl-admin.1 + sed s+~~~ETCDIR~~~+${ETCDIR}+g man5/ssl-admin.conf.5 > ${MANDIR}/man5/ssl-admin.conf.5 + install -c -g wheel -o root -m 0660 -S -v ssl-admin.conf ${ETCDIR}/ssl-admin/ssl-admin.conf.default + install -c -g wheel -o root -m 0660 -S -v openssl.conf ${ETCDIR}/ssl-admin/openssl.conf.default + [ -e "${ETCDIR}/ssl-admin/openssl.conf" ] || cp ${ETCDIR}/ssl-admin/openssl.conf.default ${ETCDIR}/ssl-admin/openssl.conf + SEDCMD "s+~~~ETCDIR~~~+${ETCDIR}+g" ssl-admin + install -c -g wheel -o root -m 0755 -S -v ssl-admin ${BINDIR}/ssl-admin + chmod 0444 ${ETCDIR}/ssl-admin/*.conf.default diff --git a/perl/build.release.sh b/perl/build.release.sh new file mode 100755 index 0000000..ad2a511 --- /dev/null +++ b/perl/build.release.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# $Id$ + +MAJVER=1 +MINVER=2 +REVISION=1 + +DIR=ssl-admin-$MAJVER.$MINVER.$REVISION + + +## Make directory - if it's there, delete it so we can start fresh. +if [ -d $DIR ]; then + rm -rf $DIR +fi +mkdir $DIR + +echo "Updating version string" +sed -i -e "s/~~~VERSION~~~/$MAJVER.$MINVER.$REVISION/" ssl-admin + +## Copy file over. +cp -r man1 man5 Makefile configure openssl.conf ssl-admin ssl-admin.conf $DIR + +## remove .svn dir, if it exists. +find $DIR -type d -name .svn | xargs rm -rf + +echo "Creating distfile..." +tar -czf $DIR.tar.gz $DIR +tar -cjf $DIR.tar.xz $DIR + +echo "Publishing package..." +scp -F /usr/home/ecrist/.ssh/config $DIR.tar.gz $DIR.tar.xz tweak:/usr/home/ftp/pub/FreeBSD/ports/ssl-admin/ +scp -F /usr/home/ecrist/.ssh/config $DIR.tar.gz $DIR.tar.xz tweak:/usr/home/ftp/pub/ssl-admin/ +scp -F /usr/home/ecrist/.ssh/config $DIR.tar.gz $DIR.tar.xz xxx:/home/ftp/pub/FreeBSD/ports/ssl-admin/ +scp -F /usr/home/ecrist/.ssh/config $DIR.tar.gz $DIR.tar.xz xxx:/home/ftp/pub/ssl-admin/ + +### Update version number in the ports Makefile +echo "Building heirarchy for FreeBSD port build" +rm -rf diff_build/freebsd_port/ +svn co http://8.8.178.107/ports/head/security/ssl-admin diff_build/freebsd_port + + +echo "Auto-modifying support files:" +sed -i -e "s/DISTVERSION=.*$/DISTVERSION= $MAJVER.$MINVER.$REVISION/" diff_build/freebsd_port/Makefile +LDIR=`pwd` +echo "Building checksum file" +cd diff_build/freebsd_port && make DISTDIR=../../ makesum + +echo "Building diff now..." +svn diff +svn diff > ../$MAJVER.$MINVER.$REVISION.patch + + + diff --git a/perl/configure b/perl/configure new file mode 100755 index 0000000..97706e8 --- /dev/null +++ b/perl/configure @@ -0,0 +1,46 @@ +#!/bin/sh +# +# $Id: configure 353 2014-06-24 19:19:58Z ecrist $ + +VARSED=`which sed` + +OS=`uname` +case "$OS" in + FreeBSD) + ${VARSED} -i "" "s+VARETC+/usr/local/etc+g" Makefile + ${VARSED} -i "" "s+VARBIN+/usr/local/bin+g" Makefile + ${VARSED} -i "" "s+VARMAN+/usr/local/man+g" Makefile + ${VARSED} -i "" "s+VARSED+${VARSED}+g" Makefile + ;; + NetBSD) + ${VARSED} -i "" "s+VARETC+/usr/local/etc+g" Makefile + ${VARSED} -i "" "s+VARBIN+/usr/local/bin+g" Makefile + ${VARSED} -i "" "s+VARMAN+/usr/share/man+g" Makefile + ${VARSED} -i "" "s+VARSED+${VARSED}+g" Makefile + ;; + OpenBSD) + ${VARSED} -i "" "s+VARETC+/etc+g" Makefile + ${VARSED} -i "" "s+VARBIN+/usr/local/bin+g" Makefile + ${VARSED} -i "" "s+VARMAN+/usr/local/man+g" Makefile + ${VARSED} -i "" "s+VARSED+${VARSED}+g" Makefile + ;; + Darwin) + ${VARSED} -i "" "s+VARETC+/Library+g" Makefile + ${VARSED} -i "" "s+VARBIN+/usr/local/bin+g" Makefile + ${VARSED} -i "" "s+VARMAN+/usr/share/man+g" Makefile + ${VARSED} -i "" "s+VARSED+${VARSED}+g" Makefile + ;; + Linux) + ${VARSED} -i "s+VARETC+/etc+g" Makefile + ${VARSED} -i "s+VARBIN+/usr/bin+g" Makefile + ${VARSED} -i "s+VARMAN+/usr/share/man+g" Makefile + ${VARSED} -i "s+VARSED+${VARSED}+g" Makefile + ${VARSED} -i "s+wheel+root+" Makefile + ;; + *) + echo "Your OS is not OS X (Darwin), BSD, or Linux." + echo "I don't know how to install on ${OS}." + echo "Please submit a bug report if you think I should." + ;; +esac + diff --git a/perl/man1/ssl-admin.1 b/perl/man1/ssl-admin.1 new file mode 100644 index 0000000..b9ded19 --- /dev/null +++ b/perl/man1/ssl-admin.1 @@ -0,0 +1,142 @@ +.TH ssl\-admin 1 +.SH NAME +ssl-admin \- OpenSSL Certificate Manager +.SH SYNOPSIS +.T +.B ssl-admin + +.SH DESCRIPTION +\fBssl-admin\fR is a menu-driven tool designed to simplify the management +and distriibution of SSL certificates. ssl-admin was originally written to +manage SSL certificates for use with OpenVPN. This functionality has not +been removed. + +.SH CORE FUNCTIONS +There are a number of core operations within \fBssl-admin\fR, often times +mutually exlusive of one another. For example, you cannot generate a new +CA certificate and generate a client certificate all at once. + +.TP +\fB--new-ca\fR +This command will generate a new root certificate and key pair and store +the new files in \fBwork-dir\fR. If you add the optional \fB--clean\fR +argument, you will wipe out the existing certificate store. + +.TP +\fB--int-ca\fR +This command will generate an intermediate CA certficate which can be used +for signing sub keys, etc. + +.TP +\fB--client-cert\fR, \fB--ccert\fR +This will generate a client signing request, certificate, and key. + +.TP +\fB--server-cert\fR, \fB--scert\fR +This will generate a client signing request, certificate, and key, with +server extensions enabled. + +.TP +\fB--dh\fR, \fB--diffie-hellman\fR +Generates the Diffie-Hellman prime. + +.TP +\fB--revoke\fR +Used to revoke a certificate in the store. + +.TP +\fB--crl-list\fR +This outputs a list of revoked certificates. + +.SH DIRECTORIES +There are a number of directories within ~~~ETCDIR~~~/ssl-admin/ which +contain the working and datafiles. +.TP +ACTIVE (~~~ETCDIR~~~/ssl-admin/active) +The active directory contains certificates that have not been revoked. The +only keys that are \fBREQUIRED\fR to be present are ca.crt and ca.key. + +.TP +CSR (~~~ETCDIR~~~/ssl-admin/csr) +The csr directory contains certificate signing requests and keys for those +keys which have been created using ssl-admin. If you need to sign a +certificate signing request generated elsewhere, place the .csr here. The +key files are not required to be present. + +.TP +PACKAGES (~~~ETCDIR~~~/ssl-admin/packages) +The packages directory contains any zipped packages you've built with ssl-admin. +Packages are generally used to distribute signed certificates to end users. + +.TP +PROG (~~~ETCDIR~~~/ssl-admin/prog) +The prog directory contains all the data files used by ssl-admin. +\fBDO NOT EDIT OR MODIFY THE FILES IN THIS DIRECTORY\fR unless you know exactly +what you are doing. If you are running OpenVPN, you may point your OpenVPN +crl-verify config option to ~~~ETCDIR~~~/ssl-admin/prog/crl.pem. + +.TP +REVOKED (~~~ETCDIR~~~/ssl-admin/revoked) +The revoked directory contains certificates and keys for those certificates +that have been revoked within ssl-admin. + +.SH MENU OPTIONS +.TP +UPDATE RUN-TIME OPTIONS +.TP +CREATE NEW CERTIFICATE REQUEST + +.TP +SIGN A CERTIFICATE REQUEST + +.TP +PERFORM A ONE-STEP REQUEST/SIGN + +.TP +REVOKE A CERTIFICATE + +.TP +RENEW/RE-SIGN A PAST CERTIFICATE REQUEST + +.TP +VIEW CURRENT CRL + +.TP +VIEW INDEX INFORMATION + +.TP +ZIP/PACKAGE END-USER FILES + +.TP +GENERATE DIFFIE-HELLMAN + +.TP +CREATE SELF-SIGNED CA + +.TP +CREATE SIGNED SERVER CERTIFICATE + +.TP +QUIT SSL-ADMIN + +.SH NOTES +This man page needs to be completed. + +.SH BUGS +.TP +OpenVPN client.ovpn error +There is an error when making a new certificate that client.ovpn doesn't exist. + +.SH FILES +.T4 +~~~ETCDIR~~~/ssl-admin/ssl-admin.conf + +.SH "SEE ALSO" +ssl-admin.conf(5), openssl(1) + +.SH AUTHOR +Eric Crist + +v~~~VERSION~~~ +$Id: ssl-admin.1 356 2014-06-25 02:59:57Z ecrist $ + diff --git a/perl/man5/ssl-admin.conf.5 b/perl/man5/ssl-admin.conf.5 new file mode 100644 index 0000000..8a0fb69 --- /dev/null +++ b/perl/man5/ssl-admin.conf.5 @@ -0,0 +1,53 @@ +.TH ssl\-admin.conf 5 +.SH NAME +ssl-admin.conf \- configuration file for ssl-admin + +.SH DESCRIPTION +The file \fB ssl-admin.conf\fR contains settings that control site- +specific settings for your default key size, length, and location +information. + +This configuration file is essentially a called perl script with the +needed variables assigned. + +.SH KEY INFORMATION +.TP +.B KEY_SIZE (num) +The length, in bits, for the default key size. A minimum of 1024 is +recommended. This option can be changed at run time. +.TP +.B KEY_DAYS (num) +The length, in days, for the default period a certificate is valid for. +365 is recommended for web, mail, etc, servers. 3650 is recommended for +VPN certificates. This option can be changed at run time. +.TP +.B KEY_CN (str) +This is the default Common Name for a certificate. Leaving the value +empty is recommended. This option is always asked for at run time. +.TP +.B KEY_CRL_LOC (str) +The publicly available location for your CRL (Certificate Revokation +List). At this time, ssl-admin does not have the ability of sending the +CRL to another system. This value simply allows it to be set within +each certificate. +This string \fBmust\fR start with "URI:", and be followed with a standard +URL. For example, "URI:http://www.example.com/crl.pem" + +.SH NOTES +This man page needs to be completed. + +.SH BUGS +No known bugs at this time. + +.SH FILES +.T4 +~~~ETCDIR~~~/ssl-admin/ssl-admin.conf + +.SH "SEE ALSO" +ssl-admin(1), openssl(1) + +.SH AUTHOR +Eric Crist + +v~~~VERSION~~~ +$Id: ssl-admin.conf.5 356 2014-06-25 02:59:57Z ecrist $ diff --git a/perl/openssl.conf b/perl/openssl.conf new file mode 100644 index 0000000..4eeca20 --- /dev/null +++ b/perl/openssl.conf @@ -0,0 +1,91 @@ +# OpenSSL Configuration File for ssl-admin + +dir = $ENV::KEY_DIR + +[ca] +default_ca = CA_default + +[CA_default] +serial = $dir/prog/serial +database = $dir/prog/index.txt +new_certs_dir = $dir/active +certificate = $dir/active/ca.crt +private_key = $dir/active/ca.key +default_days = $ENV::KEY_DAYS +default_crl_days = 30 +default_md = sha1 +preserve = no +email_in_dn = yes +nameopt = default_ca +certopt = default_ca +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_new_ca] +countryName = supplied +stateOrProvinceName = supplied +organizationName = supplied +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + + +[ req ] +default_bits = $ENV::KEY_SIZE +default_keyfile = privkey.pem +default_md = md5 +string_mask = nombstr +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[ req_distinguished_name ] +# Prompts +countryName = Country Name (2 letter code) +countryName_min = 2 +countryName_max = 2 +stateOrProvinceName = State or Province Name (full name) +localityName = Locality Name (eg, city) +0.organizationName = Organization Name (eg, company) +organizationalUnitName = Organizational Unit Name (eg, section) +commonName = Common Name (web address or username) +commonName_max = 64 +emailAddress = Email Address +emailAddress_max = 40 + +# Default Variables (environment variables set from ssl-admin.pl script. +countryName_default = $ENV::KEY_COUNTRY +commonName_default = $ENV::KEY_CN +emailAddress_default = $ENV::KEY_EMAIL +0.organizationName_default = $ENV::KEY_ORG +stateOrProvinceName_default = $ENV::KEY_PROVINCE +localityName_default = $ENV::KEY_CITY + +[ server ] + +# JY ADDED -- Make a cert with nsCertType set to "server" +basicConstraints=CA:FALSE +nsCertType = server +nsComment = "ssl-admin (OpenSSL) Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +extendedKeyUsage = serverAuth +keyUsage = digitalSignature, keyEncipherment + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = keyAgreement, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth +crlDistributionPoints = $ENV::KEY_CRL_LOC + +[ v3_ca ] +basicConstraints = CA:TRUE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +crlDistributionPoints = $ENV::KEY_CRL_LOC diff --git a/perl/patch-Makefile b/perl/patch-Makefile new file mode 100644 index 0000000..eafb84f --- /dev/null +++ b/perl/patch-Makefile @@ -0,0 +1,17 @@ +--- ./Makefile.orig 2014-06-21 10:27:18.000000000 +0200 ++++ ./Makefile 2014-06-21 10:41:45.000000000 +0200 +@@ -22,9 +22,9 @@ + [ -e "${DESTDIR}${ETCDIR}/ssl-admin" ] || mkdir -p ${DESTDIR}${ETCDIR}/ssl-admin + sed s+~~~ETCDIR~~~+${ETCDIR}+g man1/ssl-admin.1 > ${DESTDIR}${MANDIR}/man1/ssl-admin.1 + sed s+~~~ETCDIR~~~+${ETCDIR}+g man5/ssl-admin.conf.5 > ${DESTDIR}${MANDIR}/man5/ssl-admin.conf.5 +- install -c -g wheel -o root -m 0660 -S -v ssl-admin.conf ${DESTDIR}${ETCDIR}/ssl-admin/ssl-admin.conf.sample +- install -c -g wheel -o root -m 0660 -S -v openssl.conf ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample +- [ -e "${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf" ] || cp ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf ++ install -c -m 0660 -S -v ssl-admin.conf ${DESTDIR}${ETCDIR}/ssl-admin/ssl-admin.conf.sample ++ install -c -m 0660 -S -v openssl.conf ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample ++# [ -e "${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf" ] || cp ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf + sed -e "s+~~~ETCDIR~~~+${ETCDIR}+g" -e "s+~~~BUILD~~~+prod+g" ssl-admin > ssl-admin.mod +- install -c -g wheel -o root -m 0755 -S -v ssl-admin.mod ${DESTDIR}${BINDIR}/ssl-admin +- chmod 0444 ${DESTDIR}${ETCDIR}/ssl-admin/*.conf.sample ++ install -c -m 0755 -S -v ssl-admin.mod ${DESTDIR}${BINDIR}/ssl-admin ++# chmod 0444 ${DESTDIR}${ETCDIR}/ssl-admin/*.conf.sample diff --git a/perl/ssl-admin b/perl/ssl-admin new file mode 100755 index 0000000..5941e89 --- /dev/null +++ b/perl/ssl-admin @@ -0,0 +1,621 @@ +#!/usr/bin/perl +# +# Copyright (c) 2007, Eric F Crist +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# VERSION: ~~~VERSION~~~ +# $Id: ssl-admin 367 2014-10-21 15:54:27Z ecrist $ + +use strict; +use warnings; + +use File::Copy; + +## Read config file and die if there's a syntax error. +my $config_file = "~~~ETCDIR~~~/ssl-admin/ssl-admin.conf"; +die "$config_file doesn't exist. Did you copy the sample from $config_file.default?" unless (-e $config_file); +my $result = do $config_file; +die "Syntax error in $config_file\n\n" unless ($result); + +$ENV{'KEY_DIR'} = "~~~ETCDIR~~~/ssl-admin"; + + +### Program-specific settings here ### +my $program_name = "ssl-admin"; +my $build = "~~~BUILD~~~"; +my $menu_item = ""; +my $script_dir; +my $working_dir = $ENV{'KEY_DIR'}; +my $key_days = $ENV{'KEY_DAYS'}; +my $crl = "$working_dir/prog/crl.pem"; +my $key_config = "$working_dir/openssl.conf"; +my $cn= ""; +my $cn_literal=""; +my $user; +my $cn_o = 0; #Override existing value in $cn +my $zip_cmd; +my $curr_serial; +my $new_runtime = 0; +my $intermediate = "NO"; +my $key_size = $ENV{'KEY_SIZE'}; +my $serial; + +# Gather project information and run-time variables + +sub update_serial { + chomp($curr_serial = `cat $working_dir/prog/serial`); +} + +sub common_name { + my $cn_regex = '^[\w\s\-\.]+$'; + my $cn_new; + do { + print "Please enter certificate owner's name or ID.\nUsual format is first initial-last name (jdoe) or\n"; + print "hostname of server which will use this certificate.\nAll lower case, numbers OK.\nOwner [$cn]: "; + chomp($cn_new = <>); + } until $cn_new =~ m/$cn_regex/ or $cn =~ m/$cn_regex/; + if (($cn_new ne $cn) and ($cn_new ne "")){ + $cn_literal = $cn_new; + ($cn = $cn_literal) =~ s/\s/_/g; + print "\n\nFile names will use $cn.\n"; + } + $ENV{'KEY_CN'} = "$cn_literal"; +} + +sub project_info { + my $key_days_new; + my $intermediate_new; + if ($new_runtime == 1){ + print "Number of days key is valid for [$key_days]: "; + chomp($key_days_new = <>); + if (($key_days_new ne "$ENV{'KEY_DAYS'}") and ($key_days_new ne "")){ + $ENV{'KEY_DAYS'} = $key_days_new; + $key_days = $key_days_new; + } + do { + print "Key size in bits (up to 4096) [$key_size]: "; + chomp($key_size = <>); + } until ($key_size =~ m/^$/) or ($key_size =~ m/^[0-9]+$/ and ($key_size lt 4097)); + print "######################################################\n"; + print "#################### CAUTION!!! ####################\n"; + print "######################################################\n"; + do { + print "\nTurn on Intermediate CA certificate signing? (y/n): "; + chomp($intermediate_new = <>); + } until $intermediate_new =~ m/^[yn]+$/; + if ($intermediate_new eq "y"){ + $intermediate = "YES"; + print "\nYou have enabled intermediate certificate signing! This means\n"; + print "any certicates you sign this session will be authorized to sign\n"; + print "new certificates which will be trusted by you and anyone who\n"; + print "trusts you. This option is generally not going to be used.\n"; + } + elsif ($intermediate_new eq "n"){ + $intermediate = "NO"; + print "Intermediate CA certificate signing is disabled."; + } + } +} + +# Things are kinda crazy, so we're going to functionalize some things. + +sub create_csr { + my $yn = ""; + common_name(); + if ( -e "$working_dir/active/$cn.crt"){ + print "$cn already has a key. Creating another one will overwrite the existing key.\n"; + do { + print "$cn already has an active key. Do you want to overwrite? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ + common_name(); + } + } + do { + print "Would you like to password protect the private key (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl req_v3 -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } elsif ($yn eq "n") { + system("cd $working_dir && openssl req_v3 -nodes -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } +} + +sub sign_csr { + update_serial(); + print "===> Serial Number = $curr_serial\n"; + + if ($intermediate eq "NO"){ + print "=========> Signing request for $cn\n"; + `cd $working_dir && openssl ca -config $key_config -days $key_days -out $cn.crt -in $cn.csr -batch -extensions v3_req`; + } elsif ($intermediate eq "YES"){ + print "=========> Signing new Intermediate CA request for $cn\n"; + `cd $working_dir && openssl ca -config $key_config -policy policy_new_ca -out $cn.crt -extensions v3_ca -infiles $cn.csr -batch`; + } + if ($? != 0){ die "There was an error during openssl execution. Please look for error messages above."; } + print "=========> Moving certificates and keys to $working_dir/active for production.\n"; + system("mv $working_dir/$cn.crt $working_dir/active/"); + system("cp $working_dir/$cn.key $working_dir/csr/"); + system("mv $working_dir/$cn.key $working_dir/active/"); + system("mv $working_dir/active/$curr_serial.pem $working_dir/active/$cn.pem"); + my $yn = ""; + do { + print "Can I move signing request ($cn.csr) to the csr directory for archiving? (y/n): "; + if ($menu_item != 4){ + chomp($yn = <>); + } else { + $yn = 'y'; + } + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + `mv $working_dir/$cn.csr $working_dir/csr/`; + print "===> $cn.csr moved.\n" + } else { print "You will need to move $working_dir/$cn.csr to $working_dir/$cn.csr manually!"; } +} +sub new_ca { + my $yn; + common_name(); + print "\n\n===> Creating private key with $key_size bits and generating request.\n"; + do { + print "Do you want to password protect your CA private key? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl genrsa -des3 -out $cn.key $key_size"); + } else { + system("cd $working_dir && openssl genrsa -out $cn.key $key_size"); + } + print "===> Self-Signing request.\n"; + system("openssl req -new -x509 -extensions v3_ca -key $working_dir/$cn.key -out $working_dir/$cn.crt -days $key_days -config $key_config -batch"); + if ($? != 0){ die "OpenSSL exited with errors. Please read above and address the problems indicated."; } + print "===> Moving certficate and key to appropriate directory.\n"; + system("mv $working_dir/$cn.key $working_dir/active/ca.key"); + system("mv $working_dir/$cn.crt $working_dir/active/ca.crt"); +} + +sub create_server { + my $yn = ""; + common_name(); + if ( -e "$working_dir/active/$cn.crt"){ + print "$cn already has a key. Creating another one will overwrite the existing key.\n"; + do { + print "$cn already has an active key. Do you want to overwrite? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n") { + $cn_o = 1; + project_info(); + } + } + do { + print "Would you like to password protect the private key (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl req -extensions server -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } elsif ($yn eq "n"){ + system("cd $working_dir && openssl req -extensions server -nodes -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } +} +sub sign_server { + update_serial(); + print "===> Serial Number = $curr_serial\n"; + `cd $working_dir && openssl ca -config $key_config -extensions server -days $key_days -out $cn.crt -in $cn.csr -batch`; + if ($? != 0){ die "There was an error during openssl execution. Please look for error messages above."; } + print "=========> Moving certificates and keys to $working_dir/active for production.\n"; + system("mv $working_dir/$cn.crt $working_dir/active/"); + system("cp $working_dir/$cn.key $working_dir/csr/"); + system("mv $working_dir/$cn.key $working_dir/active/"); + system("mv $working_dir/active/$curr_serial.pem $working_dir/active/$cn.pem"); + my $yn = ""; + do { + print "Can I move signing request ($cn.csr) to the csr directory for archiving? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + `mv $working_dir/$cn.csr $working_dir/csr/`; + print "===> $cn.csr moved.\n" + } else { print "You will need to move $working_dir/$cn.csr to $working_dir/$cn.csr manually!\n"; + print "Remember that if you do not keep your server .csr you will need to build a new CA\n"; + print "if your server cert gets comprimised.\n"; + } +} + +sub gen_dh { + # This function generates the Diffie Hellman parameters + # openssl dhparam -out ./dh1024.pem 1024 + system("openssl dhparam -out $working_dir/dh$key_size.pem $key_size"); + print "Your Diffie Hellman parameters have been created."; +} + +# System Menu + +sub main_menu { + update_serial(); + print "\n\n=====================================================\n"; + print '# SSL-ADMIN v~~~VERSION~~~ #'; + print "\n=====================================================\n"; + print "Please enter the menu option from the following list:\n"; + print "1) Update run-time options:\n"; + print " Key Duration (days): $key_days\n"; + print " Current Serial #: $curr_serial\n"; + print " Key Size (bits): $key_size\n"; + print " Intermediate CA Signing: $intermediate\n"; + print "2) Create new Certificate Request\n"; + print "3) Sign a Certificate Request\n"; + print "4) Perform a one-step request/sign\n"; + print "5) Revoke a Certificate\n"; + print "6) Renew/Re-sign a past Certificate Request\n"; + print "7) View current Certificate Revokation List\n"; + print "8) View index information for certificate.\n"; + print "i) Generate a user config with in-line certifcates and keys.\n"; + print "z) Zip files for end user.\n"; + print "dh) Generate Diffie Hellman parameters.\n"; + print "CA) Create new Self-Signed CA certificate.\n"; + print "S) Create new Signed Server certificate.\n"; + print "q) Quit $program_name\n\n"; + print "Menu Item: "; + chomp($menu_item = <>); + menu_handler(); +} + +# Menu Handler + +sub menu_handler { + if ($menu_item eq "1"){ + $new_runtime = 1; + project_info(); + print "Run-time options reconfigured.\n\n\n"; + $new_runtime = 0; + main_menu(); + +### CREATE CERT MENU + + } elsif ($menu_item eq "2"){ + common_name(); + create_csr(); + +### SIGN CERT MENU + + } elsif ($menu_item eq "3"){ + common_name(); + sign_csr(); + +### CREATE/SIGN MENU + + } elsif ($menu_item eq "4"){ + common_name(); + create_csr(); + sign_csr(); + +### REVOKE MENU + + } elsif ($menu_item eq "5"){ + common_name(); + my $yn = ""; + print "=========> Revoking Certificate for $cn\n"; + do { + print "We're going to REVOKE an SSL certificate. Are you sure? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ main_menu(); } + my $revoke = `openssl x509 -noout -text -in $working_dir/active/$cn.crt | grep Serial`; + $revoke =~ m/Serial Number: ([A-F0-9]+)/; + $revoke = $1 or warn("Certificate doesn't seem valid."); + print "\n \$revoke = $revoke\n"; + `cd $working_dir/active && openssl ca -revoke $working_dir/active/$cn.crt -config $key_config -batch`; + print "=========> Generating new Certificate Revokation List $crl\n"; + `cd $working_dir/active && openssl ca -gencrl -out $crl -config $key_config`; + print "=========> Verifying Revokation: "; + my $check_revoke = `openssl crl -noout -text -in $crl | grep Serial`; + my $check_status = 0; + while ($check_revoke =~ m/Serial Number: ([A-F0-9]+)/g){ + if (hex $revoke == hex $1){ + $check_status = 1; + } + } + if ($check_status){ + print "SUCCESS!\n"; + } else { + print "ERRORS\n"; + } + print "=========> Moving $cn\'s files to $working_dir/revoked\n"; + my @exts = ('csr', 'pem', 'crt', 'key'); + foreach (@exts){ + move("$working_dir/active/$cn.$_", "$working_dir/revoked//$cn.$_") unless (! -e "$working_dir/active/$cn.$_"); + } + print "=========> Destroying previous packages built for $cn: "; + unlink "$working_dir/packages/$cn.ovpn", "$working_dir/packages/$cn.zip"; + print "DONE\n"; + print "=========> CSR for all users is in $working_dir/csr\n"; + print "===============> Changing file name for $cn\'s request to *.revoked"; + move("$working_dir/csr/$cn.csr", "$working_dir/csr/$cn.csr.revoked"); + sleep 3; + +### RE-SIGN/RENEW MENU + + } elsif ($menu_item eq "6"){ + $cn_o = 1; + common_name(); + my $yn; + if ( -e "$working_dir/csr/$cn.csr"){ + print "======> Moving archived request to working directory."; + system("mv $working_dir/csr/$cn.csr $working_dir"); + system("mv $working_dir/csr/$cn.key $working_dir"); + sign_csr(); + } elsif ( -e "$working_dir/csr/$cn.csr.revoked"){ + print "\n\nThe certificate you're trying to renew has been revoked!\n"; + do { + print "Are you sure you want to re-sign/renew this certficate? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n") { main_menu(); } + else { + system("mv $working_dir/csr/$cn.csr.revoked $working_dir/$cn.csr"); + system("mv $working_dir/csr/$cn.key $working_dir/$cn.key"); + sign_csr(); + } + } else { + print "There is no request in the archive for $cn.\n"; + } + sleep 2; + +### View Current CRL MENU + + } elsif ($menu_item eq "7"){ + if (! -e $crl){ + system("cd $working_dir/active && openssl ca -gencrl -config $key_config -out $crl -batch"); + } + system("openssl crl -text -noout -in $crl"); + sleep 3; + + +### Read INDEX Menu + + } elsif ($menu_item eq "8"){ + common_name(); + system("more $working_dir/prog/index.txt | grep $cn"); + sleep 3; + +### Create a config file with inline certifcates and keys. If the config has +### options for the inline files, remove them + + } elsif ($menu_item eq "i"){ + + my $yn; + common_name(); + print "========> Creating in-line configuration for $cn in $working_dir/packages\n"; + open TEMPLATECONF, "<", "$working_dir/packages/client.ovpn" or die $!; + open NEWCONF, "+>", "$working_dir/packages/$cn.ovpn" or die $!; + my @files = ("ca.crt", "$cn.crt", "$cn.key", "ta.key"); + # read the template, get rid of the cert, key, and ca files + while ($_ = ){ + if (/^[\t\s]*(cert|ca|key|tls-auth)[\t\s]+/){ + # we don't want to write these to the new config + } else { + print NEWCONF $_; + } + } + # we've written our config, now lets write the certs + my $loop=0; + foreach my $file (@files){ + -e "$working_dir/active/$file" or next; + open CERT, "<", "$working_dir/active/$file" or die $!; + my $started = 0; + my $certificate; + while ($_ = ){ + # see if we've already started + if ($started){ + $certificate .= $_; + } + # look for certificate, store it in memory + if (/^-{5}BEGIN/){ + # start of cert + $certificate .= $_; + $started = 1; + } + # look for the end + if (/^-{5}END/){ + # this is the end, do the right thing + if ($loop == 0){ + print NEWCONF "\n\n$certificate"; + } elsif ($loop == 1){ + print NEWCONF "\n\n$certificate"; + } elsif ($loop == 2) { + print NEWCONF "\n\n$certificate"; + } elsif ($loop == 3) { + print NEWCONF "\n\n$certificate\n"; + } + next; + } + } + $loop++; + } + close TEMPLATECONF; + close NEWCONF; + print "======> Inline configuration available at $working_dir/packages/$cn.ovpn\n"; + +### Create ZIP FILE Menu + + } elsif ($menu_item eq "z"){ + my $yn; + common_name(); + print "=========> Creating .zip file for $cn in $working_dir/packages\n"; + print "=================> Moving $cn.crt\n"; + `cp $working_dir/active/$cn.crt $working_dir/packages/client.crt`; + print "=================> Moving $cn.key\n"; + `cp $working_dir/active/$cn.key $working_dir/packages/client.key`; + do { + print "Is this certificate for an OpenVPN client install? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ + $zip_cmd = "cd $working_dir/packages/ && zip $cn.zip client.crt client.key ca.crt"; + } else { + $zip_cmd = "cd $working_dir/packages/ && zip $cn.zip client.crt client.key ca.crt client.ovpn"; + } + print "=================> Zipping File\n"; + system($zip_cmd); + print "=================> Cleaning up files: "; + `rm $working_dir/packages/client.crt`; + print "client.crt, "; + `rm $working_dir/packages/client.key`; + print "client.key.\n"; + print "\nYou may distribute $working_dir/packages/$cn.zip to the end user.\n"; + sleep 3; + + } elsif ($menu_item eq "dh"){ + gen_dh(); +### CREATE NEW SELF-SIGNED CA CERTIFICATE + } elsif ($menu_item eq "CA"){ + new_ca(); +### CREATE NEW SIGNED SERVER CERTIFICATE + } elsif ($menu_item eq "S"){ + common_name(); + create_server(); + sign_server(); + } elsif ($menu_item eq "q"){ + exit 0; + } +} +# Software header/introduction +# +if ( ! -e "$working_dir"){ + print "$working_dir doesn't exist. Is the variable set correctly?\n"; + exit 1; +} +print "This program will walk you through requesting, signing,\norganizing and revoking SSL certificates.\n\n"; +if ($> != 0){ + if ($build eq "devel"){ + print "\n\nRunning devel build - this isn't secure!\n\n"; + } else { + die "Sorry, but I need to be run as the root user.\n\n"; + } +} + +if ( ! -e "$working_dir/prog/install"){ + + if ( ! -e "$working_dir/active"){ + my $yn; + print "Looks like this is a new install, installing...\n"; + do { + print "You will first need to edit the ~~~ETCDIR~~~/ssl-admin/ssl-admin.conf\n"; + print "default variables. Have you done this? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn ne "y") { die "Please edit ~~~ETCDIR~~~/ssl-admin/ssl-admin.conf and run me again." } + mkdir "$working_dir/active", 0750; + mkdir "$working_dir/revoked", 0750; + mkdir "$working_dir/csr", 0750; + mkdir "$working_dir/packages", 0750; + mkdir "$working_dir/prog", 0750; + } + my $yn; + do { + print "I need the CA credentials. Would you like to create a new CA key and\n"; + print "certificate now? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + new_ca(); + if ( ! -e "$working_dir/index.txt"){ + open(FILE, ">$working_dir/prog/index.txt"); + close(FILE); + open(FILE, ">$working_dir/prog/index.txt.attr"); + print FILE "unique_subject = no"; + close(FILE); + open (FILE, ">$working_dir/prog/serial"); + print FILE "01"; + close(FILE); + } + } + else { + if ( ! -e "$working_dir/active/ca.crt"){ + my $ca_cert; + print "I need your ca.crt file. Please enter path and filename so I can have a copy: \n"; + print "Location: "; + chomp($ca_cert = <>); + if (-e $ca_cert){ + system("more $ca_cert | grep -q \"BEGIN CERTIFICATE\""); + if ($? != 0){ die "$ca_cert doesn\'t look like a certificate." } + system("more $ca_cert | grep -q \"CA:TRUE\""); +# if ($? != 0){die "$ca_cert looks valid, but isn't authorized to sign other certificates." } + system("cp $ca_cert $working_dir/active/ca.crt"); + system("cp $ca_cert $working_dir/packages/ca.crt"); + } else { die "File $ca_cert doesn\'t exist. Please locate the file and try again.\n"; } + } + if ( ! -e "$working_dir/active/ca.key"){ + my $ca_key; + print "I need your ca.key file. Please enter path and filename so I can have a copy: \n"; + print "Location: "; + chomp($ca_key = <>); + if (-e $ca_key){ + system("more $ca_key | grep -q \"BEGIN RSA PRIVATE KEY\""); + if ($? != 0 ){ die "$ca_key doesn\'t look like a private key." } + system("cp $ca_key $working_dir/active/ca.key"); + } else { die "File $ca_key doesn\'t exist. Please locate the file and try again.\n"; } + } + print "If you have an existing index.txt or index.txt.attr, you need to manually\n"; + print "place them in the $working_dir/prog/ directory.\n"; + do { + print "What serial number shall I start with? [01]: "; + chomp($serial = <>); + } until $serial =~ m/^[A-F0-9]+$/; + open (FILE, ">$working_dir/prog/serial"); + print FILE "$serial"; + close(FILE); + } + if ( ! -e "$working_dir/index.txt"){ + open(FILE, ">$working_dir/prog/index.txt"); + close(FILE); + open(FILE, ">$working_dir/prog/index.txt.attr"); + print FILE "unique_subject = no"; + close(FILE); + open (FILE, ">$working_dir/prog/serial"); + print FILE "01"; + close(FILE); + } + system("echo `date` > $working_dir/prog/install"); +} +if (! -e $crl){ + print "===> Creating initial CRL."; + system("cd $working_dir/active && openssl ca -gencrl -batch -config $key_config -out $crl"); +} +my $install_date = `cat $working_dir/prog/install`; +print "ssl-admin installed $install_date"; +update_serial(); + +# Make sure packaged ca.crt is up to date. +system("cp $working_dir/active/ca.crt $working_dir/packages/"); +if ( ! -e "$working_dir/packages/client.ovpn"){ + print "OPTIONAL: I can't find your OpenVPN client config. Please copy your config to\n$working_dir/packages/client.ovpn"; +} +while ($menu_item ne "q"){ + main_menu(); +} diff --git a/perl/ssl-admin.conf b/perl/ssl-admin.conf new file mode 100644 index 0000000..775f56e --- /dev/null +++ b/perl/ssl-admin.conf @@ -0,0 +1,21 @@ +## Set default values here. +# +# The following values can be changed without affecting +# your CA key. + +$ENV{'KEY_SIZE'} = "1024"; +$ENV{'KEY_DAYS'} = "3650"; +$ENV{'KEY_CN'} = ""; +$ENV{'KEY_CRL_LOC'} = "URI:http://CRL_URI"; + + +## WARNING!!! ## +# +# Changing the following values has vast consequences. +# These values must match what's in your root CA certificate. + +$ENV{'KEY_COUNTRY'} = "XX"; +$ENV{'KEY_PROVINCE'} = "STATE/PROVINCE"; +$ENV{'KEY_CITY'} = "CITY"; +$ENV{'KEY_ORG'} = "ORGANIZATION"; +$ENV{'KEY_EMAIL'} = 'EMAIL_ADDRESS'; diff --git a/perl/ssl-admin.orig b/perl/ssl-admin.orig new file mode 100755 index 0000000..1a4c09f --- /dev/null +++ b/perl/ssl-admin.orig @@ -0,0 +1,612 @@ +#!/usr/bin/perl +# +# Copyright (c) 2007, Eric F Crist +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# VERSION: ~~~VERSION~~~ +# $Id: ssl-admin 346 2014-04-15 17:28:06Z ecrist $ + +use strict; +use warnings; + + +## Read config file and die if there's a syntax error. +my $config_file = "~~~ETCDIR~~~/ssl-admin/ssl-admin.conf"; +die "$config_file doesn't exist. Did you copy the sample from $config_file.default?" unless (-e $config_file); +my $result = do $config_file; +die "Syntax error in $config_file\n\n" unless ($result); + +$ENV{'KEY_DIR'} = "~~~ETCDIR~~~/ssl-admin"; + + +### Program-specific settings here ### +my $program_name = "ssl-admin"; +my $menu_item = ""; +my $script_dir; +my $working_dir = $ENV{'KEY_DIR'}; +my $key_days = $ENV{'KEY_DAYS'}; +my $crl = "$working_dir/prog/crl.pem"; +my $key_config = "$working_dir/openssl.conf"; +my $cn= ""; +my $cn_literal=""; +my $user; +my $cn_o = 0; #Override existing value in $cn +my $zip_cmd; +my $curr_serial; +my $new_runtime = 0; +my $intermediate = "NO"; +my $key_size = $ENV{'KEY_SIZE'}; +my $serial; + +# Gather project information and run-time variables + +sub update_serial { + chomp($curr_serial = `cat $working_dir/prog/serial`); +} + +sub common_name { + my $cn_regex = '^[\w\s\-\.]+$'; + my $cn_new; + do { + print "Please enter certificate owner's name or ID.\nUsual format is first initial-last name (jdoe) or\n"; + print "hostname of server which will use this certificate.\nAll lower case, numbers OK.\nOwner [$cn]: "; + chomp($cn_new = <>); + } until $cn_new =~ m/$cn_regex/ or $cn =~ m/$cn_regex/; + if (($cn_new ne $cn) and ($cn_new ne "")){ + $cn_literal = $cn_new; + ($cn = $cn_literal) =~ s/\s/_/g; + print "\n\nFile names will use $cn.\n"; + } + $ENV{'KEY_CN'} = "$cn_literal"; +} + +sub project_info { + my $key_days_new; + my $intermediate_new; + if ($new_runtime == 1){ + print "Number of days key is valid for [$key_days]: "; + chomp($key_days_new = <>); + if (($key_days_new ne "$ENV{'KEY_DAYS'}") and ($key_days_new ne "")){ + $ENV{'KEY_DAYS'} = $key_days_new; + $key_days = $key_days_new; + } + do { + print "Key size in bits (up to 4096) [$key_size]: "; + chomp($key_size = <>); + } until ($key_size =~ m/^$/) or ($key_size =~ m/^[0-9]+$/ and ($key_size lt 4097)); + print "######################################################\n"; + print "#################### CAUTION!!! ####################\n"; + print "######################################################\n"; + do { + print "\nTurn on Intermediate CA certificate signing? (y/n): "; + chomp($intermediate_new = <>); + } until $intermediate_new =~ m/^[yn]+$/; + if ($intermediate_new eq "y"){ + $intermediate = "YES"; + print "\nYou have enabled intermediate certificate signing! This means\n"; + print "any certicates you sign this session will be authorized to sign\n"; + print "new certificates which will be trusted by you and anyone who\n"; + print "trusts you. This option is generally not going to be used.\n"; + } + elsif ($intermediate_new eq "n"){ + $intermediate = "NO"; + print "Intermediate CA certificate signing is disabled."; + } + } +} + +# Things are kinda crazy, so we're going to functionalize some things. + +sub create_csr { + my $yn = ""; + common_name(); + if ( -e "$working_dir/active/$cn.crt"){ + print "$cn already has a key. Creating another one will overwrite the existing key.\n"; + do { + print "$cn already has an active key. Do you want to overwrite? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ + common_name(); + } + } + do { + print "Would you like to password protect the private key (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl req -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } elsif ($yn eq "n") { + system("cd $working_dir && openssl req -nodes -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } +} + +sub sign_csr { + update_serial(); + print "===> Serial Number = $curr_serial\n"; + + if ($intermediate eq "NO"){ + print "=========> Signing request for $cn\n"; + `cd $working_dir && openssl ca -config $key_config -days $key_days -out $cn.crt -in $cn.csr -batch`; + } elsif ($intermediate eq "YES"){ + print "=========> Signing new Intermediate CA request for $cn\n"; + `cd $working_dir && openssl ca -config $key_config -policy policy_new_ca -out $cn.crt -extensions v3_ca -infiles $cn.csr -batch`; + } + if ($? != 0){ die "There was an error during openssl execution. Please look for error messages above."; } + print "=========> Moving certificates and keys to $working_dir/active for production.\n"; + system("mv $working_dir/$cn.crt $working_dir/active/"); + system("cp $working_dir/$cn.key $working_dir/csr/"); + system("mv $working_dir/$cn.key $working_dir/active/"); + system("mv $working_dir/active/$curr_serial.pem $working_dir/active/$cn.pem"); + my $yn = ""; + do { + print "Can I move signing request ($cn.csr) to the csr directory for archiving? (y/n): "; + if ($menu_item != 4){ + chomp($yn = <>); + } else { + $yn = 'y'; + } + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + `mv $working_dir/$cn.csr $working_dir/csr/`; + print "===> $cn.csr moved.\n" + } else { print "You will need to move $working_dir/$cn.csr to $working_dir/$cn.csr manually!"; } +} +sub new_ca { + my $yn; + common_name(); + print "\n\n===> Creating private key with $key_size bits and generating request.\n"; + do { + print "Do you want to password protect your CA private key? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl genrsa -des3 -out $cn.key $key_size"); + } else { + system("cd $working_dir && openssl genrsa -out $cn.key $key_size"); + } + print "===> Self-Signing request.\n"; + system("openssl req -new -x509 -extensions v3_ca -key $working_dir/$cn.key -out $working_dir/$cn.crt -days $key_days -config $key_config -batch"); + if ($? != 0){ die "OpenSSL exited with errors. Please read above and address the problems indicated."; } + print "===> Moving certficate and key to appropriate directory.\n"; + system("mv $working_dir/$cn.key $working_dir/active/ca.key"); + system("mv $working_dir/$cn.crt $working_dir/active/ca.crt"); +} + +sub create_server { + my $yn = ""; + common_name(); + if ( -e "$working_dir/active/$cn.crt"){ + print "$cn already has a key. Creating another one will overwrite the existing key.\n"; + do { + print "$cn already has an active key. Do you want to overwrite? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n") { + $cn_o = 1; + project_info(); + } + } + do { + print "Would you like to password protect the private key (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl req -extensions server -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } elsif ($yn eq "n"){ + system("cd $working_dir && openssl req -extensions server -nodes -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } +} +sub sign_server { + update_serial(); + print "===> Serial Number = $curr_serial\n"; + `cd $working_dir && openssl ca -config $key_config -extensions server -days $key_days -out $cn.crt -in $cn.csr -batch`; + if ($? != 0){ die "There was an error during openssl execution. Please look for error messages above."; } + print "=========> Moving certificates and keys to $working_dir/active for production.\n"; + system("mv $working_dir/$cn.crt $working_dir/active/"); + system("cp $working_dir/$cn.key $working_dir/csr/"); + system("mv $working_dir/$cn.key $working_dir/active/"); + system("mv $working_dir/active/$curr_serial.pem $working_dir/active/$cn.pem"); + my $yn = ""; + do { + print "Can I move signing request ($cn.csr) to the csr directory for archiving? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + `mv $working_dir/$cn.csr $working_dir/csr/`; + print "===> $cn.csr moved.\n" + } else { print "You will need to move $working_dir/$cn.csr to $working_dir/$cn.csr manually!\n"; + print "Remember that if you do not keep your server .csr you will need to build a new CA\n"; + print "if your server cert gets comprimised.\n"; + } +} + +sub gen_dh { + # This function generates the Diffie Hellman parameters + # openssl dhparam -out ./dh1024.pem 1024 + system("openssl dhparam -out $working_dir/dh$key_size.pem $key_size"); + print "Your Diffie Hellman parameters have been created."; +} + +# System Menu + +sub main_menu { + update_serial(); + print "\n\n=====================================================\n"; + print '# SSL-ADMIN #'; + print "\n=====================================================\n"; + print "Please enter the menu option from the following list:\n"; + print "1) Update run-time options:\n"; + print " Key Duration (days): $key_days\n"; + print " Current Serial #: $curr_serial\n"; + print " Key Size (bits): $key_size\n"; + print " Intermediate CA Signing: $intermediate\n"; + print "2) Create new Certificate Request\n"; + print "3) Sign a Certificate Request\n"; + print "4) Perform a one-step request/sign\n"; + print "5) Revoke a Certificate\n"; + print "6) Renew/Re-sign a past Certificate Request\n"; + print "7) View current Certificate Revokation List\n"; + print "8) View index information for certificate.\n"; + print "i) Generate a user config with in-line certifcates and keys.\n"; + print "z) Zip files for end user.\n"; + print "dh) Generate Diffie Hellman parameters.\n"; + print "CA) Create new Self-Signed CA certificate.\n"; + print "S) Create new Signed Server certificate.\n"; + print "q) Quit $program_name\n\n"; + print "Menu Item: "; + chomp($menu_item = <>); + menu_handler(); +} + +# Menu Handler + +sub menu_handler { + if ($menu_item eq "1"){ + $new_runtime = 1; + project_info(); + print "Run-time options reconfigured.\n\n\n"; + $new_runtime = 0; + main_menu(); + +### CREATE CERT MENU + + } elsif ($menu_item eq "2"){ + common_name(); + create_csr(); + +### SIGN CERT MENU + + } elsif ($menu_item eq "3"){ + common_name(); + sign_csr(); + +### CREATE/SIGN MENU + + } elsif ($menu_item eq "4"){ + common_name(); + create_csr(); + sign_csr(); + +### REVOKE MENU + + } elsif ($menu_item eq "5"){ + common_name(); + my $yn = ""; + print "=========> Revoking Certificate for $cn\n"; + do { + print "We're going to REVOKE an SSL certificate. Are you sure? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ main_menu(); } + my $revoke = `openssl x509 -noout -text -in $working_dir/active/$cn.crt | grep Serial`; + $revoke =~ m/Serial Number: ([A-F0-9]+)/; + $revoke = $1 or warn("Certificate doesn't seem valid."); + print "\n \$revoke = $revoke\n"; + `cd $working_dir/active && openssl ca -revoke $working_dir/active/$cn.crt -config $key_config -batch`; + print "=========> Generating new Certificate Revokation List $crl\n"; + `cd $working_dir/active && openssl ca -gencrl -out $crl -config $key_config`; + print "=========> Verifying Revokation: "; + my $check_revoke = `openssl crl -noout -text -in $crl | grep Serial`; + my $check_status = 0; + while ($check_revoke =~ m/Serial Number: ([A-F0-9]+)/g){ + if (hex $revoke == hex $1){ + $check_status = 1; + } + } + if ($check_status){ + print "SUCCESS!\n"; + } else { + print "ERRORS\n"; + } + print "=========> Moving $cn\'s files to $working_dir/revoked\n"; + `mv $working_dir/active/$cn.* $working_dir/revoked/`; + print "=========> Destroying previous packages built for $cn: "; + `rm -rf $working_dir/packages/$cn.*`; + print "DONE\n"; + print "=========> CSR for all users is in $working_dir/csr\n"; + print "===============> Changing file name for $cn\'s request to *.revoked"; + `mv $working_dir/csr/$cn.csr $working_dir/csr/$cn.csr.revoked`; + sleep 3; + +### RE-SIGN/RENEW MENU + + } elsif ($menu_item eq "6"){ + $cn_o = 1; + common_name(); + my $yn; + if ( -e "$working_dir/csr/$cn.csr"){ + print "======> Moving archived request to working directory."; + system("mv $working_dir/csr/$cn.csr $working_dir"); + system("mv $working_dir/csr/$cn.key $working_dir"); + sign_csr(); + } elsif ( -e "$working_dir/csr/$cn.csr.revoked"){ + print "\n\nThe certificate you're trying to renew has been revoked!\n"; + do { + print "Are you sure you want to re-sign/renew this certficate? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n") { main_menu(); } + else { + system("mv $working_dir/csr/$cn.csr.revoked $working_dir/$cn.csr"); + system("mv $working_dir/csr/$cn.key $working_dir/$cn.key"); + sign_csr(); + } + } else { + print "There is no request in the archive for $cn.\n"; + } + sleep 2; + +### View Current CRL MENU + + } elsif ($menu_item eq "7"){ + if (! -e $crl){ + system("cd $working_dir/active && openssl ca -gencrl -config $key_config -out $crl -batch"); + } + system("openssl crl -text -noout -in $crl"); + sleep 3; + + +### Read INDEX Menu + + } elsif ($menu_item eq "8"){ + common_name(); + system("more $working_dir/prog/index.txt | grep $cn"); + sleep 3; + +### Create a config file with inline certifcates and keys. If the config has +### options for the inline files, remove them + + } elsif ($menu_item eq "i"){ + + my $yn; + common_name(); + print "========> Creating in-line configuration for $cn in $working_dir/packages\n"; + open TEMPLATECONF, "<", "$working_dir/packages/client.ovpn" or die $!; + open NEWCONF, "+>", "$working_dir/packages/$cn.ovpn" or die $!; + my @files = ("ca.crt", "$cn.crt", "$cn.key" "ta.key"); + # read the template, get rid of the cert, key, and ca files + while ($_ = ){ + if (/^[\t\s]*(cert|ca|key|tls-auth)/){ + # we don't want to write these to the new config + } else { + print NEWCONF $_; + } + } + # we've written our config, now lets write the certs + my $loop=0; + foreach my $file (@files){ + -e "$working_dir/active/$file" or next; + open CERT, "<", "$working_dir/active/$file" or die $!; + my $started = 0; + my $certificate; + while ($_ = ){ + # see if we've already started + if ($started){ + $certificate .= $_; + } + # look for certificate, store it in memory + if (/^-{5}BEGIN/){ + # start of cert + $certificate .= $_; + $started = 1; + } + # look for the end + if (/^-{5}END/){ + # this is the end, do the right thing + if ($loop == 0){ + print NEWCONF "\n\n$certificate"; + } elsif ($loop == 1){ + print NEWCONF "\n\n$certificate"; + } elsif ($loop == 2) { + print NEWCONF "\n\n$certificate"; + } elsif ($loop == 3) { + print NEWCONF "\n\n$certificate\n"; + } + next; + } + } + $loop++; + } + close TEMPLATECONF; + close NEWCONF; + print "======> Inline configuration available at $working_dir/packages/$cn.ovpn\n"; + +### Create ZIP FILE Menu + + } elsif ($menu_item eq "z"){ + my $yn; + common_name(); + print "=========> Creating .zip file for $cn in $working_dir/packages\n"; + print "=================> Moving $cn.crt\n"; + `cp $working_dir/active/$cn.crt $working_dir/packages/client.crt`; + print "=================> Moving $cn.key\n"; + `cp $working_dir/active/$cn.key $working_dir/packages/client.key`; + do { + print "Is this certificate for an OpenVPN client install? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ + $zip_cmd = "cd $working_dir/packages/ && zip $cn.zip client.crt client.key ca.crt"; + } else { + $zip_cmd = "cd $working_dir/packages/ && zip $cn.zip client.crt client.key ca.crt client.ovpn"; + } + print "=================> Zipping File\n"; + system($zip_cmd); + print "=================> Cleaning up files: "; + `rm $working_dir/packages/client.crt`; + print "client.crt, "; + `rm $working_dir/packages/client.key`; + print "client.key.\n"; + print "\nYou may distribute $working_dir/packages/$cn.zip to the end user.\n"; + sleep 3; + + } elsif ($menu_item eq "dh"){ + gen_dh(); +### CREATE NEW SELF-SIGNED CA CERTIFICATE + } elsif ($menu_item eq "CA"){ + new_ca(); +### CREATE NEW SIGNED SERVER CERTIFICATE + } elsif ($menu_item eq "S"){ + common_name(); + create_server(); + sign_server(); + } elsif ($menu_item eq "q"){ + exit 0; + } +} +# Software header/introduction +# +if ( ! -e "$working_dir"){ + print "$working_dir doesn't exist. Is the variable set correctly?\n"; + exit 1; +} +print "This program will walk you through requesting, signing,\norganizing and revoking SSL certificates.\n\n"; +if ($> != 0){ + die "Sorry, but I need to be run as the root user.\n\n"; +} + +if ( ! -e "$working_dir/prog/install"){ + + if ( ! -e "$working_dir/active"){ + my $yn; + print "Looks like this is a new install, installing...\n"; + do { + print "You will first need to edit the ~~~ETCDIR~~~/ssl-admin/ssl-admin.conf\n"; + print "default variables. Have you done this? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn ne "y") { die "Please edit ~~~ETCDIR~~~/ssl-admin/ssl-admin.conf and run me again." } + mkdir "$working_dir/active", 0750; + mkdir "$working_dir/revoked", 0750; + mkdir "$working_dir/csr", 0750; + mkdir "$working_dir/packages", 0750; + mkdir "$working_dir/prog", 0750; + } + my $yn; + do { + print "I need the CA credentials. Would you like to create a new CA key and\n"; + print "certificate now? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + new_ca(); + if ( ! -e "$working_dir/index.txt"){ + open(FILE, ">$working_dir/prog/index.txt"); + close(FILE); + open(FILE, ">$working_dir/prog/index.txt.attr"); + print FILE "unique_subject = no"; + close(FILE); + open (FILE, ">$working_dir/prog/serial"); + print FILE "01"; + close(FILE); + } + } + else { + if ( ! -e "$working_dir/active/ca.crt"){ + my $ca_cert; + print "I need your ca.crt file. Please enter path and filename so I can have a copy: \n"; + print "Location: "; + chomp($ca_cert = <>); + if (-e $ca_cert){ + system("more $ca_cert | grep -q \"BEGIN CERTIFICATE\""); + if ($? != 0){ die "$ca_cert doesn\'t look like a certificate." } + system("more $ca_cert | grep -q \"CA:TRUE\""); +# if ($? != 0){die "$ca_cert looks valid, but isn't authorized to sign other certificates." } + system("cp $ca_cert $working_dir/active/ca.crt"); + system("cp $ca_cert $working_dir/packages/ca.crt"); + } else { die "File $ca_cert doesn\'t exist. Please locate the file and try again.\n"; } + } + if ( ! -e "$working_dir/active/ca.key"){ + my $ca_key; + print "I need your ca.key file. Please enter path and filename so I can have a copy: \n"; + print "Location: "; + chomp($ca_key = <>); + if (-e $ca_key){ + system("more $ca_key | grep -q \"BEGIN RSA PRIVATE KEY\""); + if ($? != 0 ){ die "$ca_key doesn\'t look like a private key." } + system("cp $ca_key $working_dir/active/ca.key"); + } else { die "File $ca_key doesn\'t exist. Please locate the file and try again.\n"; } + } + print "If you have an existing index.txt or index.txt.attr, you need to manually\n"; + print "place them in the $working_dir/prog/ directory.\n"; + do { + print "What serial number shall I start with? [01]: "; + chomp($serial = <>); + } until $serial =~ m/^[A-F0-9]+$/; + open (FILE, ">$working_dir/prog/serial"); + print FILE "$serial"; + close(FILE); + } + if ( ! -e "$working_dir/index.txt"){ + open(FILE, ">$working_dir/prog/index.txt"); + close(FILE); + open(FILE, ">$working_dir/prog/index.txt.attr"); + print FILE "unique_subject = no"; + close(FILE); + open (FILE, ">$working_dir/prog/serial"); + print FILE "01"; + close(FILE); + } + system("echo `date` > $working_dir/prog/install"); +} +if (! -e $crl){ + print "===> Creating initial CRL."; + system("cd $working_dir/active && openssl ca -gencrl -batch -config $key_config -out $crl"); +} +my $install_date = `cat $working_dir/prog/install`; +print "ssl-admin installed $install_date"; +update_serial(); + +# Make sure packaged ca.crt is up to date. +system("cp $working_dir/active/ca.crt $working_dir/packages/"); +if ( ! -e "$working_dir/packages/client.ovpn"){ + print "OPTIONAL: I can't find your OpenVPN client config. Please copy your config to\n$working_dir/packages/client.ovpn"; +} +while ($menu_item ne "q"){ + main_menu(); +} diff --git a/ports/Makefile b/ports/Makefile new file mode 100644 index 0000000..58edc8a --- /dev/null +++ b/ports/Makefile @@ -0,0 +1,23 @@ +# Created by: Eric Crist +# $FreeBSD: ports/security/ssl-admin/Makefile,v 1.4 2008/07/27 19:05:31 beech Exp $ + + +PORTNAME= ssl-admin +DISTVERSION= ~~~VERSION~~~ +CATEGORIES= security +MASTER_SITES= ftp://ftp.secure-computing.net/pub/FreeBSD/ports/ssl-admin/ \ + ftp://ftp2.secure-computing.net/pub/FreeBSD/ports/ssl-admin/ + +MAINTAINER= ecrist@secure-computing.net +COMMENT= OpenSSL certificate manager with OpenVPN support + +LICENSE= BSD3CLAUSE + +USES= perl5 shebangfix +USE_PERL5= run +RUN_DEPENDS= zip:${PORTSDIR}/archivers/zip +SUB_FILES= pkg-message +MAKE_ENV= ETCDIR=${PREFIX}/etc BINDIR=${PREFIX}/bin \ + MANDIR=${MANPREFIX}/man + +.include diff --git a/ports/distinfo b/ports/distinfo new file mode 100644 index 0000000..9eada8b --- /dev/null +++ b/ports/distinfo @@ -0,0 +1,3 @@ +MD5 (ssl-admin-1.0b1.2.tar.gz) = 5724066b6982d494ce57d436d1396d17 +SHA256 (ssl-admin-1.0b1.2.tar.gz) = b07b2a67d11ce3de3fb7867ea44539093dda42fdb2737216375a6c5f7e3c3b9f +SIZE (ssl-admin-1.0b1.2.tar.gz) = 8076 diff --git a/ports/files/patch-Makefile b/ports/files/patch-Makefile new file mode 100644 index 0000000..eafb84f --- /dev/null +++ b/ports/files/patch-Makefile @@ -0,0 +1,17 @@ +--- ./Makefile.orig 2014-06-21 10:27:18.000000000 +0200 ++++ ./Makefile 2014-06-21 10:41:45.000000000 +0200 +@@ -22,9 +22,9 @@ + [ -e "${DESTDIR}${ETCDIR}/ssl-admin" ] || mkdir -p ${DESTDIR}${ETCDIR}/ssl-admin + sed s+~~~ETCDIR~~~+${ETCDIR}+g man1/ssl-admin.1 > ${DESTDIR}${MANDIR}/man1/ssl-admin.1 + sed s+~~~ETCDIR~~~+${ETCDIR}+g man5/ssl-admin.conf.5 > ${DESTDIR}${MANDIR}/man5/ssl-admin.conf.5 +- install -c -g wheel -o root -m 0660 -S -v ssl-admin.conf ${DESTDIR}${ETCDIR}/ssl-admin/ssl-admin.conf.sample +- install -c -g wheel -o root -m 0660 -S -v openssl.conf ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample +- [ -e "${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf" ] || cp ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf ++ install -c -m 0660 -S -v ssl-admin.conf ${DESTDIR}${ETCDIR}/ssl-admin/ssl-admin.conf.sample ++ install -c -m 0660 -S -v openssl.conf ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample ++# [ -e "${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf" ] || cp ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf.sample ${DESTDIR}${ETCDIR}/ssl-admin/openssl.conf + sed -e "s+~~~ETCDIR~~~+${ETCDIR}+g" -e "s+~~~BUILD~~~+prod+g" ssl-admin > ssl-admin.mod +- install -c -g wheel -o root -m 0755 -S -v ssl-admin.mod ${DESTDIR}${BINDIR}/ssl-admin +- chmod 0444 ${DESTDIR}${ETCDIR}/ssl-admin/*.conf.sample ++ install -c -m 0755 -S -v ssl-admin.mod ${DESTDIR}${BINDIR}/ssl-admin ++# chmod 0444 ${DESTDIR}${ETCDIR}/ssl-admin/*.conf.sample diff --git a/ports/files/pkg-message.in b/ports/files/pkg-message.in new file mode 100644 index 0000000..d2a7e2b --- /dev/null +++ b/ports/files/pkg-message.in @@ -0,0 +1,6 @@ +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +Please edit the configuration file ssl-admin.conf before running +ssl-admin for the first time. + +You're now ready to manage your SSL certificates. +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * diff --git a/ports/pkg-descr b/ports/pkg-descr new file mode 100644 index 0000000..663fe3a --- /dev/null +++ b/ports/pkg-descr @@ -0,0 +1,11 @@ +ssl-admin was designed to create a user-friendly, menu-driven interface +to the OpenSSL programs. + +ssl-admin will help you do the following tasks with SSL certificates: + * Create your own CA certificate. + * Create new Certificate Signing Requests + * Sign existing Certificate Signing Requests + * Manage Certificate Revokation Lists + * Export configurations and certificates for OpenVPN. + +WWW: http://www.secure-computing.net/ssl-admin/ diff --git a/ports/pkg-plist b/ports/pkg-plist new file mode 100644 index 0000000..abec60a --- /dev/null +++ b/ports/pkg-plist @@ -0,0 +1,6 @@ +bin/ssl-admin +%%ETCDIR%%/openssl.conf.sample +%%ETCDIR%%/ssl-admin.conf.sample +man/man1/ssl-admin.1.gz +man/man5/ssl-admin.conf.5.gz +@dirrmtry %%ETCDIR%% diff --git a/ssl-admin-1.0.3.tar.gz b/ssl-admin-1.0.3.tar.gz new file mode 100644 index 0000000..4289673 Binary files /dev/null and b/ssl-admin-1.0.3.tar.gz differ diff --git a/ssl-admin-1.0.3/Makefile b/ssl-admin-1.0.3/Makefile new file mode 100644 index 0000000..542f8b2 --- /dev/null +++ b/ssl-admin-1.0.3/Makefile @@ -0,0 +1,20 @@ +# ssl-admin Makefile +# $Id$ + +ETCDIR?=/usr/local/etc +BINDIR?=/usr/local/bin +MANDIR?=/usr/local/man + +all: + +install: + + [ -e "${ETCDIR}/ssl-admin" ] || mkdir -p ${ETCDIR}/ssl-admin + sed s+~~~ETCDIR~~~+${ETCDIR}+g man1/ssl-admin.1 > ${MANDIR}/man1/ssl-admin.1 + sed s+~~~ETCDIR~~~+${ETCDIR}+g man5/ssl-admin.conf.5 > ${MANDIR}/man5/ssl-admin.conf.5 + install -c -g wheel -o root -m 0660 -S -v ssl-admin.conf ${ETCDIR}/ssl-admin/ssl-admin.conf.default + install -c -g wheel -o root -m 0660 -S -v openssl.conf ${ETCDIR}/ssl-admin/openssl.conf.default + [ -e "${ETCDIR}/ssl-admin/openssl.conf" ] || cp ${ETCDIR}/ssl-admin/openssl.conf.default ${ETCDIR}/ssl-admin/openssl.conf + sed -i "" "s+~~~ETCDIR~~~+${ETCDIR}+g" ssl-admin + install -c -g wheel -o root -m 0755 -S -v ssl-admin ${BINDIR}/ssl-admin + chmod 0444 ${ETCDIR}/ssl-admin/*.conf.default diff --git a/ssl-admin-1.0.3/man1/ssl-admin.1 b/ssl-admin-1.0.3/man1/ssl-admin.1 new file mode 100644 index 0000000..8eee778 --- /dev/null +++ b/ssl-admin-1.0.3/man1/ssl-admin.1 @@ -0,0 +1,74 @@ +.TH ssl\-admin 1 +.SH NAME +ssl-admin \- OpenSSL Certificate Manager +.SH SYNOPSIS +.T +.B ssl-admin + +.SH DESCRIPTION +\fBssl-admin\fR is a menu-driven tool designed to simplify the management +and distriibution of SSL certificates. ssl-admin was originally written to +manage SSL certificates for use with OpenVPN. This functionality has not +been removed. + +.SH First Run +The first time ssl-admin is run, you will be prompted for your existing +CA Root certificate and key file. If you do not have one, a new Root +CA will be created for you. \fBYou must have set the run-time variables +in ssl-admin.conf first.\fR + +During the initial run, a complete directory structure will be created in +\fB~~~ETCDIR~~~/ssl-admin\fR. + +.SH DIRECTORIES +There are a number of directories within ~~~ETCDIR~~~/ssl-admin/ which +contain the working and datafiles. +.TP +ACTIVE (~~~ETCDIR~~~/ssl-admin/active) +The active directory contains certificates that have not been revoked. The +only keys that are \fBREQUIRED\fR to be present are ca.crt and ca.key. + +.TP +CSR (~~~ETCDIR~~~/ssl-admin/csr) +The csr directory contains certificate signing requests and keys for those +keys which have been created using ssl-admin. If you need to sign a +certificate signing request generated elsewhere, place the .csr here. The +key files are not required to be present. + +.TP +PACKAGES (~~~ETCDIR~~~/ssl-admin/packages) +The packages directory contains any zipped packages you've built with ssl-admin. +Packages are generally used to distribute signed certificates to end users. + +.TP +PROG (~~~ETCDIR~~~/ssl-admin/prog) +The prog directory contains all the data files used by ssl-admin. +\fBDO NOT EDIT OR MODIFY THE FILES IN THIS DIRECTORY\fR unless you know exactly +what you are doing. If you are running OpenVPN, you may point your OpenVPN +crl-verify config option to ~~~ETCDIR~~~/ssl-admin/prog/crl.pem. + +.TP +REVOKED (~~~ETCDIR~~~/ssl-admin/revoked) +The revoked directory contains certificates and keys for those certificates +that have been revoked within ssl-admin. + +.SH NOTES +This man page needs to be completed. +$Id: ssl-admin.1 28 2008-12-07 16:58:37Z ecrist $ + +.SH BUGS +.TP +OpenVPN client.ovpn error +There is an error when making a new certificate that client.ovpn doesn't exist. + +.SH FILES +.T4 +~~~ETCDIR~~~/ssl-admin/ssl-admin.conf + +.SH "SEE ALSO" +ssl-admin.conf(5), openssl(1) + +.SH AUTHOR +Eric Crist + + diff --git a/ssl-admin-1.0.3/man5/ssl-admin.conf.5 b/ssl-admin-1.0.3/man5/ssl-admin.conf.5 new file mode 100644 index 0000000..3ac67b3 --- /dev/null +++ b/ssl-admin-1.0.3/man5/ssl-admin.conf.5 @@ -0,0 +1,51 @@ +.TH ssl\-admin.conf 5 +.SH NAME +ssl-admin.conf \- configuration file for ssl-admin + +.SH DESCRIPTION +The file \fB ssl-admin.conf\fR contains settings that control site- +specific settings for your default key size, length, and location +information. + +This configuration file is essentially a called perl script with the +needed variables assigned. + +.SH KEY INFORMATION +.TP +.B KEY_SIZE (num) +The length, in bits, for the default key size. A minimum of 1024 is +recommended. This option can be changed at run time. +.TP +.B KEY_DAYS (num) +The length, in days, for the default period a certificate is valid for. +365 is recommended for web, mail, etc, servers. 3650 is recommended for +VPN certificates. This option can be changed at run time. +.TP +.B KEY_CN (str) +This is the default Common Name for a certificate. Leaving the value +empty is recommended. This option is always asked for at run time. +.TP +.B KEY_CRL_LOC (str) +The publicly available location for your CRL (Certificate Revokation +List). At this time, ssl-admin does not have the ability of sending the +CRL to another system. This value simply allows it to be set within +each certificate. +This string \fBmust\fR start with "URI:", and be followed with a standard +URL. For example, "URI:http://www.example.com/crl.pem" + +.SH NOTES +This man page needs to be completed. + +$Id: ssl-admin.conf.5 21 2008-12-04 13:10:04Z krzee $ +.SH BUGS +No know bugs at this time. + +.SH FILES +.T4 +~~~ETCDIR~~~/ssl-admin/ssl-admin.conf + +.SH "SEE ALSO" +ssl-admin(1), openssl(1) + +.SH AUTHOR +Eric Crist diff --git a/ssl-admin-1.0.3/openssl.conf b/ssl-admin-1.0.3/openssl.conf new file mode 100644 index 0000000..4eeca20 --- /dev/null +++ b/ssl-admin-1.0.3/openssl.conf @@ -0,0 +1,91 @@ +# OpenSSL Configuration File for ssl-admin + +dir = $ENV::KEY_DIR + +[ca] +default_ca = CA_default + +[CA_default] +serial = $dir/prog/serial +database = $dir/prog/index.txt +new_certs_dir = $dir/active +certificate = $dir/active/ca.crt +private_key = $dir/active/ca.key +default_days = $ENV::KEY_DAYS +default_crl_days = 30 +default_md = sha1 +preserve = no +email_in_dn = yes +nameopt = default_ca +certopt = default_ca +policy = policy_match + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_new_ca] +countryName = supplied +stateOrProvinceName = supplied +organizationName = supplied +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + + +[ req ] +default_bits = $ENV::KEY_SIZE +default_keyfile = privkey.pem +default_md = md5 +string_mask = nombstr +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[ req_distinguished_name ] +# Prompts +countryName = Country Name (2 letter code) +countryName_min = 2 +countryName_max = 2 +stateOrProvinceName = State or Province Name (full name) +localityName = Locality Name (eg, city) +0.organizationName = Organization Name (eg, company) +organizationalUnitName = Organizational Unit Name (eg, section) +commonName = Common Name (web address or username) +commonName_max = 64 +emailAddress = Email Address +emailAddress_max = 40 + +# Default Variables (environment variables set from ssl-admin.pl script. +countryName_default = $ENV::KEY_COUNTRY +commonName_default = $ENV::KEY_CN +emailAddress_default = $ENV::KEY_EMAIL +0.organizationName_default = $ENV::KEY_ORG +stateOrProvinceName_default = $ENV::KEY_PROVINCE +localityName_default = $ENV::KEY_CITY + +[ server ] + +# JY ADDED -- Make a cert with nsCertType set to "server" +basicConstraints=CA:FALSE +nsCertType = server +nsComment = "ssl-admin (OpenSSL) Generated Server Certificate" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +extendedKeyUsage = serverAuth +keyUsage = digitalSignature, keyEncipherment + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = keyAgreement, nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth +crlDistributionPoints = $ENV::KEY_CRL_LOC + +[ v3_ca ] +basicConstraints = CA:TRUE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +crlDistributionPoints = $ENV::KEY_CRL_LOC diff --git a/ssl-admin-1.0.3/ssl-admin b/ssl-admin-1.0.3/ssl-admin new file mode 100755 index 0000000..71302b6 --- /dev/null +++ b/ssl-admin-1.0.3/ssl-admin @@ -0,0 +1,568 @@ +#!/usr/bin/perl +# +# Copyright (c) 2007, Eric F Crist +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# VERSION: 1.0 +# $Id: ssl-admin 48 2009-04-08 02:21:23Z ecrist $ + +use strict; +use warnings; + + +## Read config file and die if there's a syntax error. +my $config_file = "~~~ETCDIR~~~/ssl-admin/ssl-admin.conf"; +die "$config_file doesn't exits. Did you copy the sample from $config_file.sample?" unless (-e $config_file); +my $result = do $config_file; +die "Syntax error in $config_file\n\n" unless ($result); + +$ENV{'KEY_DIR'} = "~~~ETCDIR~~~/ssl-admin"; + + +### Program-specific settings here ### +my $program_name = "ssl-admin"; +my $menu_item = ""; +my $script_dir; +my $working_dir = $ENV{'KEY_DIR'}; +my $key_days = $ENV{'KEY_DAYS'}; +my $crl = "$working_dir/prog/crl.pem"; +my $key_config = "$working_dir/openssl.conf"; +my $cn= ""; +my $cn_literal=""; +my $user; +my $cn_o = 0; #Override existing value in $cn +my $zip_cmd; +my $curr_serial; +my $new_runtime = 0; +my $intermediate = "NO"; +my $key_size = $ENV{'KEY_SIZE'}; +my $serial; + +# Gather project information and run-time variables + +sub update_serial { + chomp($curr_serial = `cat $working_dir/prog/serial`); +} + +sub common_name { + my $cn_new; + if (($cn eq "") or ($cn_o == 1)){ + do { + print "Please enter certifcate owner's name or ID.\nUsual format is first initial-last name (jdoe) or\n"; + print "hostname of server which will use this certificate.\nAll lower case, numbers OK.\nOwner [$cn]: "; + chomp($cn_new = <>); + } until $cn_new =~ m/^[\w\s-]+$/ or $cn =~ m/^[\w\s-]+$/; + if (($cn_new ne $cn) and ($cn_new ne "")){ + $cn_literal = $cn_new; + ($cn = $cn_literal) =~ s/\s/_/g; + print "\n\nFile names will use $cn.\n"; + } + } else { + print "Owner name already configured as $cn, using exiting value.\n"; + } + $ENV{'KEY_CN'} = "$cn_literal"; + $cn_o = 0; +} + +sub project_info { + my $key_days_new; + my $intermediate_new; + if ($new_runtime == 1){ + print "Number of days key is valid for [$key_days]: "; + chomp($key_days_new = <>); + if (($key_days_new ne "$ENV{'KEY_DAYS'}") and ($key_days_new ne "")){ + $ENV{'KEY_DAYS'} = $key_days_new; + $key_days = $key_days_new; + } + do { + print "Key size in bits (up to 4096) [$key_size]: "; + chomp($key_size = <>); + } until ($key_size =~ m/^$/) or ($key_size =~ m/^[0-9]+$/ and ($key_size lt 4097)); + print "######################################################\n"; + print "#################### CAUTION!!! ####################\n"; + print "######################################################\n"; + do { + print "\nTurn on Intermediate CA certificate signing? (y/n): "; + chomp($intermediate_new = <>); + } until $intermediate_new =~ m/^[yn]+$/; + if ($intermediate_new eq "y"){ + $intermediate = "YES"; + print "\nYou have enabled intermediate certificate signing! This means\n"; + print "any certicates you sign this session will be authorized to sign\n"; + print "new certificates which will be trusted by you and anyone who\n"; + print "trusts you. This option is generally not going to be used.\n"; + } + elsif ($intermediate_new eq "n"){ + $intermediate = "NO"; + print "Intermediate CA certificate signing is disabled."; + } + } +} + +# Things are kinda crazy, so we're going to functionalize some things. + +sub create_csr { + my $yn = ""; + if ( -e "$working_dir/active/$cn.crt"){ + print "$cn already has a key. Creating another one will overwrite the existing key.\n"; + do { + print "$cn already has an active key. Do you want to overwrite? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ + $cn_o = 1; + project_info(); + } + } + do { + print "Would you like to password protect the private key (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl req -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } elsif ($yn eq "n") { + system("cd $working_dir && openssl req -nodes -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } +} + +sub sign_csr { + update_serial(); + print "===> Serial Number = $curr_serial\n"; + + if ($intermediate eq "NO"){ + print "=========> Signing request for $cn\n"; + `cd $working_dir && openssl ca -config $key_config -days $key_days -out $cn.crt -in $cn.csr -batch`; + } elsif ($intermediate eq "YES"){ + print "=========> Signing new Intermediate CA request for $cn\n"; + `cd $working_dir && openssl ca -config $key_config -policy policy_new_ca -out $cn.crt -extensions v3_ca -infiles $cn.csr -batch`; + } + if ($? != 0){ die "There was an error during openssl execution. Please look for error messages above."; } + print "=========> Moving certificates and keys to $working_dir/active for production.\n"; + system("mv $working_dir/$cn.crt $working_dir/active/"); + system("cp $working_dir/$cn.key $working_dir/csr/"); + system("mv $working_dir/$cn.key $working_dir/active/"); + system("mv $working_dir/active/$curr_serial.pem $working_dir/active/$cn.pem"); + my $yn = ""; + do { + print "Can I move signing request ($cn.csr) to the csr directory for archiving? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + `mv $working_dir/$cn.csr $working_dir/csr/`; + print "===> $cn.csr moved.\n" + } else { print "You will need to move $working_dir/$cn.csr to $working_dir/$cn.csr manually!"; } +} +sub new_ca { + my $yn; + common_name(); + print "\n\n===> Creating private key with $key_size bits and generating request.\n"; + do { + print "Do you want to password protect your CA private key? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl genrsa -des3 -out $cn.key $key_size"); + } else { + system("cd $working_dir && openssl genrsa -out $cn.key $key_size"); + } + print "===> Self-Signing request.\n"; + system("openssl req -new -x509 -extensions v3_ca -key $working_dir/$cn.key -out $working_dir/$cn.crt -days $key_days -config $key_config -batch"); + if ($? != 0){ die "OpenSSL exited with errors. Please read above and address the problems indicated."; } + print "===> Moving certficate and key to appropriate directory.\n"; + system("mv $working_dir/$cn.key $working_dir/active/ca.key"); + system("mv $working_dir/$cn.crt $working_dir/active/ca.crt"); +# print "===> Generating initial (empty) CRL: "; +# if (system("cd $working_dir/active && openssl ca -gencrl -config $key_config -out $crl")){ +# print " DONE\n"; +# } else { +# print " ERROR\n"; +# } + +} + +sub create_server { + my $yn = ""; + if ( -e "$working_dir/active/$cn.crt"){ + print "$cn already has a key. Creating another one will overwrite the existing key.\n"; + do { + print "$cn already has an active key. Do you want to overwrite? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n") { + $cn_o = 1; + project_info(); + } + } + do { + print "Would you like to password protect the private key (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y") { + system("cd $working_dir && openssl req -extensions server -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } elsif ($yn eq "n"){ + system("cd $working_dir && openssl req -extensions server -nodes -new -keyout $cn.key -out $cn.csr -config $key_config -batch"); + } +} +sub sign_server { + update_serial(); + print "===> Serial Number = $curr_serial\n"; + `cd $working_dir && openssl ca -config $key_config -extensions server -days $key_days -out $cn.crt -in $cn.csr -batch`; + if ($? != 0){ die "There was an error during openssl execution. Please look for error messages above."; } + print "=========> Moving certificates and keys to $working_dir/active for production.\n"; + system("mv $working_dir/$cn.crt $working_dir/active/"); + system("cp $working_dir/$cn.key $working_dir/csr/"); + system("mv $working_dir/$cn.key $working_dir/active/"); + system("mv $working_dir/active/$curr_serial.pem $working_dir/active/$cn.pem"); + my $yn = ""; + do { + print "Can I move signing request ($cn.csr) to the csr directory for archiving? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + `mv $working_dir/$cn.csr $working_dir/csr/`; + print "===> $cn.csr moved.\n" + } else { print "You will need to move $working_dir/$cn.csr to $working_dir/$cn.csr manually!\n"; + print "Remember that if you do not keep your server .csr you will need to build a new CA\n"; + print "if your server cert gets comprimised.\n"; + } +} + +sub gen_dh { + # This function generates the Diffie Hellman parameters + # openssl dhparam -out ./dh1024.pem 1024 + system("openssl dhparam -out $working_dir/dh$key_size.pem $key_size"); + print "Your Diffie Hellman parameters have been created."; +} + +# System Menu + +sub main_menu { + update_serial(); + print "\n\n=====================================================\n"; + print '# SSL-ADMIN #'; + print "\n=====================================================\n"; + print "Please enter the menu option from the following list:\n"; + print "1) Update run-time options:\n"; + print " Common Name: $cn_literal\n"; + print " Key Duration (days): $key_days\n"; + print " Current Serial #: $curr_serial\n"; + print " Key Size (bits): $key_size\n"; + print " Intermediate CA Signing: $intermediate\n"; + print "2) Create new Certificate Request\n"; + print "3) Sign a Certificate Request\n"; + print "4) Perform a one-step request/sign\n"; + print "5) Revoke a Certificate\n"; + print "6) Renew/Re-sign a past Certificate Request\n"; + print "7) View current Certificate Revokation List\n"; + print "8) View index information for certificate.\n"; + print "z) Zip files for end user.\n"; + print "dh) Generate Diffie Hellman parameters.\n"; + print "CA) Create new Self-Signed CA certificate.\n"; + print "S) Create new Signed Server certificate.\n"; + print "q) Quit $program_name\n\n"; + print "Menu Item: "; + chomp($menu_item = <>); + menu_handler(); +} + +# Menu Handler + +sub menu_handler { + if ($menu_item eq "1"){ + $cn_o = 1; + $new_runtime = 1; + common_name(); + project_info(); + print "Run-time options reconfigured.\n\n\n"; + $cn_o = 0; + $new_runtime = 0; + main_menu(); + +### CREATE CERT MENU + + } elsif ($menu_item eq "2"){ + common_name(); + create_csr(); + +### SIGN CERT MENU + + } elsif ($menu_item eq "3"){ + common_name(); + sign_csr(); + +### CREATE/SIGN MENU + + } elsif ($menu_item eq "4"){ + common_name(); + create_csr(); + sign_csr(); + +### REVOKE MENU + + } elsif ($menu_item eq "5"){ + $cn_o = 1; + common_name(); + my $yn = ""; + print "=========> Revoking Certificate for $cn\n"; + do { + print "We're going to REVOKE an SSL certificate. Are you sure? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ main_menu(); } + my $revoke = `openssl x509 -noout -text -in $working_dir/active/$cn.crt | grep Serial`; + $revoke =~ m/Serial Number: ([A-F0-9]+)/; + $revoke = $1 or warn("Certificate doesn't seem valid."); + print "\n \$revoke = $revoke\n"; + `cd $working_dir/active && openssl ca -revoke $working_dir/active/$cn.crt -config $key_config -batch`; + print "=========> Generating new Certificate Revokation List $crl\n"; + `cd $working_dir/active && openssl ca -gencrl -out $crl -config $key_config`; + print "=========> Verifying Revokation: "; + my $check_revoke = `openssl crl -noout -text -in $crl | grep Serial`; + my $check_status = 0; + while ($check_revoke =~ m/Serial Number: ([A-F0-9]+)/g){ + if (hex $revoke == hex $1){ + $check_status = 1; + } + } + if ($check_status){ + print "SUCCESS!\n"; + } else { + print "ERRORS\n"; + } + print "=========> Moving $cn\'s files to $working_dir/revoked\n"; + `mv $working_dir/active/$cn.* $working_dir/revoked/`; + print "=========> Destroying previous packages built for $cn: "; + `rm -rf $working_dir/packages/$cn.*`; + print "DONE\n"; + print "=========> CSR for all users is in $working_dir/csr\n"; + print "===============> Changing file name for $cn\'s request to *.revoked"; + `mv $working_dir/csr/$cn.csr $working_dir/csr/$cn.csr.revoked`; + sleep 3; + +### RE-SIGN/RENEW MENU + + } elsif ($menu_item eq "6"){ + $cn_o = 1; + common_name(); + my $yn; + if ( -e "$working_dir/csr/$cn.csr"){ + print "======> Moving archived request to working directory."; + system("mv $working_dir/csr/$cn.csr $working_dir"); + system("mv $working_dir/csr/$cn.key $working_dir"); + sign_csr(); + } elsif ( -e "$working_dir/csr/$cn.csr.revoked"){ + print "\n\nThe certificate you're trying to renew has been revoked!\n"; + do { + print "Are you sure you want to re-sign/renew this certficate? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n") { main_menu(); } + else { + system("mv $working_dir/csr/$cn.csr.revoked $working_dir/$cn.csr"); + system("mv $working_dir/csr/$cn.key $working_dir/$cn.key"); + sign_csr(); + } + } else { + print "There is no request in the archive for $cn.\n"; + } + sleep 2; + +### View Current CRL MENU + + } elsif ($menu_item eq "7"){ + if (! -e $crl){ + system("cd $working_dir/active && openssl ca -gencrl -config $key_config -out $crl -batch"); + } + system("openssl crl -text -noout -in $crl"); + sleep 3; + + +### Read INDEX Menu + + } elsif ($menu_item eq "8"){ + common_name(); + system("more $working_dir/prog/index.txt | grep $cn"); + sleep 3; + +### Create ZIP FILE Menu + + } elsif ($menu_item eq "z"){ + my $yn; + common_name(); + print "=========> Creating .zip file for $cn in $working_dir/packages\n"; + print "=================> Moving $cn.crt\n"; + `cp $working_dir/active/$cn.crt $working_dir/packages/client.crt`; + print "=================> Moving $cn.key\n"; + `cp $working_dir/active/$cn.key $working_dir/packages/client.key`; + do { + print "Is this certificate for an OpenVPN client install? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "n"){ + $zip_cmd = "cd $working_dir/packages/ && zip $cn.zip client.crt client.key ca.crt"; + } else { + $zip_cmd = "cd $working_dir/packages/ && zip $cn.zip client.crt client.key ca.crt client.ovpn"; + } + print "=================> Zipping File\n"; + system($zip_cmd); + print "=================> Cleaning up files: "; + `rm $working_dir/packages/client.crt`; + print "client.crt, "; + `rm $working_dir/packages/client.key`; + print "client.key.\n"; + print "\nYou may distribute $working_dir/packages/$cn.zip to the end user.\n"; + sleep 3; + + } elsif ($menu_item eq "dh"){ + gen_dh(); +### CREATE NEW SELF-SIGNED CA CERTIFICATE + } elsif ($menu_item eq "CA"){ + new_ca(); +### CREATE NEW SIGNED SERVER CERTIFICATE + } elsif ($menu_item eq "S"){ + common_name(); + create_server(); + sign_server(); + } elsif ($menu_item eq "q"){ + exit 0; + } +} +# Software header/introduction +# +if ( ! -e "$working_dir"){ + print "$working_dir doesn't exist. Is the variable set correctly?\n"; + exit 1; +} +print "This program will walk you through requesting, signing,\norganizing and revoking SSL certificates.\n\n"; +if ($> != 0){ + die "Sorry, but I need to be run as the root user.\n\n"; +} + +if ( ! -e "$working_dir/prog/install"){ + + if ( ! -e "$working_dir/active"){ + my $yn; + print "Looks like this is a new install, installing...\n"; + do { + print "You will first need to edit the ~~~ETCDIR~~~/ssl-admin/ssl-admin.conf\n"; + print "default variables. Have you done this? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn ne "y") { die "Please edit ~~~ETCDIR~~~/ssl-admin/ssl-admin.conf and run me again." } + mkdir "$working_dir/active", 0750; + mkdir "$working_dir/revoked", 0750; + mkdir "$working_dir/csr", 0750; + mkdir "$working_dir/packages", 0750; + mkdir "$working_dir/prog", 0750; + } + my $yn; + do { + print "I need the CA credentials. Would you like to create a new CA key and\n"; + print "certificate now? (y/n): "; + chomp($yn = <>); + } until $yn =~ m/^[yn]$/; + if ($yn eq "y"){ + new_ca(); + if ( ! -e "$working_dir/index.txt"){ + open(FILE, ">$working_dir/prog/index.txt"); + close(FILE); + open(FILE, ">$working_dir/prog/index.txt.attr"); + print FILE "unique_subject = no"; + close(FILE); + open (FILE, ">$working_dir/prog/serial"); + print FILE "01"; + close(FILE); + } + } + else { + if ( ! -e "$working_dir/active/ca.crt"){ + my $ca_cert; + print "I need your ca.crt file. Please enter path and filename so I can have a copy: \n"; + print "Location: "; + chomp($ca_cert = <>); + if (-e $ca_cert){ + system("more $ca_cert | grep -q \"BEGIN CERTIFICATE\""); + if ($? != 0){ die "$ca_cert doesn\'t look like a certificate." } + system("more $ca_cert | grep -q \"CA:TRUE\""); +# if ($? != 0){die "$ca_cert looks valid, but isn't authorized to sign other certificates." } + system("cp $ca_cert $working_dir/active/ca.crt"); + system("cp $ca_cert $working_dir/packages/ca.crt"); + } else { die "File $ca_cert doesn\'t exist. Please locate the file and try again.\n"; } + } + if ( ! -e "$working_dir/active/ca.key"){ + my $ca_key; + print "I need your ca.key file. Please enter path and filename so I can have a copy: \n"; + print "Location: "; + chomp($ca_key = <>); + if (-e $ca_key){ + system("more $ca_key | grep -q \"BEGIN RSA PRIVATE KEY\""); + if ($? != 0 ){ die "$ca_key doesn\'t look like a private key." } + system("cp $ca_key $working_dir/active/ca.key"); + } else { die "File $ca_key doesn\'t exist. Please locate the file and try again.\n"; } + } + print "If you have an existing index.txt or index.txt.attr, you need to manually\n"; + print "place them in the $working_dir/prog/ directory.\n"; + do { + print "What serial number shall I start with? [01]: "; + chomp($serial = <>); + } until $serial =~ m/^[A-F0-9]+$/; + open (FILE, ">$working_dir/prog/serial"); + print FILE "$serial"; + close(FILE); + } + if ( ! -e "$working_dir/index.txt"){ + open(FILE, ">$working_dir/prog/index.txt"); + close(FILE); + open(FILE, ">$working_dir/prog/index.txt.attr"); + print FILE "unique_subject = no"; + close(FILE); + open (FILE, ">$working_dir/prog/serial"); + print FILE "01"; + close(FILE); + } + system("echo `date` > $working_dir/prog/install"); +} +if (! -e $crl){ + print "Creating initial CRL..."; + if (system("cd $working_dir/active && openssl ca -gencrl -config $key_config -out $crl")){ + print " DONE"; + } else { + print " FAIL"; + } +} +my $install_date = `cat $working_dir/prog/install`; +print "ssl-admin installed $install_date"; +update_serial(); + +# Make sure packaged ca.crt is up to date. +system("cp $working_dir/active/ca.crt $working_dir/packages/"); +if ( ! -e "$working_dir/packages/client.ovpn"){ + print "I can't find your OpenVPN client config. Please copy your config to\n$working_dir/packages/client.ovpn"; +} +while ($menu_item ne "q"){ + main_menu(); +} diff --git a/ssl-admin-1.0.3/ssl-admin.conf b/ssl-admin-1.0.3/ssl-admin.conf new file mode 100644 index 0000000..f975a67 --- /dev/null +++ b/ssl-admin-1.0.3/ssl-admin.conf @@ -0,0 +1,21 @@ +## Set default values here. +# +# The following values can be changed without affecting +# your CA key. + +$ENV{'KEY_SIZE'} = "1024"; +$ENV{'KEY_DAYS'} = "3650"; +$ENV{'KEY_CN'} = ""; +$ENV{'KEY_CRL_LOC'} = "URI:http://CRL_URI"; + + +## WARNING!!! ## +# +# Changing the following values has vast consequences. +# These values must match what's in your root CA certificate. + +$ENV{'KEY_COUNTRY'} = "COUNTRY"; +$ENV{'KEY_PROVINCE'} = "STATE/PROVINCE"; +$ENV{'KEY_CITY'} = "CITY"; +$ENV{'KEY_ORG'} = "ORGANIZATION"; +$ENV{'KEY_EMAIL'} = 'EMAIL_ADDRESS'; diff --git a/svn-commit.tmp b/svn-commit.tmp new file mode 100644 index 0000000..0d20ae4 --- /dev/null +++ b/svn-commit.tmp @@ -0,0 +1,7 @@ +* fix build script +* fix overly greedy globbing on revokation +* use File::Copy instead of unpathed system commands +--This line, and those below, will be ignored-- + +M perl/build.freebsd.sh +M perl/ssl-admin