我正在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。我已经定义了一个用于包含数据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>。
DataSize
Data
<nil>
看到它要填充一个指针,我尝试将其声明为*uintptrand uint32(只是为了查看是否填充了 任何东西 ),但是什么也没有。该值始终保持不变(如果我手动将垃圾数据放入其中,则在执行系统调用后,垃圾数据将保留)。
*uintptr
uint32
我是否对结构进行了错误定义?在Go中完成此工作的例子很少,但是从众多C例子中可以看出,这 应该 是可行的。
这是预期的行为。
据此:https : //msdn.microsoft.com/zh- cn/library/windows/desktop/aa387313(v=pPFX vs.85) .aspx,该结构需要一个预先分配的缓冲区,其大小在cbData字段中,它将根据复制的数据大小进行更新。
pPFX
cbData
如果使用pbData等于进行调用NULL,则仅cbData更新该字段以反映输出缓冲区所需的大小。
pbData
NULL