Skip to content

Commit

Permalink
windows: add CertFindCertificateInStore, CertFindChainInStore and Cry…
Browse files Browse the repository at this point in the history
…ptAcquireCertificatePrivateKey

add cert loading related syscall
CertFindCertificateInStore [1]
CertFindChainInStore [2]
CryptAcquireCertificatePrivateKey [3]

[1] https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfindcertificateinstore
[2] https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfindchaininstore
[3] https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecertificateprivatekey

Change-Id: I179bffd06d714d729f3afd83687336edecae6b37
GitHub-Last-Rev: 58a8c66
GitHub-Pull-Request: #94
Reviewed-on: https://go-review.googlesource.com/c/sys/+/281012
TryBot-Result: Go Bot <[email protected]>
Reviewed-by: Jason A. Donenfeld <[email protected]>
Trust: Jason A. Donenfeld <[email protected]>
Trust: Alex Brainman <[email protected]>
Run-TryBot: Jason A. Donenfeld <[email protected]>
  • Loading branch information
tg123 authored and zx2c4 committed Feb 19, 2021
1 parent 8ebf48a commit 3351caf
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
3 changes: 3 additions & 0 deletions windows/syscall_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,9 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
//sys CertGetNameString(certContext *CertContext, nameType uint32, flags uint32, typePara unsafe.Pointer, name *uint16, size uint32) (chars uint32) = crypt32.CertGetNameStringW
//sys CertFindExtension(objId *byte, countExtensions uint32, extensions *CertExtension) (ret *CertExtension) = crypt32.CertFindExtension
//sys CertFindCertificateInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevCertContext *CertContext) (cert *CertContext, err error) [failretval==nil] = crypt32.CertFindCertificateInStore
//sys CertFindChainInStore(store Handle, certEncodingType uint32, findFlags uint32, findType uint32, findPara unsafe.Pointer, prevChainContext *CertChainContext) (certchain *CertChainContext, err error) [failretval==nil] = crypt32.CertFindChainInStore
//sys CryptAcquireCertificatePrivateKey(cert *CertContext, flags uint32, parameters unsafe.Pointer, cryptProvOrNCryptKey *Handle, keySpec *uint32, callerFreeProvOrNCryptKey *bool) (err error) = crypt32.CryptAcquireCertificatePrivateKey
//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 CryptProtectData(dataIn *DataBlob, name *uint16, optionalEntropy *DataBlob, reserved uintptr, promptStruct *CryptProtectPromptStruct, flags uint32, dataOut *DataBlob) (err error) = crypt32.CryptProtectData
Expand Down
124 changes: 124 additions & 0 deletions windows/types_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,23 @@ const (
PKCS12_NO_PERSIST_KEY = 0x00008000
PKCS12_INCLUDE_EXTENDED_PROPERTIES = 0x00000010

/* Flags for CryptAcquireCertificatePrivateKey */
CRYPT_ACQUIRE_CACHE_FLAG = 0x00000001
CRYPT_ACQUIRE_USE_PROV_INFO_FLAG = 0x00000002
CRYPT_ACQUIRE_COMPARE_KEY_FLAG = 0x00000004
CRYPT_ACQUIRE_NO_HEALING = 0x00000008
CRYPT_ACQUIRE_SILENT_FLAG = 0x00000040
CRYPT_ACQUIRE_WINDOW_HANDLE_FLAG = 0x00000080
CRYPT_ACQUIRE_NCRYPT_KEY_FLAGS_MASK = 0x00070000
CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG = 0x00010000
CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG = 0x00020000
CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG = 0x00040000

/* pdwKeySpec for CryptAcquireCertificatePrivateKey */
AT_KEYEXCHANGE = 1
AT_SIGNATURE = 2
CERT_NCRYPT_KEY_SPEC = 0xFFFFFFFF

/* Default usage match type is AND with value zero */
USAGE_MATCH_TYPE_AND = 0
USAGE_MATCH_TYPE_OR = 1
Expand Down Expand Up @@ -412,6 +429,89 @@ const (
CERT_TRUST_IS_CA_TRUSTED = 0x00004000
CERT_TRUST_IS_COMPLEX_CHAIN = 0x00010000

/* Certificate Information Flags */
CERT_INFO_VERSION_FLAG = 1
CERT_INFO_SERIAL_NUMBER_FLAG = 2
CERT_INFO_SIGNATURE_ALGORITHM_FLAG = 3
CERT_INFO_ISSUER_FLAG = 4
CERT_INFO_NOT_BEFORE_FLAG = 5
CERT_INFO_NOT_AFTER_FLAG = 6
CERT_INFO_SUBJECT_FLAG = 7
CERT_INFO_SUBJECT_PUBLIC_KEY_INFO_FLAG = 8
CERT_INFO_ISSUER_UNIQUE_ID_FLAG = 9
CERT_INFO_SUBJECT_UNIQUE_ID_FLAG = 10
CERT_INFO_EXTENSION_FLAG = 11

/* dwFindType for CertFindCertificateInStore */
CERT_COMPARE_MASK = 0xFFFF
CERT_COMPARE_SHIFT = 16
CERT_COMPARE_ANY = 0
CERT_COMPARE_SHA1_HASH = 1
CERT_COMPARE_NAME = 2
CERT_COMPARE_ATTR = 3
CERT_COMPARE_MD5_HASH = 4
CERT_COMPARE_PROPERTY = 5
CERT_COMPARE_PUBLIC_KEY = 6
CERT_COMPARE_HASH = CERT_COMPARE_SHA1_HASH
CERT_COMPARE_NAME_STR_A = 7
CERT_COMPARE_NAME_STR_W = 8
CERT_COMPARE_KEY_SPEC = 9
CERT_COMPARE_ENHKEY_USAGE = 10
CERT_COMPARE_CTL_USAGE = CERT_COMPARE_ENHKEY_USAGE
CERT_COMPARE_SUBJECT_CERT = 11
CERT_COMPARE_ISSUER_OF = 12
CERT_COMPARE_EXISTING = 13
CERT_COMPARE_SIGNATURE_HASH = 14
CERT_COMPARE_KEY_IDENTIFIER = 15
CERT_COMPARE_CERT_ID = 16
CERT_COMPARE_CROSS_CERT_DIST_POINTS = 17
CERT_COMPARE_PUBKEY_MD5_HASH = 18
CERT_COMPARE_SUBJECT_INFO_ACCESS = 19
CERT_COMPARE_HASH_STR = 20
CERT_COMPARE_HAS_PRIVATE_KEY = 21
CERT_FIND_ANY = (CERT_COMPARE_ANY << CERT_COMPARE_SHIFT)
CERT_FIND_SHA1_HASH = (CERT_COMPARE_SHA1_HASH << CERT_COMPARE_SHIFT)
CERT_FIND_MD5_HASH = (CERT_COMPARE_MD5_HASH << CERT_COMPARE_SHIFT)
CERT_FIND_SIGNATURE_HASH = (CERT_COMPARE_SIGNATURE_HASH << CERT_COMPARE_SHIFT)
CERT_FIND_KEY_IDENTIFIER = (CERT_COMPARE_KEY_IDENTIFIER << CERT_COMPARE_SHIFT)
CERT_FIND_HASH = CERT_FIND_SHA1_HASH
CERT_FIND_PROPERTY = (CERT_COMPARE_PROPERTY << CERT_COMPARE_SHIFT)
CERT_FIND_PUBLIC_KEY = (CERT_COMPARE_PUBLIC_KEY << CERT_COMPARE_SHIFT)
CERT_FIND_SUBJECT_NAME = (CERT_COMPARE_NAME<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
CERT_FIND_SUBJECT_ATTR = (CERT_COMPARE_ATTR<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
CERT_FIND_ISSUER_NAME = (CERT_COMPARE_NAME<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
CERT_FIND_ISSUER_ATTR = (CERT_COMPARE_ATTR<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
CERT_FIND_SUBJECT_STR_A = (CERT_COMPARE_NAME_STR_A<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
CERT_FIND_SUBJECT_STR_W = (CERT_COMPARE_NAME_STR_W<<CERT_COMPARE_SHIFT | CERT_INFO_SUBJECT_FLAG)
CERT_FIND_SUBJECT_STR = CERT_FIND_SUBJECT_STR_W
CERT_FIND_ISSUER_STR_A = (CERT_COMPARE_NAME_STR_A<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
CERT_FIND_ISSUER_STR_W = (CERT_COMPARE_NAME_STR_W<<CERT_COMPARE_SHIFT | CERT_INFO_ISSUER_FLAG)
CERT_FIND_ISSUER_STR = CERT_FIND_ISSUER_STR_W
CERT_FIND_KEY_SPEC = (CERT_COMPARE_KEY_SPEC << CERT_COMPARE_SHIFT)
CERT_FIND_ENHKEY_USAGE = (CERT_COMPARE_ENHKEY_USAGE << CERT_COMPARE_SHIFT)
CERT_FIND_CTL_USAGE = CERT_FIND_ENHKEY_USAGE
CERT_FIND_SUBJECT_CERT = (CERT_COMPARE_SUBJECT_CERT << CERT_COMPARE_SHIFT)
CERT_FIND_ISSUER_OF = (CERT_COMPARE_ISSUER_OF << CERT_COMPARE_SHIFT)
CERT_FIND_EXISTING = (CERT_COMPARE_EXISTING << CERT_COMPARE_SHIFT)
CERT_FIND_CERT_ID = (CERT_COMPARE_CERT_ID << CERT_COMPARE_SHIFT)
CERT_FIND_CROSS_CERT_DIST_POINTS = (CERT_COMPARE_CROSS_CERT_DIST_POINTS << CERT_COMPARE_SHIFT)
CERT_FIND_PUBKEY_MD5_HASH = (CERT_COMPARE_PUBKEY_MD5_HASH << CERT_COMPARE_SHIFT)
CERT_FIND_SUBJECT_INFO_ACCESS = (CERT_COMPARE_SUBJECT_INFO_ACCESS << CERT_COMPARE_SHIFT)
CERT_FIND_HASH_STR = (CERT_COMPARE_HASH_STR << CERT_COMPARE_SHIFT)
CERT_FIND_HAS_PRIVATE_KEY = (CERT_COMPARE_HAS_PRIVATE_KEY << CERT_COMPARE_SHIFT)
CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG = 0x1
CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG = 0x2
CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG = 0x4
CERT_FIND_NO_ENHKEY_USAGE_FLAG = 0x8
CERT_FIND_OR_ENHKEY_USAGE_FLAG = 0x10
CERT_FIND_VALID_ENHKEY_USAGE_FLAG = 0x20
CERT_FIND_OPTIONAL_CTL_USAGE_FLAG = CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG
CERT_FIND_EXT_ONLY_CTL_USAGE_FLAG = CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG
CERT_FIND_PROP_ONLY_CTL_USAGE_FLAG = CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG
CERT_FIND_NO_CTL_USAGE_FLAG = CERT_FIND_NO_ENHKEY_USAGE_FLAG
CERT_FIND_OR_CTL_USAGE_FLAG = CERT_FIND_OR_ENHKEY_USAGE_FLAG
CERT_FIND_VALID_CTL_USAGE_FLAG = CERT_FIND_VALID_ENHKEY_USAGE_FLAG

/* policyOID values for CertVerifyCertificateChainPolicy function */
CERT_CHAIN_POLICY_BASE = 1
CERT_CHAIN_POLICY_AUTHENTICODE = 2
Expand All @@ -423,6 +523,17 @@ const (
CERT_CHAIN_POLICY_EV = 8
CERT_CHAIN_POLICY_SSL_F12 = 9

/* flag for dwFindType CertFindChainInStore */
CERT_CHAIN_FIND_BY_ISSUER = 1

/* dwFindFlags for CertFindChainInStore when dwFindType == CERT_CHAIN_FIND_BY_ISSUER */
CERT_CHAIN_FIND_BY_ISSUER_COMPARE_KEY_FLAG = 0x0001
CERT_CHAIN_FIND_BY_ISSUER_COMPLEX_CHAIN_FLAG = 0x0002
CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG = 0x0004
CERT_CHAIN_FIND_BY_ISSUER_LOCAL_MACHINE_FLAG = 0x0008
CERT_CHAIN_FIND_BY_ISSUER_NO_KEY_FLAG = 0x4000
CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG = 0x8000

/* Certificate Store close flags */
CERT_CLOSE_STORE_FORCE_FLAG = 0x00000001
CERT_CLOSE_STORE_CHECK_FLAG = 0x00000002
Expand Down Expand Up @@ -1360,6 +1471,19 @@ type CryptProtectPromptStruct struct {
Prompt *uint16
}

type CertChainFindByIssuerPara struct {
Size uint32
UsageIdentifier *byte
KeySpec uint32
AcquirePrivateKeyFlags uint32
IssuerCount uint32
Issuer Pointer
FindCallback Pointer
FindArg Pointer
IssuerChainIndex *uint32
IssuerElementIndex *uint32
}

type WinTrustData struct {
Size uint32
PolicyCallbackData uintptr
Expand Down
34 changes: 34 additions & 0 deletions windows/zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3351caf

Please sign in to comment.