mirror of
https://git.proxmox.com/git/proxmox-acme
synced 2025-04-28 17:15:59 +00:00
support downloading alternate chains
the current default chains end with an expired root certificate for maximum compatibility with old Android versions. this breaks some other older clients (openssl, gnutls) which don't expect chains to contain any expired certificates, even if they are 'above' the trust anchor. by setting $root, it is possible to specify which root the ACME provided certificate chain should end with, downloading alternate chains as necessary. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> Reviewed-by: Stoiko Ivanov <s.ivanov@proxmox.com> Tested-by: Stoiko Ivanov <s.ivanov@proxmox.com>
This commit is contained in:
parent
b5d46dc4a6
commit
2307c38b59
@ -442,17 +442,50 @@ sub deactivate_authorization {
|
||||
|
||||
# Get certificate
|
||||
# GET-as-POST to order's certificate URL
|
||||
# if $root is specified, attempts to find a matching (alternate) chain
|
||||
# Expects a '200 OK' reply
|
||||
# returns certificate chain in PEM format
|
||||
sub get_certificate {
|
||||
my ($self, $order) = @_;
|
||||
my ($self, $order, $root) = @_;
|
||||
|
||||
$self->fatal("no certificate URL available (yet?)", $order)
|
||||
if !$order->{certificate};
|
||||
|
||||
my $check_root = sub {
|
||||
my ($chain) = @_;
|
||||
|
||||
my @certs = PVE::Certificate::split_pem($chain);
|
||||
my $root_pem = $certs[-1];
|
||||
|
||||
my ($file, $fh) = PVE::Tools::tempfile_contents($root_pem);
|
||||
my $info = PVE::Certificate::get_certificate_info($file);
|
||||
|
||||
return defined($info->{issuer}) && $info->{issuer} =~ m/\Q$root\E/i;
|
||||
};
|
||||
|
||||
my $r = $self->do(POST => $order->{certificate}, '');
|
||||
my $return = eval {
|
||||
# default chain
|
||||
my $res = __get_result($r, 200, 1);
|
||||
if ($root && !$check_root->($res)) {
|
||||
# alternate chains if requested and default didn't match
|
||||
$res = undef;
|
||||
my @links = $r->header('link');
|
||||
for my $link (@links) {
|
||||
if ($link =~ /^<(.*)>;rel="alternate"$/) {
|
||||
my $url = $1;
|
||||
my $chain = eval { __get_result($self->do(POST => $url, ''), 200, 1); };
|
||||
die "failed to retrieve alternate chain from '$url' - $@\n" if $@;
|
||||
if ($check_root->($chain)) {
|
||||
$res = $chain;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
die "no matching alternate chain for '$root' returned by server\n"
|
||||
if !defined($res);
|
||||
}
|
||||
|
||||
if ($res =~ /^(-----BEGIN CERTIFICATE-----)(.+)(-----END CERTIFICATE-----)$/s) { # untaint
|
||||
return $1 . $2 . $3;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user