Skip to content

Commit c40afb7

Browse files
committed
Simplified examples
1 parent 57131b0 commit c40afb7

File tree

4 files changed

+32
-162
lines changed

4 files changed

+32
-162
lines changed

Cargo.lock

Lines changed: 3 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ bitflags = "2"
2323
windows-sys = { version = "0.61", features = ["Win32_Foundation", "Win32_Security_Cryptography"] }
2424

2525
[dev-dependencies]
26-
clap = { version = "4", default-features = false, features = ["std", "derive", "help"] }
2726
rustls-aws-lc-rs = { git = "https://github.com/rustls/rustls.git" }
2827
rustls-util = { git = "https://github.com/rustls/rustls.git" }
2928
rustls-native-certs = "0.8"

examples/client.rs

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ use std::{
22
hash::Hasher,
33
io::{Read, Write},
44
net::{Shutdown, TcpStream},
5-
path::PathBuf,
65
sync::Arc,
76
};
87

9-
use clap::Parser;
108
use rustls::{
119
ClientConfig, RootCertStore,
1210
client::{ClientCredentialResolver, CredentialRequest},
@@ -16,7 +14,7 @@ use rustls::{
1614
};
1715
use rustls_cng::{
1816
signer::CngSigningKey,
19-
store::{CertStore, CertStoreType, Pkcs12Flags},
17+
store::{CertStore, CertStoreType},
2018
};
2119
use rustls_util::Stream;
2220

@@ -26,7 +24,6 @@ const PORT: u16 = 8000;
2624
pub struct ClientCertResolver {
2725
store: CertStore,
2826
cert_name: String,
29-
pin: Option<String>,
3027
}
3128

3229
fn get_chain(
@@ -37,7 +34,7 @@ fn get_chain(
3734
let context = contexts
3835
.first()
3936
.ok_or_else(|| std::io::Error::other("No client cert"))?;
40-
let key = context.acquire_key(true)?;
37+
let key = context.acquire_key(false)?;
4138
let signing_key = CngSigningKey::new(key)?;
4239
let chain = context.as_chain_der()?.into_iter().map(Into::into).collect();
4340
Ok((chain, signing_key))
@@ -47,9 +44,6 @@ impl ClientCredentialResolver for ClientCertResolver {
4744
fn resolve(&self, server_hello: &CredentialRequest) -> Option<SelectedCredential> {
4845
println!("Server sig schemes: {:?}", server_hello.signature_schemes());
4946
let (chain, signing_key) = get_chain(&self.store, &self.cert_name).ok()?;
50-
if let Some(ref pin) = self.pin {
51-
signing_key.key().set_pin(pin).ok()?;
52-
}
5347
Credentials::new_unchecked(Arc::new(Identity::from_cert_chain(chain).ok()?), Box::new(signing_key))
5448
.signer(server_hello.signature_schemes())
5549
}
@@ -61,69 +55,34 @@ impl ClientCredentialResolver for ClientCertResolver {
6155
fn hash_config(&self, _: &mut dyn Hasher) {}
6256
}
6357

64-
#[derive(Parser)]
65-
#[clap(name = "rustls-client-sample")]
66-
struct AppParams {
67-
#[clap(short = 'c', long = "ca-cert", help = "CA cert name to verify the peer certificate")]
68-
ca_cert: Option<String>,
69-
70-
#[clap(short = 'k', long = "keystore", help = "Use external PFX keystore")]
71-
keystore: Option<PathBuf>,
72-
73-
#[clap(short = 'p', long = "password", help = "Keystore password or token pin")]
74-
password: Option<String>,
75-
76-
#[clap(short = 's', long = "server-name", help = "Server name for TLS SNI extension")]
77-
server_name: Option<String>,
78-
79-
#[clap(short = 'l', long = "client-cert", help = "Client cert name for client auth")]
80-
client_cert: Option<String>,
81-
82-
#[clap(help = "Server address")]
83-
server_address: String,
84-
}
85-
8658
fn main() -> Result<(), Box<dyn std::error::Error>> {
87-
let params: AppParams = AppParams::parse();
88-
89-
let store = if let Some(ref keystore) = params.keystore {
90-
let data = std::fs::read(keystore)?;
91-
CertStore::from_pkcs12(
92-
&data,
93-
params.password.as_deref().unwrap_or_default(),
94-
Pkcs12Flags::default(),
95-
)?
96-
} else {
97-
CertStore::open(CertStoreType::CurrentUser, "my")?
98-
};
59+
let args = std::env::args().collect::<Vec<_>>();
60+
if args.len() < 2 {
61+
println!("Usage: {} <sni-name> [client-cert-name]", args[0]);
62+
return Ok(());
63+
}
64+
65+
let store = CertStore::open(CertStoreType::CurrentUser, "my")?;
9966

10067
let mut root_store = RootCertStore::empty();
10168
root_store.add_parsable_certificates(rustls_native_certs::load_native_certs().certs);
10269

103-
if let Some(ca_cert) = params.ca_cert {
104-
let ca_cert_context = store.find_by_subject_str(&ca_cert)?;
105-
let ca_cert = ca_cert_context.first().unwrap();
106-
107-
root_store.add(ca_cert.as_der().into())?;
108-
}
109-
11070
let builder =
11171
ClientConfig::builder(Arc::new(rustls_aws_lc_rs::DEFAULT_PROVIDER)).with_root_certificates(root_store);
11272

113-
let client_config = Arc::new(if let Some(client_cert) = params.client_cert {
73+
let client_config = Arc::new(if let Some(client_cert) = args.get(2) {
11474
builder.with_client_credential_resolver(Arc::new(ClientCertResolver {
11575
store,
11676
cert_name: client_cert.clone(),
117-
pin: params.password.clone(),
11877
}))?
11978
} else {
12079
builder.with_no_client_auth()?
12180
});
12281

123-
let server_name = ServerName::try_from(params.server_name.as_deref().unwrap_or(&params.server_address))?.to_owned();
82+
let server_name = ServerName::try_from(args[1].as_str())?.to_owned();
12483

12584
let mut connection = client_config.connect(server_name).build()?;
126-
let mut client = TcpStream::connect(format!("{}:{}", params.server_address, PORT))?;
85+
let mut client = TcpStream::connect(format!("127.0.0.1:{}", PORT))?;
12786

12887
let mut tls_stream = Stream::new(&mut connection, &mut client);
12988
tls_stream.write_all(b"ping")?;

examples/server.rs

Lines changed: 17 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,64 @@
11
use std::{
22
io::{Read, Write},
33
net::{Shutdown, TcpListener, TcpStream},
4-
path::PathBuf,
54
sync::Arc,
65
};
76

8-
use clap::Parser;
97
use rustls::{
108
RootCertStore, ServerConfig, ServerConnection,
119
crypto::{Credentials, Identity, SelectedCredential},
1210
server::{ClientHello, ServerCredentialResolver, WebPkiClientVerifier},
1311
};
1412
use rustls_cng::{
1513
signer::CngSigningKey,
16-
store::{CertStore, CertStoreType, Pkcs12Flags},
14+
store::{CertStore, CertStoreType},
1715
};
1816
use rustls_util::Stream;
1917

2018
const PORT: u16 = 8000;
2119

22-
#[derive(Parser)]
23-
#[clap(name = "rustls-server-sample")]
24-
struct AppParams {
25-
#[clap(
26-
action,
27-
short = 'c',
28-
long = "ca-cert",
29-
help = "CA cert name to verify the peer certificate"
30-
)]
31-
ca_cert: Option<String>,
32-
33-
#[clap(action, short = 'k', long = "keystore", help = "Use external PFX keystore")]
34-
keystore: Option<PathBuf>,
35-
36-
#[clap(action, short = 'p', long = "password", help = "Keystore password or card pin")]
37-
password: Option<String>,
38-
}
39-
4020
#[derive(Debug)]
4121
pub struct ServerCertResolver {
4222
store: CertStore,
43-
pin: Option<String>,
4423
}
4524

4625
impl ServerCredentialResolver for ServerCertResolver {
4726
fn resolve(&self, client_hello: &ClientHello) -> Result<SelectedCredential, rustls::Error> {
4827
println!("Client hello server name: {:?}", client_hello.server_name());
4928
let name = client_hello
5029
.server_name()
51-
.ok_or_else(|| rustls::Error::NoSuitableCertificate)?;
30+
.ok_or_else(|| rustls::Error::NoSuitableCertificate)
31+
.inspect_err(|e| println!("{}", e))?;
5232

5333
let contexts = self
5434
.store
5535
.find_by_subject_str(name)
56-
.map_err(|_| rustls::Error::NoSuitableCertificate)?;
36+
.map_err(|_| rustls::Error::NoSuitableCertificate)
37+
.inspect_err(|e| println!("{}", e))?;
5738

5839
let (context, key) = contexts
5940
.into_iter()
6041
.find_map(|ctx| {
61-
let key = ctx.acquire_key(true).ok()?;
62-
if let Some(ref pin) = self.pin {
63-
key.set_pin(pin).ok()?;
64-
}
42+
let key = ctx.acquire_key(false).ok()?;
6543
CngSigningKey::new(key).ok().map(|key| (ctx, key))
6644
})
67-
.ok_or_else(|| rustls::Error::NoSuitableCertificate)?;
45+
.ok_or_else(|| rustls::Error::NoSuitableCertificate)
46+
.inspect_err(|e| println!("{}", e))?;
6847

6948
println!("Key alg group: {:?}", key.key().algorithm_group());
7049
println!("Key alg: {:?}", key.key().algorithm());
7150

7251
let chain = context
7352
.as_chain_der()
74-
.map_err(|_| rustls::Error::NoSuitableCertificate)?;
53+
.map_err(|_| rustls::Error::NoSuitableCertificate)
54+
.inspect_err(|e| println!("{}", e))?;
55+
7556
let certs = chain.into_iter().map(Into::into).collect();
7657

7758
Credentials::new_unchecked(Arc::new(Identity::from_cert_chain(certs)?), Box::new(key))
7859
.signer(client_hello.signature_schemes())
7960
.ok_or_else(|| rustls::Error::General("No common schemes".to_owned()))
61+
.inspect_err(|e| println!("{}", e))
8062
}
8163
}
8264

@@ -113,39 +95,20 @@ fn accept(server: TcpListener, config: Arc<ServerConfig>) -> Result<(), Box<dyn
11395
}
11496

11597
fn main() -> Result<(), Box<dyn std::error::Error>> {
116-
let params: AppParams = AppParams::parse();
117-
118-
let store = if let Some(ref keystore) = params.keystore {
119-
let data = std::fs::read(keystore)?;
120-
CertStore::from_pkcs12(
121-
&data,
122-
params.password.as_deref().unwrap_or_default(),
123-
Pkcs12Flags::default(),
124-
)?
125-
} else {
126-
CertStore::open(CertStoreType::CurrentUser, "my")?
127-
};
98+
let store = CertStore::open(CertStoreType::CurrentUser, "my")?;
12899

129100
let mut root_store = RootCertStore::empty();
130101
root_store.add_parsable_certificates(rustls_native_certs::load_native_certs().certs);
131102

132-
if let Some(ca_cert) = params.ca_cert {
133-
let ca_cert_context = store.find_by_subject_str(&ca_cert)?;
134-
let ca_cert = ca_cert_context.first().unwrap();
135-
136-
root_store.add(ca_cert.as_der().into())?;
137-
}
138-
139103
let verifier = WebPkiClientVerifier::builder(Arc::new(root_store), &rustls_aws_lc_rs::DEFAULT_PROVIDER).build()?;
140104

141105
let server_config = ServerConfig::builder(Arc::new(rustls_aws_lc_rs::DEFAULT_PROVIDER))
142106
.with_client_cert_verifier(Arc::new(verifier))
143-
.with_server_credential_resolver(Arc::new(ServerCertResolver {
144-
store,
145-
pin: params.password.clone(),
146-
}))?;
107+
.with_server_credential_resolver(Arc::new(ServerCertResolver { store }))?;
108+
109+
let server = TcpListener::bind(format!("127.0.0.1:{PORT}"))?;
147110

148-
let server = TcpListener::bind(format!("0.0.0.0:{PORT}"))?;
111+
println!("Listening on port {}", PORT);
149112

150113
// to test: openssl s_client -servername HOSTNAME -connect localhost:8000
151114
accept(server, Arc::new(server_config))?;

0 commit comments

Comments
 (0)