in source/windows/windows_pki_utils.c [24:146]
int aws_load_cert_from_system_cert_store(const char *cert_path, HCERTSTORE *cert_store, PCCERT_CONTEXT *certs) {
AWS_LOGF_INFO(AWS_LS_IO_PKI, "static: loading certificate at windows cert manager path %s.", cert_path);
char *location_of_next_segment = strchr(cert_path, '\\');
if (!location_of_next_segment) {
AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: invalid certificate path %s.", cert_path);
return aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
}
size_t store_name_len = location_of_next_segment - cert_path;
DWORD store_val = 0;
if (!strncmp(cert_path, "CurrentUser", store_name_len)) {
store_val = CERT_SYSTEM_STORE_CURRENT_USER;
} else if (!strncmp(cert_path, "LocalMachine", store_name_len)) {
store_val = CERT_SYSTEM_STORE_LOCAL_MACHINE;
} else if (!strncmp(cert_path, "CurrentService", store_name_len)) {
store_val = CERT_SYSTEM_STORE_CURRENT_SERVICE;
} else if (!strncmp(cert_path, "Services", store_name_len)) {
store_val = CERT_SYSTEM_STORE_SERVICES;
} else if (!strncmp(cert_path, "Users", store_name_len)) {
store_val = CERT_SYSTEM_STORE_USERS;
} else if (!strncmp(cert_path, "CurrentUserGroupPolicy", store_name_len)) {
store_val = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY;
} else if (!strncmp(cert_path, "LocalMachineGroupPolicy", store_name_len)) {
store_val = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY;
} else if (!strncmp(cert_path, "LocalMachineEnterprise", store_name_len)) {
store_val = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE;
} else {
AWS_LOGF_ERROR(
AWS_LS_IO_PKI, "static: certificate path %s does not contain a valid cert store identifier.", cert_path);
return aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
}
AWS_LOGF_DEBUG(AWS_LS_IO_PKI, "static: determined registry value for lookup as %d.", (int)store_val);
location_of_next_segment += 1;
char *store_path_start = location_of_next_segment;
location_of_next_segment = strchr(location_of_next_segment, '\\');
if (!location_of_next_segment) {
AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: invalid certificate path %s.", cert_path);
return aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
}
/* The store_val value has to be only the path segment related to the physical store. Looking
at the docs, 128 bytes should be plenty to store that segment.
https://docs.microsoft.com/en-us/windows/desktop/SecCrypto/system-store-locations */
char store_path[128] = {0};
AWS_FATAL_ASSERT(location_of_next_segment - store_path_start < sizeof(store_path));
memcpy(store_path, store_path_start, location_of_next_segment - store_path_start);
location_of_next_segment += 1;
if (strlen(location_of_next_segment) != CERT_HASH_STR_LEN) {
AWS_LOGF_ERROR(
AWS_LS_IO_PKI,
"static: invalid certificate path %s. %s should have been"
" 40 bytes of hex encoded data",
cert_path,
location_of_next_segment);
return aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
}
*cert_store = CertOpenStore(
CERT_STORE_PROV_SYSTEM_A, 0, (HCRYPTPROV)NULL, CERT_STORE_OPEN_EXISTING_FLAG | store_val, store_path);
if (!*cert_store) {
AWS_LOGF_ERROR(
AWS_LS_IO_PKI,
"static: invalid certificate path %s. Failed to load cert store with error code %d",
cert_path,
(int)GetLastError());
return aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
}
BYTE cert_hash_data[CERT_HASH_LEN];
CRYPT_HASH_BLOB cert_hash = {
.pbData = cert_hash_data,
.cbData = CERT_HASH_LEN,
};
if (!CryptStringToBinaryA(
location_of_next_segment,
CERT_HASH_STR_LEN,
CRYPT_STRING_HEX,
cert_hash.pbData,
&cert_hash.cbData,
NULL,
NULL)) {
AWS_LOGF_ERROR(
AWS_LS_IO_PKI,
"static: invalid certificate path %s. %s should have been a hex encoded string",
cert_path,
location_of_next_segment);
aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
goto on_error;
}
*certs = CertFindCertificateInStore(
*cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_HASH, &cert_hash, NULL);
if (!*certs) {
AWS_LOGF_ERROR(
AWS_LS_IO_PKI,
"static: invalid certificate path %s. "
"The referenced certificate was not found in the certificate store, error code %d",
cert_path,
(int)GetLastError());
aws_raise_error(AWS_ERROR_FILE_INVALID_PATH);
goto on_error;
}
return AWS_OP_SUCCESS;
on_error:
if (*cert_store != NULL) {
aws_close_cert_store(*cert_store);
*cert_store = NULL;
}
return AWS_OP_ERR;
}