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
CodePudding user response:
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)