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>
Jason A. Donenfeld
3 years ago
284 | 284 | //sys CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) = crypt32.CertFindExtension |
285 | 285 | //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 |
286 | 286 | //sys CryptDecodeObject(encodingType uint32, structType *byte, encodedBytes *byte, lenEncodedBytes uint32, flags uint32, decoded unsafe.Pointer, decodedLen *uint32) (err error) = crypt32.CryptDecodeObject |
287 | //sys CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptProtectData | |
288 | //sys CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptUnprotectData | |
287 | 289 | //sys WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) = wintrust.WinVerifyTrustEx |
288 | 290 | //sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW |
289 | 291 | //sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey |
497 | 497 | SECURITY_FLAG_IGNORE_WRONG_USAGE = 0x00000200 |
498 | 498 | SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000 |
499 | 499 | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000 |
500 | ||
501 | /* Flags for Crypt[Un]ProtectData */ | |
502 | CRYPTPROTECT_UI_FORBIDDEN = 0x1 | |
503 | CRYPTPROTECT_LOCAL_MACHINE = 0x4 | |
504 | CRYPTPROTECT_CRED_SYNC = 0x8 | |
505 | CRYPTPROTECT_AUDIT = 0x10 | |
506 | CRYPTPROTECT_NO_RECOVERY = 0x20 | |
507 | CRYPTPROTECT_VERIFY_PROTECTION = 0x40 | |
508 | CRYPTPROTECT_CRED_REGENERATE = 0x80 | |
509 | ||
510 | /* Flags for CryptProtectPromptStruct */ | |
511 | CRYPTPROTECT_PROMPT_ON_UNPROTECT = 1 | |
512 | CRYPTPROTECT_PROMPT_ON_PROTECT = 2 | |
513 | CRYPTPROTECT_PROMPT_RESERVED = 4 | |
514 | CRYPTPROTECT_PROMPT_STRONG = 8 | |
515 | CRYPTPROTECT_PROMPT_REQUIRE_STRONG = 16 | |
500 | 516 | ) |
501 | 517 | |
502 | 518 | const ( |
1336 | 1352 | InfoOrSerializedInfoOrOID unsafe.Pointer |
1337 | 1353 | } |
1338 | 1354 | |
1355 | type CryptProtectPromptStruct struct { | |
1356 | Size uint32 | |
1357 | PromptFlags uint32 | |
1358 | App HWND | |
1359 | Prompt *uint16 | |
1360 | } | |
1361 | ||
1339 | 1362 | type WinTrustData struct { |
1340 | 1363 | Size uint32 |
1341 | 1364 | PolicyCallbackData uintptr |
154 | 154 | procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW") |
155 | 155 | procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy") |
156 | 156 | procCryptDecodeObject = modcrypt32.NewProc("CryptDecodeObject") |
157 | procCryptProtectData = modcrypt32.NewProc("CryptProtectData") | |
157 | 158 | procCryptQueryObject = modcrypt32.NewProc("CryptQueryObject") |
159 | procCryptUnprotectData = modcrypt32.NewProc("CryptUnprotectData") | |
158 | 160 | procPFXImportCertStore = modcrypt32.NewProc("PFXImportCertStore") |
159 | 161 | procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W") |
160 | 162 | procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W") |
1274 | 1276 | return |
1275 | 1277 | } |
1276 | 1278 | |
1279 | func CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { | |
1280 | 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) | |
1281 | if r1 == 0 { | |
1282 | err = errnoErr(e1) | |
1283 | } | |
1284 | return | |
1285 | } | |
1286 | ||
1277 | 1287 | 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) { |
1278 | 1288 | 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) |
1289 | if r1 == 0 { | |
1290 | err = errnoErr(e1) | |
1291 | } | |
1292 | return | |
1293 | } | |
1294 | ||
1295 | func CryptUnprotectData(dataIn *DataBlob, name **uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) { | |
1296 | 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) | |
1279 | 1297 | if r1 == 0 { |
1280 | 1298 | err = errnoErr(e1) |
1281 | 1299 | } |