Skip to content

Commit

Permalink
[io/ssl/win] Look for certificates in local machine store as well cur…
Browse files Browse the repository at this point in the history
…rent user store.

Add certificates from "ca", "trust" and "my" stores in addition to "root".
Improve certificate tracing: print certificates as they are added.
Clean up error logging.

Fixes #45909

TEST=remove certs from current user store, see requests fail to connect, add cert to local machine store, confirm connection works.

Change-Id: Ied234098d56b406c9868602a2b806786ae3740be
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/198241
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
  • Loading branch information
aam authored and commit-bot@chromium.org committed May 6, 2021
1 parent 1f55b7c commit 8564fd0
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 16 deletions.
4 changes: 2 additions & 2 deletions runtime/bin/secure_socket_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ void SecureSocketUtils::CheckStatusSSL(int status,
}
if (SSL_LOG_STATUS) {
int error = ERR_get_error();
Syslog::PrintErr("Failed: %s status %d", message, status);
Syslog::PrintErr("Failed: %s status: %d ", message, status);
char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE];
ERR_error_string_n(error, error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE);
Syslog::PrintErr("ERROR: %d %s\n", error, error_string);
Syslog::PrintErr("%s\n", error_string);
}
SecureSocketUtils::ThrowIOException(status, type, message, ssl);
}
Expand Down
99 changes: 85 additions & 14 deletions runtime/bin/security_context_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,35 @@ static void PrintSSLErr(const char* str) {
char error_string[SecureSocketUtils::SSL_ERROR_MESSAGE_BUFFER_SIZE];
ERR_error_string_n(error, error_string,
SecureSocketUtils::SSL_ERROR_MESSAGE_BUFFER_SIZE);
Syslog::PrintErr("%s ERROR: %d %s\n", str, error, error_string);
Syslog::PrintErr("%s %s\n", str, error_string);
}

// Add certificates from Windows trusted root store.
static bool AddCertificatesFromRootStore(X509_STORE* store) {
// The UWP platform doesn't support CertEnumCertificatesInStore hence
// this function cannot work when compiled in UWP mode.
#ifdef TARGET_OS_WINDOWS_UWP
return false;
#else
// Open root system store.
// Note that only current user certificates are accessible using this method,
// not the local machine store.
HCERTSTORE cert_store = CertOpenSystemStore(NULL, L"ROOT");
#ifndef TARGET_OS_WINDOWS_UWP
static bool AddCertificatesFromNamedSystemStore(const wchar_t* name,
DWORD store_type,
X509_STORE* store) {
ASSERT(store_type == CERT_SYSTEM_STORE_CURRENT_USER ||
store_type == CERT_SYSTEM_STORE_LOCAL_MACHINE);

if (SSL_LOG_STATUS) {
Syslog::Print("AddCertificatesFromNamedSystemStore %ls type: %s\n", name,
store_type == CERT_SYSTEM_STORE_CURRENT_USER
? "Current User"
: "Local Machine");
}

HCERTSTORE cert_store =
CertOpenStore(CERT_STORE_PROV_SYSTEM,
0, // the encoding type is not needed
NULL, // use the default HCRYPTPROV
store_type | CERT_STORE_READONLY_FLAG, name);

if (cert_store == NULL) {
if (SSL_LOG_STATUS) {
DWORD error = GetLastError();
Syslog::PrintErr("Failed to open Windows root store due to %d\n", error);
Syslog::PrintErr(
"Failed to open Windows root store %ls type %d due to %d\n", name,
store_type, error);
}
return false;
}
Expand Down Expand Up @@ -84,10 +95,34 @@ static bool AddCertificatesFromRootStore(X509_STORE* store) {
continue;
}
BIO_free(root_cert_bio);

if (SSL_LOG_STATUS) {
auto s_name = X509_get_subject_name(root_cert);
auto s_issuer_name = X509_get_issuer_name(root_cert);
auto serial_number = X509_get_serialNumber(root_cert);
BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, nullptr);
char* hex = BN_bn2hex(bn);
Syslog::Print("Considering root certificate serial: %s subject name: ",
hex);
OPENSSL_free(hex);
X509_NAME_print_ex_fp(stdout, s_name, 4, 0);
Syslog::Print(" issuer:");
X509_NAME_print_ex_fp(stdout, s_issuer_name, 4, 0);
Syslog::Print("\n");
}

int status = X509_STORE_add_cert(store, root_cert);
if (status == 0) {
int error = ERR_get_error();
if (ERR_GET_REASON(error) == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
if (SSL_LOG_STATUS) {
Syslog::Print("...duplicate\n");
}
X509_free(root_cert);
continue;
}
if (SSL_LOG_STATUS) {
PrintSSLErr("Fail to add certificate to trust store");
PrintSSLErr("Failed to add certificate to x509 trust store");
}
X509_free(root_cert);
CertFreeCertificateContext(cert_context);
Expand All @@ -104,6 +139,42 @@ static bool AddCertificatesFromRootStore(X509_STORE* store) {
}
return false;
}
return true;
}

static bool AddCertificatesFromSystemStore(DWORD store_type,
X509_STORE* store) {
if (!AddCertificatesFromNamedSystemStore(L"ROOT", store_type, store)) {
return false;
}
if (!AddCertificatesFromNamedSystemStore(L"CA", store_type, store)) {
return false;
}
if (!AddCertificatesFromNamedSystemStore(L"TRUST", store_type, store)) {
return false;
}
if (!AddCertificatesFromNamedSystemStore(L"MY", store_type, store)) {
return false;
}
return true;
}
#endif // ifdef TARGET_OS_WINDOWS_UWP

// Add certificates from Windows trusted root store.
static bool AddCertificatesFromRootStore(X509_STORE* store) {
// The UWP platform doesn't support CertEnumCertificatesInStore hence
// this function cannot work when compiled in UWP mode.
#ifdef TARGET_OS_WINDOWS_UWP
return false;
#else
if (!AddCertificatesFromSystemStore(CERT_SYSTEM_STORE_CURRENT_USER, store)) {
return false;
}

if (!AddCertificatesFromSystemStore(CERT_SYSTEM_STORE_LOCAL_MACHINE, store)) {
return false;
}

return true;
#endif // ifdef TARGET_OS_WINDOWS_UWP
}
Expand Down

0 comments on commit 8564fd0

Please sign in to comment.