Merge pull request #9242 from shiftkey/certificate-addition-windows
certificate trust API for Windows
This commit is contained in:
commit
c59fab0179
4 changed files with 111 additions and 6 deletions
|
@ -129,7 +129,7 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||||
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
dict.SetMethod("showErrorBox", &atom::ShowErrorBox);
|
||||||
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
|
dict.SetMethod("showOpenDialog", &ShowOpenDialog);
|
||||||
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
|
dict.SetMethod("showSaveDialog", &ShowSaveDialog);
|
||||||
#if defined(OS_MACOSX)
|
#if defined(OS_MACOSX) || defined(OS_WIN)
|
||||||
dict.SetMethod("showCertificateTrustDialog",
|
dict.SetMethod("showCertificateTrustDialog",
|
||||||
&certificate_trust::ShowCertificateTrust);
|
&certificate_trust::ShowCertificateTrust);
|
||||||
#endif
|
#endif
|
||||||
|
|
98
atom/browser/ui/certificate_trust_win.cc
Normal file
98
atom/browser/ui/certificate_trust_win.cc
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// Copyright (c) 2017 GitHub, Inc.
|
||||||
|
// Use of this source code is governed by the MIT license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "atom/browser/ui/certificate_trust.h"
|
||||||
|
|
||||||
|
#include <wincrypt.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "base/callback.h"
|
||||||
|
#include "net/cert/cert_database.h"
|
||||||
|
|
||||||
|
namespace certificate_trust {
|
||||||
|
|
||||||
|
// Add the provided certificate to the Trusted Root Certificate Authorities
|
||||||
|
// store for the current user.
|
||||||
|
//
|
||||||
|
// This requires prompting the user to confirm they trust the certificate.
|
||||||
|
BOOL AddToTrustedRootStore(const PCCERT_CONTEXT cert_context,
|
||||||
|
const scoped_refptr<net::X509Certificate>& cert) {
|
||||||
|
auto root_cert_store = CertOpenStore(
|
||||||
|
CERT_STORE_PROV_SYSTEM,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
CERT_SYSTEM_STORE_CURRENT_USER,
|
||||||
|
L"Root");
|
||||||
|
|
||||||
|
if (root_cert_store == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = CertAddCertificateContextToStore(
|
||||||
|
root_cert_store,
|
||||||
|
cert_context,
|
||||||
|
CERT_STORE_ADD_REPLACE_EXISTING,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
// force Chromium to reload it's database for this certificate
|
||||||
|
auto cert_db = net::CertDatabase::GetInstance();
|
||||||
|
cert_db->NotifyObserversCertDBChanged(cert.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
CertCloseStore(root_cert_store, CERT_CLOSE_STORE_FORCE_FLAG);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CERT_CHAIN_PARA GetCertificateChainParameters() {
|
||||||
|
CERT_ENHKEY_USAGE enhkey_usage;
|
||||||
|
enhkey_usage.cUsageIdentifier = 0;
|
||||||
|
enhkey_usage.rgpszUsageIdentifier = NULL;
|
||||||
|
|
||||||
|
CERT_USAGE_MATCH cert_usage;
|
||||||
|
// ensure the rules are applied to the entire chain
|
||||||
|
cert_usage.dwType = USAGE_MATCH_TYPE_AND;
|
||||||
|
cert_usage.Usage = enhkey_usage;
|
||||||
|
|
||||||
|
CERT_CHAIN_PARA params = { sizeof(CERT_CHAIN_PARA) };
|
||||||
|
params.RequestedUsage = cert_usage;
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowCertificateTrust(atom::NativeWindow* parent_window,
|
||||||
|
const scoped_refptr<net::X509Certificate>& cert,
|
||||||
|
const std::string& message,
|
||||||
|
const ShowTrustCallback& callback) {
|
||||||
|
PCCERT_CHAIN_CONTEXT chain_context;
|
||||||
|
|
||||||
|
auto cert_context = cert->CreateOSCertChainForCert();
|
||||||
|
|
||||||
|
auto params = GetCertificateChainParameters();
|
||||||
|
|
||||||
|
if (CertGetCertificateChain(NULL,
|
||||||
|
cert_context,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
¶ms,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&chain_context)) {
|
||||||
|
auto error_status = chain_context->TrustStatus.dwErrorStatus;
|
||||||
|
if (error_status == CERT_TRUST_IS_SELF_SIGNED ||
|
||||||
|
error_status == CERT_TRUST_IS_UNTRUSTED_ROOT) {
|
||||||
|
// these are the only scenarios we're interested in supporting
|
||||||
|
AddToTrustedRootStore(cert_context, cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
CertFreeCertificateChain(chain_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
CertFreeCertificateContext(cert_context);
|
||||||
|
|
||||||
|
callback.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace certificate_trust
|
|
@ -176,7 +176,7 @@ it is usually used to report errors in early stage of startup. If called
|
||||||
before the app `ready`event on Linux, the message will be emitted to stderr,
|
before the app `ready`event on Linux, the message will be emitted to stderr,
|
||||||
and no GUI dialog will appear.
|
and no GUI dialog will appear.
|
||||||
|
|
||||||
### `dialog.showCertificateTrustDialog([browserWindow, ]options, callback)` _macOS_
|
### `dialog.showCertificateTrustDialog([browserWindow, ]options, callback)` _macOS_ _Windows_
|
||||||
|
|
||||||
* `browserWindow` BrowserWindow (optional)
|
* `browserWindow` BrowserWindow (optional)
|
||||||
* `options` Object
|
* `options` Object
|
||||||
|
@ -184,11 +184,17 @@ and no GUI dialog will appear.
|
||||||
* `message` String - The message to display to the user.
|
* `message` String - The message to display to the user.
|
||||||
* `callback` Function
|
* `callback` Function
|
||||||
|
|
||||||
Displays a modal dialog that shows a message and certificate information, and
|
On macOS, this displays a modal dialog that shows a message and certificate
|
||||||
gives the user the option of trusting/importing the certificate.
|
information, and gives the user the option of trusting/importing the
|
||||||
|
certificate. If you provide a `browserWindow` argument the dialog will be
|
||||||
|
attached to the parent window, making it modal.
|
||||||
|
|
||||||
The `browserWindow` argument allows the dialog to attach itself to a parent
|
On Windows the options are more limited, due to the Win32 APIs used:
|
||||||
window, making it modal.
|
|
||||||
|
- The `message` argument is not used, as the OS provides its own confirmation
|
||||||
|
dialog.
|
||||||
|
- The `browserWindow` argument is ignored since it is not possible to make
|
||||||
|
this confirmation dialog modal.
|
||||||
|
|
||||||
## Sheets
|
## Sheets
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,7 @@
|
||||||
'atom/browser/ui/atom_menu_model.h',
|
'atom/browser/ui/atom_menu_model.h',
|
||||||
'atom/browser/ui/certificate_trust.h',
|
'atom/browser/ui/certificate_trust.h',
|
||||||
'atom/browser/ui/certificate_trust_mac.mm',
|
'atom/browser/ui/certificate_trust_mac.mm',
|
||||||
|
'atom/browser/ui/certificate_trust_win.cc',
|
||||||
'atom/browser/ui/cocoa/atom_menu_controller.h',
|
'atom/browser/ui/cocoa/atom_menu_controller.h',
|
||||||
'atom/browser/ui/cocoa/atom_menu_controller.mm',
|
'atom/browser/ui/cocoa/atom_menu_controller.mm',
|
||||||
'atom/browser/ui/cocoa/atom_touch_bar.h',
|
'atom/browser/ui/cocoa/atom_touch_bar.h',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue