Skip to content
New issue

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

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

Already on GitHub? # to your account

Use workaround for windows x509.SystemCertPool() #2756

Merged
merged 6 commits into from
Feb 4, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/config/tlscfg/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ func (p *Options) Config(logger *zap.Logger) (*tls.Config, error) {

func (p Options) loadCertPool() (*x509.CertPool, error) {
if len(p.CAPath) == 0 { // no truststore given, use SystemCertPool
certPool, err := systemCertPool()
certPool, err := createCertPool()
if err != nil {
return nil, fmt.Errorf("failed to load SystemCertPool: %w", err)
return nil, fmt.Errorf("failed to create CertPool: %w", err)
}
return certPool, nil
}
Expand Down
30 changes: 30 additions & 0 deletions pkg/config/tlscfg/options_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2021 The Jaeger Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build !windows

package tlscfg

import (
"crypto/x509"
"fmt"
)

func createCertPool() (*x509.CertPool, error) {
certPool, err := systemCertPool()
if err != nil {
return nil, fmt.Errorf("failed to load SystemCertPool: %w", err)
}
return certPool, nil
}
78 changes: 78 additions & 0 deletions pkg/config/tlscfg/options_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2021 The Jaeger Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build windows

package tlscfg

import (
"crypto/x509"
"fmt"
"syscall"
"unsafe"
)

const (
// CRYPT_E_NOT_FOUND is an error code specific to windows cert pool.
// See https://github.com/golang/go/issues/16736#issuecomment-540373689.
CRYPT_E_NOT_FOUND = 0x80092004
)

// workaround https://github.com/golang/go/issues/16736
// fix borrowed from Sensu: https://github.com/sensu/sensu-go/pull/4018
func appendCerts(rootCAs *x509.CertPool) (*x509.CertPool, error) {
storeHandle, err := syscall.CertOpenSystemStore(0, syscall.StringToUTF16Ptr("Root"))
if err != nil {
return nil, err
}

var cert *syscall.CertContext
for {
cert, err = syscall.CertEnumCertificatesInStore(storeHandle, cert)
if err != nil {
if errno, ok := err.(syscall.Errno); ok {
if errno == CRYPT_E_NOT_FOUND {
break
}
}
return nil, err
}
if cert == nil {
break
}
// Copy the buf, since ParseCertificate does not create its own copy.
buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:]
buf2 := make([]byte, cert.Length)
copy(buf2, buf)
if c, err := x509.ParseCertificate(buf2); err == nil {
rootCAs.AddCert(c)
}
}
return rootCAs, nil
}

func createCertPool() (*x509.CertPool, error) {
certPool, err := systemCertPool()
if err != nil {
return nil, fmt.Errorf("failed to load SystemCertPool: %w", err)
}
if certPool == nil {
certPool = x509.NewCertPool()
}
certPool, err = appendCerts(certPool)
if err != nil {
return nil, fmt.Errorf("failed to append SystemCertPool: %w", err)
}
return certPool, nil
}