diff --git a/ssl_mgmt/README b/ssl_mgmt/README
new file mode 100644
index 0000000..72a79c4
--- /dev/null
+++ b/ssl_mgmt/README
@@ -0,0 +1,70 @@
+ssl_mgmt is a helper to manage ssl certificate: creation, renewal and removal.
+So far, only renewal is supported.
+
+ssl_mgmt refers to certificates through the service they are associated with.
+
+*** EXAMPLES ***
+
+To renew the certificate associated to https, the command line is:
+ssl_mgmt renew https
+
+If you want to renew certificates of all services, you should do:
+ssl_mgmt renew all
+
+Note: This suppose that
+ * all services are listed in /root/homemade_certs;
+ * directories have special rights so that newly created certificates
+ automatically get proper rights;
+ * Root CA is already created
+ * openssl.cnf.in is copied at the root of the CA hierarchy
+
+The file system hierarchy assumed is:
+lrwxrwxrwx 1 root root 14 6 janv. 2010 certs -> /etc/ssl/certs
+drws--S---+ 2 root ssl-cert 4096 23 janv. 2011 csr
+-rw------- 1 root ssl-cert 1937 20 févr. 16:38 index.txt
+-rw------- 1 root ssl-cert 20 20 févr. 16:38 index.txt.attr
+drwSr-Sr--+ 2 root ssl-cert 4096 20 févr. 16:38 newcerts
+drwSr-S---+ 2 root ssl-cert 4096 20 févr. 16:38 newkeys
+-rw-r--r-- 1 root ssl-cert 1546 20 févr. 14:24 openssl.cnf.in
+lrwxrwxrwx 1 root root 16 6 janv. 2010 private -> /etc/ssl/private
+-rw------- 1 root ssl-cert 3 20 févr. 16:38 serial
+
+About csr, newcerts and newkeys:
+
+# file: usr/lib/ssl/CA/csr
+# owner: root
+# group: ssl-cert
+# flags: ss-
+user::rwx
+group::---
+other::---
+default:user::rw-
+default:group::r--
+default:other::---
+
+# file: usr/lib/ssl/CA/newcerts
+# owner: root
+# group: ssl-cert
+# flags: ss-
+user::rw-
+group::r--
+other::r--
+default:user::rw-
+default:group::r--
+default:other::r--
+
+# file: usr/lib/ssl/CA/newkeys
+# owner: root
+# group: ssl-cert
+# flags: ss-
+user::rw-
+group::r--
+other::---
+default:user::rw-
+default:group::r--
+default:other::---
+
+To use this script, you have to be root, or to be able to execute
+commands with root privileges through sudo.
+You should install it in a directory within the PATH of the root user,
+such as /usr/local/sbin.
diff --git a/ssl_mgmt/openssl.cnf.in b/ssl_mgmt/openssl.cnf.in
new file mode 100644
index 0000000..3ce6cb8
--- /dev/null
+++ b/ssl_mgmt/openssl.cnf.in
@@ -0,0 +1,62 @@
+#
+# OpenSSL configuration file.
+#
+
+# Establish working directory
+dir = .
+
+[ ca ]
+default_ca = CA_Default
+
+[ CA_Default ]
+serial = $dir/serial
+database = $dir/index.txt
+new_certs_dir = $dir/newcerts
+certificate = $dir/certs/ca-cert.pem
+private_key = $dir/private/ca-key.pem
+default_days = #LENGTH# # Certificates are signed for default_days days
+default_md = md5
+preserve = no
+email_in_dn = no
+nameopt = default_ca
+certopt = default_ca
+policy = policy_match
+copy_extensions = copy
+
+[ policy_match ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+[ req ]
+default_bits = 2048 # Taille des clés
+default_keyfile = newkeys/key.pem # Nom de la clé généré (à spécifier en ligne de commande si différent)
+default_md = md5 # Algorithme de résumé (hash)
+string_mask = nombstr # Caractères authorisés
+prompt = no
+distinguished_name = req_distinguished_name
+req_extensions = v3_req
+# On ne veut ces extensions que pour générer les certificats racines
+# donc on le spécifie sur la ligne de commande
+x509_extensions = v3_ca
+
+[ req_distinguished_name ]
+organizationName = #ORG#
+organizationalUnitName = #ORGUNIT#
+localityName = #LOCALITY#
+stateOrProvinceName = #STATE#
+countryName = #COUNTRY#
+commonName = #COMMONNAME#
+
+[ v3_ca ]
+basicConstraints = CA:TRUE
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+
+[ v3_req ]
+basicConstraints = CA:FALSE
+subjectKeyIdentifier = hash
+subjectAltName = #ALTNAME#
diff --git a/ssl_mgmt/ssl_mgmt b/ssl_mgmt/ssl_mgmt
new file mode 100755
index 0000000..51456f7
--- /dev/null
+++ b/ssl_mgmt/ssl_mgmt
@@ -0,0 +1,253 @@
+#!/bin/sh
+#
+# ssl_mgmt, Copyright © 2012 Thomas Preud'homme
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# email_account is a helper to create e-mail accounts in a configuration
+# using Postfix mail transport agent with vhosts and Cyrus IMAP server,
+# in a Debian environment.
+
+set -u
+
+confFile=openssl.cnf
+
+# Display usage.
+usage ()
+{
+ local - progname
+ progname=$1
+ echo "Usage :"
+ echo
+ echo "$progname renew "
+ echo "$progname -h"
+ echo
+ echo "First form renew the certificate of the given service"
+ echo
+ echo "Second form prints this help."
+}
+
+# @param question Question to ask
+# @return 0 if answer is positive, 1 else
+#
+# Ask question to the user with a default choice set to no.
+ask_user_default_no ()
+{
+ local - answer
+ answer="unset"
+ echo -n "$1 [y/N] "
+ while [ -n "$answer" -a "$answer" != "y" -a "$answer" != "Y" -a "$answer" != "n" -a "$answer" != "N" ]
+ do
+ read answer
+ if [ -z "$answer" -o "$answer" = "n" -o "$answer" = "N" ]
+ then
+ return 1
+ fi
+ if [ "$answer" = "y" -o "$answer" = "Y" ]
+ then
+ break
+ fi
+ echo -n "$2 [y/N] "
+ done
+ return 0
+}
+
+# Test number of argument is correct and their value are correct also.
+test_args ()
+{
+ local - user domain
+ while getopts "h" opt
+ do
+ case $opt in
+ "h")
+ if [ $# -gt 1 ]
+ then
+ echo "Error! Too many arguments." >&2
+ exit 1
+ fi
+ usage $(basename "$0")
+ exit 0 ;;
+ esac
+ done
+ if [ $# -ne 2 -o "$1" != "renew" ]
+ then
+ usage $(basename "$0")
+ exit 0
+ fi
+ eval service="\$$((OPTIND+1))"
+}
+
+# Are we root?
+must_sudo ()
+{
+ uid="$(id -u)"
+ [ ! $uid -eq 0 ]
+ return $?
+}
+
+# This function tries to become root with sudo and execute this script.
+# NB: This function doesn't return.
+try_sudo ()
+{
+ local - ret
+ echo "You aren't root. Trying to use sudo to become root…"
+ sudo $0 "$@" # Try to execute the script with sudo
+ ret=$?
+ if [ ! $ret -eq 0 ]
+ then
+ echo "Error! You must be root or being able to become root by sudo without password to create an email account or add an email alias." >&2
+ fi
+ exit $ret
+}
+
+get_field_from_line ()
+{
+ local - line field result
+
+ line="$1"
+ field="$2"
+ result="${line#*$field=}"
+ echo "${result%%/*}"
+}
+
+get_cert_params ()
+{
+ local - subject issuer dates ext fromDate toDate
+
+ certFile="/etc/ssl/certs/${service}-cert.pem"
+ subject="$(openssl x509 -in "$certFile" -noout -subject)"
+ dates="$(openssl x509 -in "$certFile" -noout -dates)"
+ exclNoExt="-certopt no_header,no_version,no_serial,no_signame"
+ exclNoExt="$exclNoExt,no_validity,no_subject,no_issuer,no_pubkey"
+ exclNoExt="$exclNoExt,no_sigdump,no_aux"
+ altName="$(openssl x509 -in "$certFile" -text $exclNoExt | while read ext
+ do
+ if [ "$ext" = "X509v3 Subject Alternative Name:" ]
+ then
+ read altName
+ echo $altName
+ break
+ fi
+ done)"
+ country=$(get_field_from_line "$subject" "C")
+ state=$(get_field_from_line "$subject" "ST")
+ city=$(get_field_from_line "$subject" "L")
+ organization=$(get_field_from_line "$subject" "O")
+ unit=$(get_field_from_line "$subject" "OU")
+ commonName=$(get_field_from_line "$subject" "CN")
+ fromDate=${dates#*notBefore=}
+ fromDate=${fromDate%notAfter*}
+ fromDate=$(date -d "$fromDate" "+%s")
+ toDate=${dates#*notAfter=}
+ toDate=$(date -d "$toDate" "+%s")
+ days=$(($toDate-$fromDate))
+ days=$(($days/86400))
+}
+
+add_to_replace_cmd ()
+{
+ local - replaceCmd key value
+
+ replaceCmd="$1"
+ key="$2"
+ value="$3"
+ if [ -n "$value" ]
+ then
+ echo "$replaceCmd${replaceCmd:+;}s/$key/$value/"
+ fi
+}
+
+generate_config ()
+{
+ local - replaceCmd cnfTmpFile
+
+ replaceCmd="$(add_to_replace_cmd "${replaceCmd:-}" "#LENGTH#" "${days:-}")"
+ replaceCmd="$(add_to_replace_cmd "$replaceCmd" "#ORG#" "${organization:-}")"
+ replaceCmd="$(add_to_replace_cmd "$replaceCmd" "#ORGUNIT#" "${unit:-}")"
+ replaceCmd="$(add_to_replace_cmd "$replaceCmd" "#LOCALITY#" "${city:-}")"
+ replaceCmd="$(add_to_replace_cmd "$replaceCmd" "#STATE#" "${state:-}")"
+ replaceCmd="$(add_to_replace_cmd "$replaceCmd" "#COUNTRY#" "${country:-}")"
+ replaceCmd="$(add_to_replace_cmd "$replaceCmd" "#COMMONNAME#" "${commonName:-}")"
+ replaceCmd="$(add_to_replace_cmd "$replaceCmd" "#ALTNAME#" "${altName:-}")"
+ sed "$replaceCmd" $confFile.in > $confFile
+ if ask_user_default_no "Do you want to edit the openssl configuration file?"
+ then
+ if [ -z "${EDITOR:-}" ]
+ then
+ $EDITOR $confFile
+ else
+ editor $confFile
+ fi
+ fi
+ cnfTmpFile="$(mktemp --tmpdir=. openssl.cnf.XXXXXXXXXX)"
+ mv $confFile $cnfTmpFile
+ grep -v "#[A-Z]\+#" $cnfTmpFile > $confFile
+ rm $cnfTmpFile
+}
+
+generate_cert ()
+{
+ openssl req -new -nodes -out csr/${service}-req.pem -keyout newkeys/${service}-key.pem -config $confFile
+ openssl req -in csr/${service}-req.pem -text -verify -noout
+ if ! ask_user_default_no "Is the Certificate Signing Request correct?"
+ then
+ return 1
+ fi
+ mv newkeys/${service}-key.pem private
+ openssl ca -batch -out newcerts/${service}-cert.pem -config $confFile -passin file:/root/passwords/root_ca -infiles csr/${service}-req.pem
+ mv newcerts/${service}-cert.pem certs
+ cat private/${service}-key.pem certs/${service}-cert.pem > private/${service}-keycert.pem
+ return 0
+}
+
+main ()
+{
+ local - ret servicesok
+ ret=0
+ test_args "$@"
+ # This test should be useless if rights on this file are corrects
+ # (that is 770 for root:gt owner)
+ if must_sudo
+ then
+ try_sudo "$@"
+ fi
+ cd /usr/lib/ssl/CA/
+ if [ "${service}" = "all" ]
+ then
+ services=""
+ while read service
+ do
+ services="$services $service"
+ done