Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/x509: select a certificate store for systemVerify on Windows #34977

SeanBurford opened this issue Oct 18, 2019 · 6 comments

crypto/x509: select a certificate store for systemVerify on Windows #34977

SeanBurford opened this issue Oct 18, 2019 · 6 comments
NeedsInvestigation OS-Windows


Copy link

@SeanBurford SeanBurford commented Oct 18, 2019

What version of Go are you using (go version)?

$ go version
go version go1.13 linux/amd64

Does this issue reproduce with the latest release?


What operating system and processor architecture are you using (go env)?


What did you do?

Attempted to build a set of certificate chains for a certificate:

var cert *x509.Certificate
intermediates := x509.NewCertPool()
vo := x509.VerifyOptions{
    Roots:         nil, // Use system roots
    Intermediates: intermediates,
chains, err := cert.Verify(vo)

What did you expect to see?

Complete chains when running as a user or as the system user.

What did you see instead?

systemVerify() in crypto.x509.root_windows.go always passes HCCE_CURRENT_USER as the hChainEngine argument to syscall.CertGetCertificateChain() (syscall.Handle(0) in the first argument). This means that chain lookups as the system user will fail for us, because the required certificates are stored in HCCE_LOCAL_MACHINE (syscall.Handle(1)).

It's possible to pass an additional store as argument 4 to the syscall. This argument is currently storeCtx.Store, which is nil but it might be possible for createStoreContext to populate it with a HCERTSTORE pointing to HCCE_LOCAL_MACHINE.

Alternately, the store preference could be specified in VerifyOptions.

Copy link

@networkimprov networkimprov commented Oct 18, 2019

@SeanBurford it helps if you bracket code examples with ``` lines


cc @alexbrainman @mattn @zx2c4
@gopherbot add OS-Windows

Copy link

@mattn mattn commented Oct 18, 2019

x509.SystemCertPool() on Windows is not provided from standard library any more. The reason is that Windows doesn't ship with all of its root certificates installed. Instead, it downloads them on-demand.

See #18609

Copy link

@zx2c4 zx2c4 commented Oct 18, 2019

@SeanBurford Are you saying that when the process is running as S-1-5-18, HCCE_CURRENT_USER results in Go using a totally empty certificate store?

@dmitshur dmitshur changed the title Select a certificate store for systemVerify on Windows crypto/x509: select a certificate store for systemVerify on Windows Oct 21, 2019
@dmitshur dmitshur added the NeedsInvestigation label Oct 21, 2019
Copy link

@SeanBurford SeanBurford commented Oct 22, 2019

@zx2c4, no, I'm saying that the intermediates that we need to build the chain to a certificate are installed in the Local Machine System CA store. When running as S-1-5-18 a search of the Current User CA store doesn't find them so the chain(s) cannot be built.

Copy link

@zx2c4 zx2c4 commented Oct 22, 2019

So should we be passing HCCE_LOCAL_MACHINE all the time, or will that result in other complications when running as non-S-1-5-18?

Copy link

@andig andig commented Mar 19, 2022

I have a similar issue. Connecting to TLS with LetsEncrypt certificate I'd like to verify that root ca is either LetsEncrypt (I'd expect that to come from the system cert pool) or my own root ca certificate (I don't claim cryptographic correctness).

On windows this will error when retrieving the system cert pool:

certPool, err := x509.SystemCertPool()
if err != nil {
	return nil, err

if !certPool.AppendCertsFromPEM(caPEM()) {
	return nil, fmt.Errorf("failed to add CA certificate")

// create the credentials and return it
config := &tls.Config{
	RootCAs: certPool,

In the absence of SystemCertPool, what is the right way to check the root CA (on Windows)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
NeedsInvestigation OS-Windows
None yet

No branches or pull requests

7 participants