[prev in list] [next in list] [prev in thread] [next in thread] 

List:       postfix-users
Subject:    Re: Self-signed TLS certificates
From:       Viktor Dukhovni <postfix-users () dukhovni ! org>
Date:       2018-01-24 16:36:55
Message-ID: 5B212262-ACB0-4DB4-9C05-D577FAF6B737 () dukhovni ! org
[Download RAW message or body]



> On Jan 24, 2018, at 9:21 AM, Danny Horne <danny@trisect.uk> wrote:
> 
>> You can get away with a lot less complexity than the usual OpenSSL CA.
>> See, for example:
>> 
>>   https://raw.githubusercontent.com/openssl/openssl/master/test/certs/mkcert.sh
>> 
>> which creates certificates via "openssl x509 -req" without all the overhead of
>> a stateful CA.  What you'd do differently is password-protect the CA key, and
>> perhaps issue certificates with a somewhat shorter lifetime than the 100 years
>> in that script.
>> 
> I'll stick with what I have for now.  Read up about creating a private
> CA and it went over my head, I also couldn't figure out what input that
> script needed from me

It contains sample code that creates keys, root CAs, intermediate CAs,
CA-issued leaf certificates, and self-signed certificates.  It was used
to create the certificates for the OpenSSL test-suite, and is not as-is
intended to be used for other purposes, though enough knobs are likely
there to make that possible.  Usage examples can be found in:

  https://raw.githubusercontent.com/openssl/openssl/master/test/certs/setup.sh

if anyone wants to take a closer look.  That said, it sounds like the
path forward is for Postfix to add support for 2-level (private CA and
server cert, not just self-signed) certificate chains to the "postfix tls"
command.  That'll have to wait for 3.4, as 3.3 is almost done at this
point, too late to be adding new features, and in any case my cycles are
presently too limited.

-- 
	Viktor.

P.S.  A quick overview of mkcert.sh internals (uses some
bash-specific features):

The key() function generates RSA, DSA, ECDSA, DH or ED25519 keys
(if the output file is not already present):

  key() {
    local key=$1; shift

    local alg=rsa
    if [ -n "$OPENSSL_KEYALG" ]; then
        alg=$OPENSSL_KEYALG
    fi

    local bits=2048
    if [ -n "$OPENSSL_KEYBITS" ]; then
        bits=$OPENSSL_KEYBITS
    fi

    if [ ! -f "${key}.pem" ]; then
        args=(-algorithm "$alg")
        case $alg in
        rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );;
        ec)  args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits")
               args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);;
        dsa)  args=(-paramfile "$bits");;
        ed25519)  ;;
        *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;;
        esac
        stderr_onerror \
            openssl genpkey "${args[@]}" -out "${key}.pem"
    fi
  }

the req() function generates a certificate signing request (CSR) after
generating a key (if not already present) and list of DN components of
the form "name = value":

  req() {
    local key=$1; shift

    key "$key"
    local errs

    stderr_onerror \
        openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \
            -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \
              "$REQMASK" "prompt = no" "distinguished_name = dn"
                      for dn in "$@"; do echo "$dn"; done)
  }

The cert() function reads a CSR from standard input and creates a
signed certificate:

  cert() {
    local cert=$1; shift
    local exts=$1; shift
    stderr_onerror \
        openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \
            -extfile <(printf "%s\n" "$exts") "$@"
  }

The various gen* functions, put these together to create various certificates.
Specifically genroot(), genca() and genee() create root CAs, intermediate CAs
and End-Entity certificates.  This "CA" is stateless, no record is kept of
issued certificates, so OCSP and CRLs are not possible.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic