【发布时间】:2016-02-25 17:22:59
【问题描述】:
我在 Windows 上使用 Go 1.6 并尝试将证书容器导出到 PFX(此处的最终目标是从证书存储访问可导出的私钥)。
我已经打开了一个内存存储并在存储中插入了一个证书:
var storedCertCtx *syscall.CertContext
storeHandle, err := syscall.CertOpenStore(syscall.CERT_STORE_PROV_MEMORY, 0, 0, syscall.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, 0)
err = syscall.CertAddCertificateContextToStore(storeHandle, certenum, syscall.CERT_STORE_ADD_ALWAYS, &storedCertCtx)
现在我想生成该商店的 PFX。我已经定义了一个包含data blob 的结构,并希望使用PFXExportCertStoreEx 来获取商店的PFX:
var (
crypt32 = syscall.NewLazyDLL("crypt32.dll")
procPFXExportCertStoreEx = crypt32.NewProc("PFXExportCertStoreEx")
)
type CRYPTOAPI_BLOB struct {
DataSize uint32
Data *byte
}
var pfxBlob CRYPTOAPI_BLOB
err = PfxExportCertStore(storeHandle, &pfxBlob, syscall.StringToUTF16Ptr("MyPassword"), 0, 0)
syscall.Syscall6(procPFXExportCertStoreEx.Addr(), 5,
uintptr(storeHandle), //hStore
uintptr(unsafe.Pointer(&pfxBlob)), //*pPFX
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("password"))), //szPassword
0, //*pvPara
0, //dwFlags
0)
这一半有效。
DataSize 填充了看起来合适的值(即,如果我向商店添加更多证书,它会变得更大),但是 Data 是始终 <nil>。
看到它应该用指针填充,我尝试将其声明为 *uintptr 和 uint32(只是为了查看是否填充了 anything),但什么也没有。该值始终保持不变(如果我手动将垃圾数据放在那里,垃圾数据会在系统调用执行后保留)。
我是否错误地定义了结构?在 Go 中完成这项工作的示例很少,但从众多 C 示例中我可以看出,这应该工作。
【问题讨论】:
-
“空白”是指
pfxBlob.Data == 0,还是指Data点为空的内存块? -
@JimB 如果我执行
fmt.Println(pfxBlob.Data),我会得到<nil>。我还刚刚注意到我粘贴到代码 sn-p 中的结构来自以前的修订版,我将更新为最新版本。 -
有没有试过检查调用后的返回值和错误?
-
从快速的 google 看来,这是预期的行为:msdn.microsoft.com/en-us/library/windows/desktop/… - 从阅读看来,您需要预先分配缓冲区并将大小放入
cbData。如果pbData为 nil,则调用仅返回所需的大小。 -
@JimB GetLastError() 不返回任何内容,系统调用的第一个返回表示成功。
标签: go system-calls x509 certificate-store