mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-02 23:27:31 -04:00
windows: add support for DPAPI
DPAPI allows machine or user-based blob encryption, using APIs from crypt32: https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptunprotectdata https://docs.microsoft.com/en-us/windows/win32/api/dpapi/nf-dpapi-cryptprotectdata Change-Id: I57fb4f1877a5fb7629809e79111cbfa02b11cca3 Reviewed-on: https://go-review.googlesource.com/c/sys/+/285716 Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Jason A. Donenfeld <Jason@zx2c4.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
@@ -285,6 +285,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||||||
//sys CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) = crypt32.CertFindExtension
|
//sys CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) = crypt32.CertFindExtension
|
||||||
//sys CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) = crypt32.CryptQueryObject
|
//sys CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) = crypt32.CryptQueryObject
|
||||||
//sys CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) = crypt32.CryptDecodeObject
|
//sys CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) = crypt32.CryptDecodeObject
|
||||||
|
//sys CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptProtectData
|
||||||
|
//sys CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptUnprotectData
|
||||||
//sys WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) = wintrust.WinVerifyTrustEx
|
//sys WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) = wintrust.WinVerifyTrustEx
|
||||||
//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
|
//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
|
||||||
//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
|
//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
|
||||||
|
|||||||
@@ -498,6 +498,22 @@ const (
|
|||||||
SECURITY_FLAG_IGNORE_WRONG_USAGE = 0x00000200
|
SECURITY_FLAG_IGNORE_WRONG_USAGE = 0x00000200
|
||||||
SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000
|
SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000
|
||||||
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000
|
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000
|
||||||
|
|
||||||
|
/* Flags for Crypt[Un]ProtectData */
|
||||||
|
CRYPTPROTECT_UI_FORBIDDEN = 0x1
|
||||||
|
CRYPTPROTECT_LOCAL_MACHINE = 0x4
|
||||||
|
CRYPTPROTECT_CRED_SYNC = 0x8
|
||||||
|
CRYPTPROTECT_AUDIT = 0x10
|
||||||
|
CRYPTPROTECT_NO_RECOVERY = 0x20
|
||||||
|
CRYPTPROTECT_VERIFY_PROTECTION = 0x40
|
||||||
|
CRYPTPROTECT_CRED_REGENERATE = 0x80
|
||||||
|
|
||||||
|
/* Flags for CryptProtectPromptStruct */
|
||||||
|
CRYPTPROTECT_PROMPT_ON_UNPROTECT = 1
|
||||||
|
CRYPTPROTECT_PROMPT_ON_PROTECT = 2
|
||||||
|
CRYPTPROTECT_PROMPT_RESERVED = 4
|
||||||
|
CRYPTPROTECT_PROMPT_STRONG = 8
|
||||||
|
CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -1337,6 +1353,13 @@ type CertStrongSignPara struct {
|
|||||||
InfoOrSerializedInfoOrOID unsafe.Pointer
|
InfoOrSerializedInfoOrOID unsafe.Pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CryptProtectPromptStruct struct {
|
||||||
|
Size uint32
|
||||||
|
PromptFlags uint32
|
||||||
|
App HWND
|
||||||
|
Prompt *uint16
|
||||||
|
}
|
||||||
|
|
||||||
type WinTrustData struct {
|
type WinTrustData struct {
|
||||||
Size uint32
|
Size uint32
|
||||||
PolicyCallbackData uintptr
|
PolicyCallbackData uintptr
|
||||||
|
|||||||
@@ -155,7 +155,9 @@ var (
|
|||||||
procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW")
|
procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW")
|
||||||
procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
|
procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
|
||||||
procCryptDecodeObject = modcrypt32.NewProc("CryptDecodeObject")
|
procCryptDecodeObject = modcrypt32.NewProc("CryptDecodeObject")
|
||||||
|
procCryptProtectData = modcrypt32.NewProc("CryptProtectData")
|
||||||
procCryptQueryObject = modcrypt32.NewProc("CryptQueryObject")
|
procCryptQueryObject = modcrypt32.NewProc("CryptQueryObject")
|
||||||
|
procCryptUnprotectData = modcrypt32.NewProc("CryptUnprotectData")
|
||||||
procPFXImportCertStore = modcrypt32.NewProc("PFXImportCertStore")
|
procPFXImportCertStore = modcrypt32.NewProc("PFXImportCertStore")
|
||||||
procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W")
|
procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W")
|
||||||
procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W")
|
procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W")
|
||||||
@@ -1275,6 +1277,14 @@ func CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall9(procCryptProtectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) {
|
func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentTypeFlags uint32, expectedFormatTypeFlags uint32, flags uint32, msgAndCertEncodingType *uint32, contentType *uint32, formatType *uint32, certStore *Handle, msg *Handle, context *unsafe.Pointer) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall12(procCryptQueryObject.Addr(), 11, uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context)), 0)
|
r1, _, e1 := syscall.Syscall12(procCryptQueryObject.Addr(), 11, uintptr(objectType), uintptr(object), uintptr(expectedContentTypeFlags), uintptr(expectedFormatTypeFlags), uintptr(flags), uintptr(unsafe.Pointer(msgAndCertEncodingType)), uintptr(unsafe.Pointer(contentType)), uintptr(unsafe.Pointer(formatType)), uintptr(unsafe.Pointer(certStore)), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(context)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@@ -1283,6 +1293,14 @@ func CryptQueryObject(objectType uint32, object unsafe.Pointer, expectedContentT
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall9(procCryptUnprotectData.Addr(), 7, uintptr(unsafe.Pointer(dataIn)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(optionalEntropy)), uintptr(reserved), uintptr(unsafe.Pointer(promptStruct)), uintptr(flags), uintptr(unsafe.Pointer(dataOut)), 0, 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func PFXImportCertStore(pfx *CryptDataBlob, password *uint16, flags uint32) (store Handle, err error) {
|
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))
|
r0, _, e1 := syscall.Syscall(procPFXImportCertStore.Addr(), 3, uintptr(unsafe.Pointer(pfx)), uintptr(unsafe.Pointer(password)), uintptr(flags))
|
||||||
store = Handle(r0)
|
store = Handle(r0)
|
||||||
|
|||||||
Reference in New Issue
Block a user