From bb7f2100fe29e98a840cb10da6c85846cbea4277 Mon Sep 17 00:00:00 2001 From: Boshi LIAN Date: Mon, 30 Nov 2020 05:23:58 -0800 Subject: [PATCH] add PFXImportCertStore CertDuplicateCertificateContext --- windows/mkwinsyscall/mkwinsyscall.go | 22 ++++++++++++++------- windows/syscall_windows.go | 2 ++ windows/types_windows.go | 20 +++++++++++++++++++ windows/zsyscall_windows.go | 29 ++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/windows/mkwinsyscall/mkwinsyscall.go b/windows/mkwinsyscall/mkwinsyscall.go index 22f844e8..4e0724b8 100644 --- a/windows/mkwinsyscall/mkwinsyscall.go +++ b/windows/mkwinsyscall/mkwinsyscall.go @@ -344,13 +344,14 @@ func (r *Rets) SetErrorCode() string { // Fn describes syscall function. type Fn struct { - Name string - Params []*Param - Rets *Rets - PrintTrace bool - dllname string - dllfuncname string - src string + Name string + Params []*Param + Rets *Rets + PrintTrace bool + WideCharStringParam bool + dllname string + dllfuncname string + src string // TODO: get rid of this field and just use parameter index instead curTmpVarIdx int // insure tmp variables have uniq names } @@ -479,6 +480,10 @@ func newFn(s string) (*Fn, error) { f.dllfuncname = n[:len(n)-1] f.Rets.fnMaybeAbsent = true } + if n := f.dllfuncname; strings.HasSuffix(n, "@W") { + f.dllfuncname = n[:len(n)-2] + f.WideCharStringParam = true + } return f, nil } @@ -596,6 +601,9 @@ func (p *Fn) MaybeAbsent() string { // IsUTF16 is true, if f is W (utf16) function. It is false // for all A (ascii) functions. func (f *Fn) IsUTF16() bool { + if f.WideCharStringParam { + return true + } s := f.DLLFuncName() return s[len(s)-1] == 'W' } diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index c71bad12..33a30f27 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -265,6 +265,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore //sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore //sys CertDeleteCertificateFromStore(certContext *CertContext) (err error) = crypt32.CertDeleteCertificateFromStore +//sys CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext, err error) [failretval==nil] = crypt32.CertDuplicateCertificateContext +//sys PFXImportCertStore(pfx *CryptDataBlob, password string, flags uint32) (store Handle, err error) = crypt32.PFXImportCertStore@W //sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain //sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain //sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext diff --git a/windows/types_windows.go b/windows/types_windows.go index 265d797c..85e8464f 100644 --- a/windows/types_windows.go +++ b/windows/types_windows.go @@ -419,6 +419,21 @@ const ( SECURITY_FLAG_IGNORE_WRONG_USAGE = 0x00000200 SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000 SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000 + + /* Flags for PFXImportCertStore */ + CRYPT_EXPORTABLE = 0x00000001 + CRYPT_USER_PROTECTED = 0x00000002 + // CRYPT_MACHINE_KEYSET = 0x00000020 + CRYPT_USER_KEYSET = 0x00001000 + PKCS12_PREFER_CNG_KSP = 0x00000100 + PKCS12_ALWAYS_CNG_KSP = 0x00000200 + PKCS12_ALLOW_OVERWRITE_KEY = 0x00004000 + PKCS12_NO_PERSIST_KEY = 0x00008000 + PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x0010 + + /* Certificate Store close flags */ + CERT_CLOSE_STORE_FORCE_FLAG = 0x00000001 + CERT_CLOSE_STORE_CHECK_FLAG = 0x00000002 ) const ( @@ -1139,6 +1154,11 @@ type CertChainPolicyStatus struct { ExtraPolicyStatus Pointer } +type CryptDataBlob struct { + Size uint32 + Data *byte +} + const ( // do not reorder HKEY_CLASSES_ROOT = 0x80000000 + iota diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index a933c0ee..3072510e 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -142,6 +142,7 @@ var ( procCertCloseStore = modcrypt32.NewProc("CertCloseStore") procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext") procCertDeleteCertificateFromStore = modcrypt32.NewProc("CertDeleteCertificateFromStore") + procCertDuplicateCertificateContext = modcrypt32.NewProc("CertDuplicateCertificateContext") procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore") procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain") procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext") @@ -149,6 +150,7 @@ var ( procCertOpenStore = modcrypt32.NewProc("CertOpenStore") procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") + procPFXImportCertStore = modcrypt32.NewProc("PFXImportCertStore") procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") @@ -1163,6 +1165,15 @@ func CertDeleteCertificateFromStore(certContext *CertContext) (err error) { return } +func CertDuplicateCertificateContext(certContext *CertContext) (dupContext *CertContext, err error) { + r0, _, e1 := syscall.Syscall(procCertDuplicateCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(certContext)), 0, 0) + dupContext = (*CertContext)(unsafe.Pointer(r0)) + if dupContext == nil { + err = errnoErr(e1) + } + return +} + func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) { r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0) context = (*CertContext)(unsafe.Pointer(r0)) @@ -1219,6 +1230,24 @@ func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext return } +func PFXImportCertStore(pfx *CryptDataBlob, password string, flags uint32) (store Handle, err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(password) + if err != nil { + return + } + return _PFXImportCertStore(pfx, _p0, flags) +} + +func _PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) { + r0, _, e1 := syscall.Syscall(procPFXImportCertStore.Addr(), 3, uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags)) + store = Handle(r0) + if store == 0 { + err = errnoErr(e1) + } + return +} + func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) { r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0) same = r0 != 0