Skip to content

Commit 0ae70b2

Browse files
committed
Added support for silent flag
1 parent c377b43 commit 0ae70b2

File tree

7 files changed

+40
-17
lines changed

7 files changed

+40
-17
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustls-cng"
3-
version = "0.5.3"
3+
version = "0.6.0"
44
authors = ["Dmitry Pankratov <[email protected]>"]
55
description = "Windows CNG API bridge for rustls"
66
license = "MIT/Apache-2.0"

examples/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fn get_chain(
3434
let context = contexts
3535
.first()
3636
.ok_or_else(|| anyhow::Error::msg("No client cert"))?;
37-
let key = context.acquire_key()?;
37+
let key = context.acquire_key(true)?;
3838
let signing_key = CngSigningKey::new(key)?;
3939
let chain = context
4040
.as_chain_der()?

examples/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl ResolvesServerCert for ServerCertResolver {
6363

6464
// attempt to acquire a private key and construct CngSigningKey
6565
let (context, key) = contexts.into_iter().find_map(|ctx| {
66-
let key = ctx.acquire_key().ok()?;
66+
let key = ctx.acquire_key(true).ok()?;
6767
if let Some(ref pin) = self.pin {
6868
key.set_pin(pin).ok()?;
6969
}

src/cert.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,15 @@ impl CertContext {
5757
unsafe { &*self.0.inner() }
5858
}
5959

60-
/// Attempt to silently acquire a CNG private key from this context.
61-
pub fn acquire_key(&self) -> Result<NCryptKey> {
60+
/// Attempt to acquire a CNG private key from this context.
61+
/// The `silent` parameter indicates whether to suppress the user prompts.
62+
pub fn acquire_key(&self, silent: bool) -> Result<NCryptKey> {
6263
let mut handle = HCRYPTPROV_OR_NCRYPT_KEY_HANDLE::default();
6364
let mut key_spec = CERT_KEY_SPEC::default();
64-
let flags = CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG | CRYPT_ACQUIRE_SILENT_FLAG;
65+
66+
let flags =
67+
if silent { CRYPT_ACQUIRE_SILENT_FLAG } else { 0 } | CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG;
68+
6569
unsafe {
6670
let result = CryptAcquireCertificatePrivateKey(
6771
self.inner(),
@@ -72,7 +76,9 @@ impl CertContext {
7276
ptr::null_mut(),
7377
) != 0;
7478
if result {
75-
Ok(NCryptKey::new_owned(handle))
79+
let mut key = NCryptKey::new_owned(handle);
80+
key.set_silent(silent);
81+
Ok(key)
7682
} else {
7783
Err(CngError::from_win32_error())
7884
}
@@ -137,7 +143,9 @@ impl CertContext {
137143

138144
for (index, element) in elements.iter().enumerate() {
139145
if index != 0 {
140-
if 0 != ((**element).TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) {
146+
if 0 != ((**element).TrustStatus.dwInfoStatus
147+
& CERT_TRUST_IS_SELF_SIGNED)
148+
{
141149
break;
142150
}
143151
}

src/key.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,31 @@ impl Drop for InnerKey {
6666

6767
/// CNG private key wrapper
6868
#[derive(Clone, Debug)]
69-
pub struct NCryptKey(Arc<InnerKey>);
69+
pub struct NCryptKey {
70+
inner: Arc<InnerKey>,
71+
silent: bool,
72+
}
7073

7174
impl NCryptKey {
7275
/// Create an owned instance which frees the underlying handle automatically
7376
pub fn new_owned(handle: NCRYPT_KEY_HANDLE) -> Self {
74-
NCryptKey(Arc::new(InnerKey::Owned(handle)))
77+
NCryptKey {
78+
inner: Arc::new(InnerKey::Owned(handle)),
79+
silent: true,
80+
}
7581
}
7682

7783
/// Create a borrowed instance which doesn't free the key handle
7884
pub fn new_borrowed(handle: NCRYPT_KEY_HANDLE) -> Self {
79-
NCryptKey(Arc::new(InnerKey::Borrowed(handle)))
85+
NCryptKey {
86+
inner: Arc::new(InnerKey::Borrowed(handle)),
87+
silent: true,
88+
}
8089
}
8190

8291
/// Return an inner CNG key handle
8392
pub fn inner(&self) -> NCRYPT_KEY_HANDLE {
84-
self.0.inner()
93+
self.inner.inner()
8594
}
8695

8796
fn get_string_property(&self, property: PCWSTR) -> Result<String> {
@@ -160,6 +169,11 @@ impl NCryptKey {
160169
CngError::from_hresult(result)
161170
}
162171

172+
/// Enable or disable silent key operations without prompting the user. The default value is 'true'.
173+
pub fn set_silent(&mut self, silent: bool) {
174+
self.silent = silent;
175+
}
176+
163177
/// Sign a given digest with this key. The `hash` slice must be 32, 48 or 64 bytes long.
164178
pub fn sign(&self, hash: &[u8], padding: SignaturePadding) -> Result<Vec<u8>> {
165179
unsafe {
@@ -189,6 +203,7 @@ impl NCryptKey {
189203
};
190204

191205
let mut result = 0;
206+
let dwflags = flag | if self.silent { NCRYPT_SILENT_FLAG } else { 0 };
192207

193208
CngError::from_hresult(NCryptSignHash(
194209
self.inner(),
@@ -198,7 +213,7 @@ impl NCryptKey {
198213
ptr::null_mut(),
199214
0,
200215
&mut result,
201-
NCRYPT_SILENT_FLAG | flag,
216+
dwflags,
202217
))?;
203218

204219
let mut signature = vec![0u8; result as usize];
@@ -211,7 +226,7 @@ impl NCryptKey {
211226
signature.as_mut_ptr(),
212227
signature.len() as u32,
213228
&mut result,
214-
NCRYPT_SILENT_FLAG | flag,
229+
dwflags,
215230
))?;
216231

217232
Ok(signature)

tests/test_client_server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ mod client {
2929
let context = contexts
3030
.first()
3131
.ok_or_else(|| anyhow::Error::msg("No client cert"))?;
32-
let key = context.acquire_key()?;
32+
let key = context.acquire_key(true)?;
3333
let signing_key = CngSigningKey::new(key)?;
3434
let chain = context
3535
.as_chain_der()?
@@ -123,7 +123,7 @@ mod server {
123123
let contexts = self.0.find_by_subject_str(name).ok()?;
124124

125125
let (context, key) = contexts.into_iter().find_map(|ctx| {
126-
let key = ctx.acquire_key().ok()?;
126+
let key = ctx.acquire_key(true).ok()?;
127127
CngSigningKey::new(key).ok().map(|key| (ctx, key))
128128
})?;
129129

tests/test_sign.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ fn test_sign() {
2828
SignatureScheme::ECDSA_NISTP384_SHA384,
2929
];
3030

31-
let key = context.acquire_key().unwrap();
31+
let key = context.acquire_key(true).unwrap();
3232
let signing_key = CngSigningKey::new(key).unwrap();
3333
assert_eq!(signing_key.algorithm(), SignatureAlgorithm::ECDSA);
3434
let signer = signing_key.choose_scheme(&offered).unwrap();

0 commit comments

Comments
 (0)