summaryrefslogtreecommitdiff
path: root/libgo/go/crypto/x509/root_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/crypto/x509/root_windows.go')
-rw-r--r--libgo/go/crypto/x509/root_windows.go35
1 files changed, 34 insertions, 1 deletions
diff --git a/libgo/go/crypto/x509/root_windows.go b/libgo/go/crypto/x509/root_windows.go
index 392c869012d..ca2fba5cb42 100644
--- a/libgo/go/crypto/x509/root_windows.go
+++ b/libgo/go/crypto/x509/root_windows.go
@@ -225,4 +225,37 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
return chains, nil
}
-func loadSystemRoots() (*CertPool, error) { return nil, nil }
+func loadSystemRoots() (*CertPool, error) {
+ const CRYPT_E_NOT_FOUND = 0x80092004
+
+ store, err := syscall.CertOpenSystemStore(0, syscall.StringToUTF16Ptr("ROOT"))
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertCloseStore(store, 0)
+
+ roots := NewCertPool()
+ var cert *syscall.CertContext
+ for {
+ cert, err = syscall.CertEnumCertificatesInStore(store, 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 := ParseCertificate(buf2); err == nil {
+ roots.AddCert(c)
+ }
+ }
+ return roots, nil
+}