curl handling of this case depends on the build.
curl can use any of several TLS implementations, determined at compile time, and it should not be much of a surprise that the behavior of the TLS implementation in curl depends on the TLS implementation in curl.
curl with schannel CAN fetch a missing chain cert (not sent by the server, as required by RFCs) using AIA, and validate the result. In addition, curl with schannel will fill-in a missing chain cert if it is in the Windows cert store (just as it will always validate against roots in the Windows cert store), and while I can't easily verify exactly when such chain certs get put in the Windows store, my (Win 10 Home) system, used daily for good bit of web browsing and occasionally for things like curl and powershell iwr, does have about a dozen of them. curl with schannel is only available on Windows, of course. And since you suggest you are using --pinnedpubkey
which is not supported with schannel, you may not be using schannel.
OpenSSL definitely does not ever use AIA for this, so curl with OpenSSL, popular on many (but not all) Linux distros, does not either. As Frederic discovered, OpenSSL will fill-in a chain cert (as well as a root) from the file supplied as --cacert
, so if you either know or can guess what chain cert(s) you will need, and download them (all) in advance, this will work.
I'm pretty sure NSS itself can do AIA (because Firefox does), but I don't know if and how curl would access or enable it, and the one curl with NSS I can easily test (on Ubuntu 16.04 on WSL, admittedly a bit out of date) does not do it..
I don't know about GnuTLS either way, but curl with GnuTLS on CentOS 7 does not do it.
However, to your real question, I don't of any tool that will do it manually and save the result.
https://www.ssllabs.com/ssltest/ does a very extensive test of SSL/TLS features and compatibility which includes filling-in and validating your cert/chain in a browser-like fashion and displaying the results; if will even display multiple trust paths if it finds them, which browsers don't do. You might be able to scrape those results. https://whatsmychaincert.com/ does only the chain build/correction, and I seem to recall it produces a nice PEM, but I can't verify since the only public test I know of is currently broken (the same one Frederic referenced, incomplete-chain.badssl.com).
Java (more exactly JSSE, the SSL/TLS implementation in Java when using the 'standard' cryptoproviders) can fetch using AIA as part of validation (but not by default, you must enable it) so you could write a simple Java program that connects to a website, validates the cert with AIA.caIssuers enabled, and if successful write out the resulting cert and/or its key for pinning; I'd expect this is only 20-30 lines and if no better solution is provided and I have time later I'll give it a shot. (Or, this being Stack, anyone else can do so.)
curl
happy. What can be the root of your problem is a self-signed certificate, which - by default - you don't trust (in this case there are no intermediate certificate, but this is not the root of the issue). With such certificates, you have to configurecurl
to trust this certificate.curl
trusts it.--pinnedpubkey <value>
) or null if verifying failedcurl
with a self-signed certificate... and it works. All you need is thatcurl
trusts the proposed root. Either throught the/etc/ssl/certs
files which are trusted by default, or with a--cacert
option. (Note copying the self-signed certificate in /etc/ssl/certs` doesn't work)