From a01d36b17d01f48c38036f51d64e04f627f1414a Mon Sep 17 00:00:00 2001 From: Lukas Schauer Date: Fri, 8 Jan 2016 22:17:59 +0100 Subject: [PATCH] Updated Import existing account key (markdown) --- Import-existing-account-key.md | 32 ----- Import-from-official-letsencrypt-client.md | 136 +++++++++++++++++++++ 2 files changed, 136 insertions(+), 32 deletions(-) delete mode 100644 Import-existing-account-key.md create mode 100644 Import-from-official-letsencrypt-client.md diff --git a/Import-existing-account-key.md b/Import-existing-account-key.md deleted file mode 100644 index 9fed5b9..0000000 --- a/Import-existing-account-key.md +++ /dev/null @@ -1,32 +0,0 @@ -If for any reason you want to import your existing account key from the official letsencrypt client place the following script next to `private_key.json` (should be in a subdirectory under `/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory`) and run it. - -It should return your private key in PEM format, which you can pipe directly into `private_key.pem`. - -```perl -#!/usr/bin/env perl - -use strict; - -use Crypt::OpenSSL::RSA; -use Crypt::OpenSSL::Bignum; -use JSON; -use File::Slurp; -use MIME::Base64; - -my $json_file = "private_key.json"; -my $json_content = read_file($json_file); -$json_content =~ tr/-/+/; -$json_content =~ tr/_/\//; - -my $json = decode_json($json_content); - -my $n = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{n})); -my $e = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{e})); -my $d = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{d})); -my $p = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{p})); -my $q = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{q})); - -my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters($n, $e, $d, $p, $q); - -print($rsa->get_private_key_string()); -``` \ No newline at end of file diff --git a/Import-from-official-letsencrypt-client.md b/Import-from-official-letsencrypt-client.md new file mode 100644 index 0000000..08a84a3 --- /dev/null +++ b/Import-from-official-letsencrypt-client.md @@ -0,0 +1,136 @@ +# Import existing certificates + +If you want to import your existing certificates from the official letsencrypt client place this script next to `letsencrypt.sh` and run it. + +You may want to check if `letsencrypt.sh` is working and all paths are set correctly. +By default it will copy the certificates to the `certs/` directory next to `letsencrypt.sh`. + +## Code + +```bash +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +umask 077 # paranoid umask, we're creating private keys + +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BASEDIR="${SCRIPTDIR}" +LETSENCRYPT="/etc/letsencrypt" + +eval "$("${SCRIPTDIR}/letsencrypt.sh" --env)" + +if [[ ! -e "${LETSENCRYPT}" ]]; then + echo "No existing letsencrypt files found." + exit 1 +fi + +if [[ -e "${BASEDIR}/domains.txt" ]]; then + DOMAINS_TXT="${BASEDIR}/domains.txt" +elif [[ -e "${SCRIPTDIR}/domains.txt" ]]; then + DOMAINS_TXT="${SCRIPTDIR}/domains.txt" +else + echo "You have to create a domains.txt file listing the domains you want certificates for. Have a look at domains.txt.example." + echo "For the purpose of this import script the file can be empty, but it has to exist." + exit 1 +fi + +for certdir in "${LETSENCRYPT}/live/"*; do + domain="$(basename "${certdir}")" + echo "Processing ${domain}" + + # Check if we already have a certificate for the same (main) domain + if [ -e "${BASEDIR}/certs/${domain}" ]; then + echo " + Skipping: Found existing certificate directory, don't want to delete anything." + continue + fi + + # Check if private-key, certificate and fullchain exist + if [[ ! -e "${certdir}/privkey.pem" ]]; then + echo " + Skipping: Private key is missing." + continue + fi + if [[ ! -e "${certdir}/cert.pem" ]]; then + echo " + Skipping: Certificate is missing." + continue + fi + if [[ ! -e "${certdir}/fullchain.pem" ]]; then + echo " + Skipping: Chain is missing." + continue + fi + + # Check if certificate still valid + if ! openssl x509 -checkend 0 -noout -in "${certdir}/cert.pem" >/dev/null 2>&1; then + echo " + Skipping: Certificate is expired." + continue + fi + + # Import certificate + timestamp="$(date +%s)" + + echo " + Adding list of domains to ${DOMAINS_TXT}" + SAN="$(openssl x509 -in "${certdir}/cert.pem" -noout -text | grep -A1 "Subject Alternative Name" | grep "DNS")" + SAN="${SAN//DNS:/}" + SAN="${SAN//, / }" + altnames="${domain}" + for altname in ${SAN}; do + if [[ ! "${altname}" = "${domain}" ]]; then + altnames="${altnames} ${altname}" + fi + done + echo "${altnames}" >> "${DOMAINS_TXT}" + + mkdir -p "${BASEDIR}/certs/${domain}" + + echo " + Importing private key" + cat "${certdir}/privkey.pem" > "${BASEDIR}/certs/${domain}/privkey-${timestamp}.pem" + ln -s "privkey-${timestamp}.pem" "${BASEDIR}/certs/${domain}/privkey.pem" + + echo " + Importing certificate" + cat "${certdir}/cert.pem" > "${BASEDIR}/certs/${domain}/cert-${timestamp}.pem" + ln -s "cert-${timestamp}.pem" "${BASEDIR}/certs/${domain}/cert.pem" + + echo " + Importing chain" + cat "${certdir}/fullchain.pem" > "${BASEDIR}/certs/${domain}/fullchain-${timestamp}.pem" + ln -s "fullchain-${timestamp}.pem" "${BASEDIR}/certs/${domain}/fullchain.pem" +done +``` + +# Import account key + +If for any reason you want to import your existing account key from the official letsencrypt client place this perl script next to `private_key.json` (should be in a subdirectory under `/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory`) and run it. + +It should return your private key in PEM format, which you can pipe directly into `private_key.pem`. + +## Code + +```perl +#!/usr/bin/env perl + +use strict; + +use Crypt::OpenSSL::RSA; +use Crypt::OpenSSL::Bignum; +use JSON; +use File::Slurp; +use MIME::Base64; + +my $json_file = "private_key.json"; +my $json_content = read_file($json_file); +$json_content =~ tr/-/+/; +$json_content =~ tr/_/\//; + +my $json = decode_json($json_content); + +my $n = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{n})); +my $e = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{e})); +my $d = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{d})); +my $p = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{p})); +my $q = Crypt::OpenSSL::Bignum->new_from_bin(decode_base64($json->{q})); + +my $rsa = Crypt::OpenSSL::RSA->new_key_from_parameters($n, $e, $d, $p, $q); + +print($rsa->get_private_key_string()); +``` \ No newline at end of file