Unable to install an ECC cert: "Private key is password-protected, but either none was entered or the password was incorrect"

SYSTEM INFORMATION
OS type and version RHEL 9.1
Webmin version 2.013
Virtualmin version 7.5
Related packages openssl-3.0.1

This is a new RHEL 9.1 system on Azure. I have acme.sh installed to manage Lets Encrypt (LE) certs. When trying to install an acme.sh generated private key and cert issued by LE, Virtualmin throws this error:

Failed to install certificate : Private key is password-protected, but either none was entered or the password was incorrect

Looking into the details of the cert and key, sometime around mid-December LE changed from RSA to EC certs, whether issuing a new cert or renewing one. This is the first time I have tried to install a cert with Virtualmin after the change to EC certs. I don’t know if that is related, but I speculate it may be.

I tried telling Virtualmin that it has a passphrase and leaving it blank, and that threw the same error.

I have used the openssl procedure to remove a passphrase, but the private key does not change when doing so. Researching this, I have found that EC certs apparently do not have a passphrase.

When I directly edit httpd.conf and add the cert, key, and CA file, apache accepts it without error and serves the site in secure mode. This verifies that the key does not have a passphrase.

I have long run CentOS up to 7, several Rocky 8, and one RHEL 8 system, and I’ve not seen this problem before.

Can anyone shed light on this? Thanks!

Why are you doing it that way. Just get VM to install the LE cert.

Thanks for the reply. For historical and other reasons I prefer to directly manage all certs outside of VM.

In any case, what I am doing should work, but it does not.

I used the VM LE panel to issue and install a new cert. VM uses certbot; that worked. The key type is ECDSA (ECC), so it should be functionally equivalent to the acme.sh cert.

I then tried to use VM to manually install the same certbot generated key that VM had previously generated and installed itself, and that failed with the same error. I don’t know if the VM manual installation process assumes it is working with RSA keys.

I just regenerated an RSA key for the same domain, and that installed without problem where the EC key failed.

It appears that there is a bug in VM that fails when manually installing an EC key/cert.

Hello,

I have run into the same issue. I solved the situation by manual replacement of ssl.cert, ssl.key, ssl.ca. Than, to let virtualmin propagate those changes in certificates and let it create files ssl.combined and ssl.everything is necceserry to do following:

In Virtualmin virtual server → server configuration → SSL certificate → CA Certificate select correct CA file and click “Save Certificate” - This will recreate ssl.combined and ssl.everything and replace your actually used certificate with the new one.

Regards,
Lukinno

Interesting approach, I had not thought to fool vmin by using the same file names. I could see renewal being a problem unless somehow at renewal time you change the filenames to the ssl.* forms.

I have filed a bug report on github. The failure seems consistent enough to warrant that.

The problem is with VM. It doesn’t accept EC key/cert.

What I did to resolve this problem is, to force acme.sh to generate an RSA PRIVATE KEY instead of the EC key which I believe is the default. This cmd acme.sh --issue -d your-domain.com -d *.your-domain.com --dns dns_dgon --keylength 4096 --force tells acme to generate RSA Key.

I assume you already have acme installed on your server. In my case, I use Digital Ocean to host my application so whatever your provider is, just add the –keylength 4096 in your cmd to force acme to generate RSA Key.

I hope this helps.

1 Like

Thanks for the reply, @antiomic. The default in acme.sh does indeed seem to be ecc now; in roughly early January when it apparently switched to ecc it even regenerated new ecc keya for existing certs it was renewing. I saw the --ecc option to acme.sh, with no corresponding --rsa option, but did not read through the script to see that setting the key size would force an rsa key. That is useful information, thanks!

I found the keylength check in _isEccKey(). If a power of 2 >= 1024 <= 8192 the ecc keylength check fails and appartently defaults to rsa; i did not chase it further than that.

Having opened a ticket on this I think I will wait for a vmin fix to be installed from the repo. For the moment I turned off vmin auto-renew on the cert, left the ecc key active, and directly edited httpd.conf to configure the cert. With that when vmin is updated the configuration should be correct wihout having to revisit it ('Ha! you credulous soul!" I think to myself…).

The simple fix in your case would be is to force acme.sh request RSA key rather than ECC for Virtualmin to handle it properly … starting with Webmin 2.020 we will do it by passing --key-type rsa param to certbot command, which will work correctly with Virtualmin Let’s Encrypt automatic certificate requests.

Thanks, @Ilia. Forcing acme.sh to gen an rsa key, as antinomic described, only seems a workaround to avoid some deeper problem in vmin that will not manually install an ecc key. Do you not plan to fix that?

As I mentioned earlier in the thread, I do not use vmin to manage certs; I do that externally to vmin using acme.sh. I can modify that process to force rsa keys, but I would prefer to be able to use the more efficient ecc keys.

@Ilia Using VM to create certificate won’t work for folks like me who need wildcard certificates and can only achieve that using the acme dnsapi. So you will need to point VM to the CA Certificate save it and then update certificate and key before installing.

@fishnet I know the frustration yeah. I spent hours trying to figure a way around the problem. I have submitted a ticket for the bug. It ought to have been fixed and shipped out with the latest VM version at least that’s what a VM rep said but I can’t tell what happened.

Forcing acme.sh to gen an rsa key, as antinomic described, only seems a workaround to avoid some deeper problem in vmin that will not manually install an ecc key. Do you not plan to fix that?

If users going to use ECC keys not issued by Virtualmin, then we would have to support it to provide cross-compatibility.

What are your thoughts @Jamie?

but I would prefer to be able to use the more efficient ecc keys

This is a moot question!

I’m looking into ECC cert support now - we do want to be handle them in Virtualmin.

I wondered if RSA was hard coded somewhere… A grep for ‘openssl rsa’ turned up routines in dkim-lib.pl and feature-ssl.pl. There may be other places that are not so easily identifiable. In feature-ssl.pl, the routines check_passphrase, get_key_size, and check_cert_key_match use that string. In dkim-lib.pl, the routine get_dkim_pubkey uses it; I assume DKIM can use an EC key, but I don’t know that.

As a hack I commented check_passphrase and check_cert_key_match in /usr/libexec/webmin/virtual-server/newkey.cgi, and the cert installed. Either modifying those two routines to distinguish the two, or defining separate routines for RSA and EC, and EC certs should install. Anyway, hopefully this will help focus the work to add installing EC certs.

if( $newkey =~ /BEGIN RSA/ ){
$passok = &check_passphrase($newkey, $in{'pass_def'} ? undef : $in{'pass'});
$passok || &error($text{'newkey_epass'});

# Check that the cert and key match
$certerr = &check_cert_key_match($cert, $newkey);
$certerr && &error(&text('newkey_ematch', $certerr));
}

[I don’t know if you will see this immediately, as my reply went to Ilia. If of use…]

I wondered if RSA was hard coded somewhere… A grep for ‘openssl rsa’ turned up routines in dkim-lib.pl and feature-ssl.pl. There may be other places that are not so easily identifiable. In feature-ssl.pl, the routines check_passphrase, get_key_size, and check_cert_key_match use that string. In dkim-lib.pl, the routine get_dkim_pubkey uses it; I assume DKIM can use an EC key, but I don’t know that.

As a hack I commented check_passphrase and check_cert_key_match in /usr/libexec/webmin/virtual-server/newkey.cgi, and the cert installed. Either modifying those two routines to distinguish the two, or defining separate routines for RSA and EC, and EC certs should install. Anyway, hopefully this will help focus the work to add installing EC certs.

if( $newkey =~ /BEGIN RSA/ ){
$passok = &check_passphrase($newkey, $in{'pass_def'} ? undef : $in{'pass'});
$passok || &error($text{'newkey_epass'});

# Check that the cert and key match
$certerr = &check_cert_key_match($cert, $newkey);
$certerr && &error(&text('newkey_ematch', $certerr));
}

Ok, I’ve committed an update that should fix this, for inclusion in the next Virtualmin release. You can see the patch here:

Cool, thank you!

No problem. We will fix it in the next Virtualmin release.

This patch will also be needed to work with the keys that don’t set explicit type:

Also, the next Virtualmin release will support creation of Elliptic Curve certs within Virtualmin.