windowsgox509certificateglide-golanggolang-migrate

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


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

Solution

  • 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)