@@ -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 ;
108use rustls:: {
119 ClientConfig , RootCertStore ,
1210 client:: { ClientCredentialResolver , CredentialRequest } ,
@@ -16,7 +14,7 @@ use rustls::{
1614} ;
1715use rustls_cng:: {
1816 signer:: CngSigningKey ,
19- store:: { CertStore , CertStoreType , Pkcs12Flags } ,
17+ store:: { CertStore , CertStoreType } ,
2018} ;
2119use rustls_util:: Stream ;
2220
@@ -26,7 +24,6 @@ const PORT: u16 = 8000;
2624pub struct ClientCertResolver {
2725 store : CertStore ,
2826 cert_name : String ,
29- pin : Option < String > ,
3027}
3128
3229fn 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-
8658fn 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" ) ?;
0 commit comments