As part of my DIY mail server project, the other day I put a POP3 server on that box – solid-pop3d if you want to know –, and since that server doesn't have SSL built in, I configured stunnel to provide that, re-using a certificate I get for mail.tfiu.de's https server from letsencrypt. Trivial configuration:
[spop3d] accept=995 connect=110 cert=/etc/stunnel/mail.pem
And bang!, an error message from stunnel:
[ ] Loading private key from file: /etc/stunnel/mail.pem [!] error queue: 140B0009: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib [!] SSL_CTX_use_PrivateKey_file: 909006C: error:0909006C:PEM routines:get_name:no start line
One of my least favourite pastimes is figuring out cryptic OpenSSL error messages, and so I immediately fed this to $SEARCH_ENGINE. The responses were, let's say, lacking rigour, and so I thought I might use this blog to give future message googlers an explanation of what the problem was in my case.
What OpenSSL was saying here simply was: there's no private key in the PEM.
Where would the fun be if OpenSSL had said that itself?
In case this doesn't immediately tell you how to fix things: “PEM files” in today's computing [1] are typically bundles of a “key” (that's the pair of public and secret key in sensible language), a “certificate” (that's a signed public key in sensible language), and possibly intermediate certificates that user agents may need to figure out that the signature on the certificate is any good, based on what certificate authorities they trust.
All these things almost always come in base64 encoded ASCII these days (that's the actual meaning of “PEM“), which is nice because you can create your “PEM file” with cat if you've got the other parts. For instance, in my dealings with letsencrypt, I'm creating the key using:
openssl genrsa 4096 > $SERVERNAME.key
Then I build a certificiate signing request in some way that's immaterial here, and finally call the great acme-tiny something like:
acme-tiny --account-key ./account.key --csr ./"$SERVERNAME".csr \ --acme-dir /var/www/acme-challenge\ > ./"$SERVERNAME".crt
Letsencrypt also hands out the the intermediate certificates at a well-known URI, so I pull that, too:
curl https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem \ > intermediate.pem
With that, all I have to do to make the “PEM file” is:
cat $SERVERNAME.crt intermediate.pem > $SERVERNAME.pem # not
That was basically what I had in my certificate updating script, and that is what caused the error in my case. Spot it? Right, I failed to cat the key file in. I should have written:
cat $SERVERNAME.key $SERVERNAME.crt intermediate.pem > $SERVERNAME.pem
So – if you're seeing this error message, while I can't say why your key pair is missing in the PEM, I'd strongly suspect it is. Diagnosis: look for
-----BEGIN RSA PRIVATE KEY-----
somewhere in the file (and make sure all the dashes are present if you see something that looks like that and you're still seeing the odd OpenSSL message).
[1] | I've had to look that up myself: PEM actually has nothing to do with all kinds of cryptographic material cat-ed together into one file. Rather, it stands for Privacy-Enhanced Mail, something the IETF tried to establish in the early 1990ies where today (regrettably) S/MIME sits and what we could all mercifully forget if people finally just adopted PGP already. RFC 1421 – where a good deal of PEM is defined – was published in 1993 and still talks about BITNET! Oh wow. While this sort of PEM is dead, it did pioneer the ASCII-armoring of X.509 material. Of course, ASCII-armoring as such had been around for many years at that time – let me just mention uuencode, the cornerstone of software distribution on Usenet –, and PGP had even used base64 for crypto stuff, but all these (sensibly) steered clear of X.509. And ASCII-armored X.509 is PEM's legacy, as acknowledged by RFC 7468 (published in 2015, more than 20 years after the original PEM). Of course, RFC 7468 doesn't mention the .pem extension, let alone anything about the practice of assembling multiple kinds of cryptographic material in files with that extension. |
Zitiert in: A Mail Server on Debian