in google_guest_agent/agentcrypto/mtls_mds_windows.go [121:184]
func findCert(storeName, issuer, certID string) (*windows.CertContext, error) {
logger.Infof("Searching for certificate with serial number %s in store %s by issuer %s", certID, storeName, issuer)
storeNamePtr, err := syscall.UTF16PtrFromString(storeName)
if err != nil {
return nil, fmt.Errorf("UTF16PtrFromString(%s) failed with error: %v", storeName, err)
}
issuerPtr, err := syscall.UTF16PtrFromString(issuer)
if err != nil {
return nil, fmt.Errorf("UTF16PtrFromString(%s) failed with error: %v", issuer, err)
}
st, err := windows.CertOpenStore(
windows.CERT_STORE_PROV_SYSTEM,
0,
0,
windows.CERT_SYSTEM_STORE_LOCAL_MACHINE,
uintptr(unsafe.Pointer(storeNamePtr)))
if err != nil {
return nil, fmt.Errorf("failed to open cert store: %w", err)
}
defer windows.CertCloseStore(st, 0)
// prev is used for enumerating through all the certificates that matches the issuer.
// On the first call to the function this parameter is NULL on all subsequent calls,
// this parameter is the last CertContext pointer returned by the CertFindCertificateInStore function
var prev *windows.CertContext
// maxCertEnumeration would avoid requiring a infinite loop that relies on enumerating
// until we get nil crt.
for i := 1; i <= maxCertEnumeration; i++ {
logger.Debugf("Attempt %d, searching certificate...", i)
// https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certfindcertificateinstore
crt, err := windows.CertFindCertificateInStore(
st,
windows.X509_ASN_ENCODING|windows.PKCS_7_ASN_ENCODING,
0,
windows.CERT_FIND_ISSUER_STR,
unsafe.Pointer(issuerPtr),
prev)
if err != nil {
return nil, fmt.Errorf("unable to find certificate: %w", err)
}
if crt == nil {
return nil, fmt.Errorf("no certificate by issuer %s with ID %s", issuer, certID)
}
x509Cert, err := certContextToX509(crt)
if err != nil {
return nil, fmt.Errorf("failed to parse certificate context: %w", err)
}
if fmt.Sprintf("%x", x509Cert.SerialNumber) == certID {
return crt, nil
}
prev = crt
}
return nil, nil
}