func certContextToX509(ctx *windows.CertContext) (*x509.Certificate, error) {
	var der []byte
	slice := (*reflect.SliceHeader)(unsafe.Pointer(&der))
	slice.Data = uintptr(unsafe.Pointer(ctx.EncodedCert))
	slice.Len = int(ctx.Length)
	slice.Cap = int(ctx.Length)
	return x509.ParseCertificate(der)
}
certContextToX509 creates an x509.Certificate from a Windows cert context.
package certtostore
import (
	"bytes"
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rsa"
	"crypto/x509"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/big"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"strings"
	"syscall"
	"time"
	"unicode/utf16"
	"unsafe"
	"golang.org/x/crypto/cryptobyte/asn1"
	"golang.org/x/crypto/cryptobyte"
	"golang.org/x/sys/windows"
	"github.com/google/logger"
)
const (
	acquireCached           = 0x1                                              
	acquireSilent           = 0x40                                             
	acquireOnlyNCryptKey    = 0x40000                                          
	encodingX509ASN         = 1                                                
	encodingPKCS7           = 65536                                            
	certStoreProvSystem     = 10                                               
	certStoreCurrentUser    = uint32(certStoreCurrentUserID << compareShift)   
	certStoreLocalMachine   = uint32(certStoreLocalMachineID << compareShift)  
	certStoreCurrentUserID  = 1                                                
	certStoreLocalMachineID = 2                                                
	infoIssuerFlag          = 4                                                
	compareNameStrW         = 8                                                
	compareShift            = 16                                               
	findIssuerStr           = compareNameStrW<<compareShift | infoIssuerFlag   
	signatureKeyUsage       = 0x80                                             
	ncryptKeySpec           = 0xFFFFFFFF                                       
	bCryptPadPKCS1 uintptr = 0x2
	rsa1Magic = 0x31415352  
	ecs1Magic = 0x31534345  
	ecs3Magic = 0x33534345  
	ecs5Magic = 0x35534345  
	ncryptPersistFlag           = 0x80000000  
	ncryptAllowDecryptFlag      = 0x1         
	ncryptAllowSigningFlag      = 0x2         
	ncryptWriteKeyToLegacyStore = 0x00000200  
	NCryptPadOAEPFlag = 0x00000004  
	nCryptMachineKey   = 0x20  
	nCryptOverwriteKey = 0x80  
	cryptENotFound = 0x80092004  
	ProviderMSPlatform = "Microsoft Platform Crypto Provider"
	ProviderMSSoftware = "Microsoft Software Key Storage Provider"
	ProviderMSLegacy = "Microsoft Enhanced Cryptographic Provider v1.0"
	hcceLocalMachine                  = windows.Handle(0x01)  
	certChainCacheOnlyURLRetrieval    = 0x00000004            
	certChainDisableAIA               = 0x00002000            
	certChainRevocationCheckCacheOnly = 0x80000000            
)
var (
	bCryptRSAPublicBlob = wide("RSAPUBLICBLOB")
	bCryptECCPublicBlob = wide("ECCPUBLICBLOB")
	nCryptAlgorithmGroupProperty = wide("Algorithm Group")  
	nCryptUniqueNameProperty     = wide("Unique Name")      
	curveIDs = map[uint32]elliptic.Curve{
		ecs1Magic: elliptic.P256(),  
		ecs3Magic: elliptic.P384(),  
		ecs5Magic: elliptic.P521(),  
	}
	algIDs = map[crypto.Hash]*uint16{
		crypto.SHA1:   wide("SHA1"),    
		crypto.SHA256: wide("SHA256"),  
		crypto.SHA384: wide("SHA384"),  
		crypto.SHA512: wide("SHA512"),  
	}
	my   = wide("MY")
	ca   = wide("CA")
	root = wide("ROOT")
	crypt32 = windows.MustLoadDLL("crypt32.dll")
	nCrypt  = windows.MustLoadDLL("ncrypt.dll")
	certDeleteCertificateFromStore    = crypt32.MustFindProc("CertDeleteCertificateFromStore")
	certFindCertificateInStore        = crypt32.MustFindProc("CertFindCertificateInStore")
	certFreeCertificateChain          = crypt32.MustFindProc("CertFreeCertificateChain")
	certGetCertificateChain           = crypt32.MustFindProc("CertGetCertificateChain")
	certGetIntendedKeyUsage           = crypt32.MustFindProc("CertGetIntendedKeyUsage")
	cryptAcquireCertificatePrivateKey = crypt32.MustFindProc("CryptAcquireCertificatePrivateKey")
	cryptFindCertificateKeyProvInfo   = crypt32.MustFindProc("CryptFindCertificateKeyProvInfo")
	nCryptCreatePersistedKey          = nCrypt.MustFindProc("NCryptCreatePersistedKey")
	nCryptDecrypt                     = nCrypt.MustFindProc("NCryptDecrypt")
	nCryptExportKey                   = nCrypt.MustFindProc("NCryptExportKey")
	nCryptFinalizeKey                 = nCrypt.MustFindProc("NCryptFinalizeKey")
	nCryptOpenKey                     = nCrypt.MustFindProc("NCryptOpenKey")
	nCryptOpenStorageProvider         = nCrypt.MustFindProc("NCryptOpenStorageProvider")
	nCryptGetProperty                 = nCrypt.MustFindProc("NCryptGetProperty")
	nCryptSetProperty                 = nCrypt.MustFindProc("NCryptSetProperty")
	nCryptSignHash                    = nCrypt.MustFindProc("NCryptSignHash")
)
type paddingInfo struct {
	pszAlgID *uint16
}
func wide(s string) *uint16 {
	w := utf16.Encode([]rune(s))
	w = append(w, 0)
	return &w[0]
}
func openProvider(provider string) (uintptr, error) {
	var err error
	var hProv uintptr
	pname := wide(provider)
	r, _, err := nCryptOpenStorageProvider.Call(uintptr(unsafe.Pointer(&hProv)), uintptr(unsafe.Pointer(pname)), 0)
	if r == 0 {
		return hProv, nil
	}
	return hProv, fmt.Errorf("NCryptOpenStorageProvider returned %X: %v", r, err)
}
func findCert(store windows.Handle, enc, findFlags, findType uint32, para *uint16, prev *windows.CertContext) (*windows.CertContext, error) {
	h, _, err := certFindCertificateInStore.Call(
		uintptr(store),
		uintptr(enc),
		uintptr(findFlags),
		uintptr(findType),
		uintptr(unsafe.Pointer(para)),
		uintptr(unsafe.Pointer(prev)),
	)
	if h == 0 {
		if errno, ok := err.(syscall.Errno); ok && errno == cryptENotFound {
			return nil, nil
		}
		return nil, err
	}
	return (*windows.CertContext)(unsafe.Pointer(h)), nil
}
func intendedKeyUsage(enc uint32, cert *windows.CertContext) (usage uint16) {
	certGetIntendedKeyUsage.Call(uintptr(enc), uintptr(unsafe.Pointer(cert.CertInfo)), uintptr(unsafe.Pointer(&usage)), 2)
	return
}
type WinCertStore struct {
	CStore              windows.Handle
	Prov                uintptr
	ProvName            string
	issuers             []string
	intermediateIssuers []string
	container           string
	keyStorageFlags     uintptr
	certChains          [][]*x509.Certificate
}
func OpenWinCertStore(provider, container string, issuers, intermediateIssuers []string, legacyKey bool) (*WinCertStore, error) {
	cngProv, err := openProvider(provider)
	if err != nil {
		return nil, fmt.Errorf("unable to open crypto provider or provider not available: %v", err)
	}
	wcs := &WinCertStore{
		Prov:                cngProv,
		ProvName:            provider,
		issuers:             issuers,
		intermediateIssuers: intermediateIssuers,
		container:           container,
	}
	if legacyKey {
		wcs.keyStorageFlags = ncryptWriteKeyToLegacyStore
		wcs.ProvName = ProviderMSLegacy
	}
	return wcs, nil
}