在使用`certtostore`在Golang中从Windows证书存储中获取证书时遇到错误?

huangapple go评论73阅读模式
英文:

Getting error while fetching certificate from windows certificate store in Golang using `certtostore`?

问题

我想使用来自Windows证书存储的证书包,有人可以告诉我我在这里做错了什么吗?

我的代码:

package main

import (
	"fmt"
	"runtime"

	"github.com/google/certtostore"
)

type certmgr struct {
	certToStore certtostore.CertStorage
}

func main() {
	if runtime.GOOS == "windows" {
		var cert certmgr
		certInStore, err := cert.certToStore.Cert()
		if err != nil {
			fmt.Println("message", "获取系统存储证书时出错...")
		}

		fmt.Println("Windows系统存储证书", *certInStore)

	}
}

我得到的错误:

panic: 运行时错误:无效的内存地址或空指针解引用
[signal 0xc0000005 code=0x0 addr=0x0 pc=0xbe2dda]

goroutine 1 [running]:
main.main()
        C:/Users/prajwal.bhagat/go/src/phoenix/mainsvc/cmd/main/test.go:17 +0x1a
exit status 2
英文:

I want to use certificate bundle from windows certificate store, can anyone please tell me what wrong I am doing here?

My Code:

package main

import (
	"fmt"
	"runtime"

	"github.com/google/certtostore"
)

type certmgr struct {
	certToStore certtostore.CertStorage
}

func main() {
	if runtime.GOOS == "windows" {
		var cert certmgr
		certInStore, err := cert.certToStore.Cert()
		if err != nil {
			fmt.Println("message", "Error in getting system store certificate ...")
		}

		fmt.Println("Windows System Store Certificate", *certInStore)

	}
}

The Error I am getting :

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0xbe2dda]

goroutine 1 [running]:
main.main()
        C:/Users/prajwal.bhagat/go/src/phoenix/mainsvc/cmd/main/test.go:17 +0x1a
exit status 2

答案1

得分: 0

你可以使用类似 google/certtostore 的库,它是一个多平台的包,可以让你在Linux上使用x509证书,在Windows上使用证书存储。

它并不直接获取证书包,而是使用了Windows的certGetCertificateChain调用,该调用从终端证书开始构建证书链上下文,如果可能的话,回溯到受信任的根CA

它被CertWithContext()使用,该函数使用创建WinCertStore时提供的发行者值进行证书查找。
它返回证书和其Windows上下文,可以用于执行其他操作,比如使用CertKey()查找私钥。


> 无效的内存地址或空指针解引用

你需要初始化var cert certmgr

更一般地说,你需要首先获取存储,就像这个示例中所示:

	fmt.Println("打开证书存储")

	// 打开本地证书存储。提供程序通常不重要,所以使用普遍存在的Software。参见getHostKey中的注释。
	store, err := certtostore.OpenWinCertStore(certtostore.ProviderMSSoftware, "", []string{"localhost"}, nil, false)
	
	if err != nil {
		fmt.Errorf("OpenWinCertStore: %v", err)
		return
	}	
	
	fmt.Println("从证书存储获取证书")
	// 从存储中获取与容器/发行者/中间证书完全匹配的第一个证书。
	// 该函数对存储打开的提供程序无关,因为存储列出了所有提供程序的证书。
	crt, context, err := store.CertWithContext()
	if err != nil {
		fmt.Println("从证书存储获取证书失败。", err)
		return
	}
	
	if crt == nil {
		fmt.Println("没有证书")
		return
	}

	fmt.Println("从证书获取密钥")
	// 从证书中获取私钥。无论提供程序如何,这应该都能工作,因为密钥直接与证书关联。
	key, err := store.CertKey(context)
	if err != nil {
		fmt.Printf("在%s中找不到私钥,%s", store.ProvName, err)
		return
	}

	if key == nil {
		fmt.Println("没有密钥")
		return
	}

	fmt.Printf("在容器'%s'中找到带有私钥的证书'%s',算法'%s'\n", crt.Subject, key.Container, key.AlgorithmGroup)
英文:

You could use a library like google/certtostore, which is a multi-platform package that allows you to work with x509 certificates on Linux and the certificate store on Windows.

It does not fetch directly a certificate bundle, but does use the Windows certGetCertificateChain call, which builds a certificate chain context starting from an end certificate and going back, if possible, to a trusted root CA.

It is used by CertWithContext(), which performs a certificate lookup using value of issuers that was provided when WinCertStore was created.
It returns both the certificate and its Windows context, which can be used to perform other operations, such as looking up the private key with CertKey().


> invalid memory address or nil pointer dereference

You need to initialize the var cert certmgr

More generally, you need to get the store first, as in this example:

	fmt.Println("open cert store")

	// Open the local cert store. Provider generally shouldn't matter, so use Software which is ubiquitous. See comments in getHostKey.
	store, err := certtostore.OpenWinCertStore(certtostore.ProviderMSSoftware, "", []string{"localhost"}, nil, false)
	
	if err != nil {
		fmt.Errorf("OpenWinCertStore: %v", err)
		return
	}	
	
	fmt.Println("get cert from cert store")
	// Obtain the first cert matching all of container/issuers/intermediates in the store.
	// This function is indifferent to the provider the store was opened with, as the store lists certs
	// from all providers.
	crt, context, err := store.CertWithContext()
	if err != nil {
		fmt.Println("failed to get cert from cert store. ", err)
		return
	}
	
	if crt == nil {
		fmt.Println("no cert")
		return
	}

	fmt.Println("get key from cert")
	// Obtain the private key from the cert. This *should* work regardless of provider because
	// the key is directly linked to the certificate.
	key, err := store.CertKey(context)
	if err != nil {
		fmt.Printf("private key not found in %s, %s", store.ProvName, err)
		return
	}

	if key == nil {
		fmt.Println("no key")
		return
	}

	fmt.Printf("find cert '%s' with private key in container '%s', algo '%s'\n", crt.Subject, key.Container, key.AlgorithmGroup)

huangapple
  • 本文由 发表于 2022年6月2日 16:46:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/72473312.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定