@@ -2,6 +2,7 @@ use super::error::CertError;
22use crate :: cli:: certificate:: show:: ShowCertCmd ;
33use crate :: command:: Command ;
44use crate :: log:: MaybeFancy ;
5+ use anyhow:: Context ;
56use camino:: Utf8Path ;
67use camino:: Utf8PathBuf ;
78use certificate:: CsrTemplate ;
@@ -12,6 +13,7 @@ use std::fs::Permissions;
1213use std:: os:: unix:: fs:: PermissionsExt ;
1314use std:: path:: Path ;
1415use tedge_config:: TEdgeConfig ;
16+ use tedge_p11_server:: CryptokiConfig ;
1517use tokio:: fs:: File ;
1618use tokio:: fs:: OpenOptions ;
1719use tokio:: io:: AsyncWriteExt ;
@@ -42,8 +44,10 @@ impl Command for CreateCertCmd {
4244 format ! ( "create a test certificate for the device {}." , self . id)
4345 }
4446
45- async fn execute ( & self , _: TEdgeConfig ) -> Result < ( ) , MaybeFancy < anyhow:: Error > > {
46- self . create_test_certificate ( & self . csr_template ) . await ?;
47+ async fn execute ( & self , config : TEdgeConfig ) -> Result < ( ) , MaybeFancy < anyhow:: Error > > {
48+ let cryptoki = config. device . cryptoki_config ( None ) ?;
49+ self . create_test_certificate ( & self . csr_template , cryptoki)
50+ . await ?;
4751 eprintln ! ( "Certificate created successfully" ) ;
4852 eprintln ! ( " => the certificate has to be uploaded to the cloud" ) ;
4953 eprintln ! ( " => before the device can be connected\n " ) ;
@@ -53,8 +57,23 @@ impl Command for CreateCertCmd {
5357}
5458
5559impl CreateCertCmd {
56- pub async fn create_test_certificate ( & self , config : & CsrTemplate ) -> Result < ( ) , CertError > {
57- let cert = KeyCertPair :: new_selfsigned_certificate ( config, & self . id , & KeyKind :: New ) ?;
60+ // test certificate here means it's not yet permanent - establishing the connection using this
61+ // new certificate will be tested during `tedge connect` and if an error happens, we will revert
62+ // to the previous certificate. If not, the certificate will be set as a permanent active
63+ // certificate and will not be tested on further connections.
64+ pub async fn create_test_certificate (
65+ & self ,
66+ template : & CsrTemplate ,
67+ cryptoki : Option < CryptokiConfig > ,
68+ ) -> Result < ( ) , CertError > {
69+ let key_kind = if let Some ( cryptoki) = cryptoki {
70+ KeyKind :: from_cryptoki ( cryptoki. clone ( ) , None )
71+ . context ( "failed to create a remote keykind" ) ?
72+ } else {
73+ KeyKind :: New
74+ } ;
75+
76+ let cert = KeyCertPair :: new_selfsigned_certificate ( template, & self . id , & key_kind) ?;
5877
5978 let cert_path = & self . cert_path ;
6079 persist_new_public_key (
@@ -66,15 +85,18 @@ impl CreateCertCmd {
6685 . await
6786 . map_err ( |err| err. cert_context ( cert_path. clone ( ) ) ) ?;
6887
69- let key_path = & self . key_path ;
70- persist_new_private_key (
71- key_path,
72- cert. private_key_pem_string ( ) ?,
73- & self . user ,
74- & self . group ,
75- )
76- . await
77- . map_err ( |err| err. key_context ( key_path. clone ( ) ) ) ?;
88+ // only persist to filesystem if we just created a new key (not using HSM)
89+ if let KeyKind :: New = key_kind {
90+ let key_path = & self . key_path ;
91+ persist_new_private_key (
92+ key_path,
93+ cert. private_key_pem_string ( ) ?,
94+ & self . user ,
95+ & self . group ,
96+ )
97+ . await
98+ . map_err ( |err| err. key_context ( key_path. clone ( ) ) ) ?;
99+ }
78100 Ok ( ( ) )
79101 }
80102}
@@ -238,7 +260,8 @@ mod tests {
238260 } ;
239261
240262 assert_matches ! (
241- cmd. create_test_certificate( & CsrTemplate :: default ( ) ) . await ,
263+ cmd. create_test_certificate( & CsrTemplate :: default ( ) , None )
264+ . await ,
242265 Ok ( ( ) )
243266 ) ;
244267 assert_eq ! ( parse_pem_file( & cert_path) . tag( ) , "CERTIFICATE" ) ;
@@ -268,7 +291,7 @@ mod tests {
268291 } ;
269292
270293 assert ! ( cmd
271- . create_test_certificate( & CsrTemplate :: default ( ) )
294+ . create_test_certificate( & CsrTemplate :: default ( ) , None )
272295 . await
273296 . ok( )
274297 . is_none( ) ) ;
@@ -293,7 +316,7 @@ mod tests {
293316 } ;
294317
295318 let cert_error = cmd
296- . create_test_certificate ( & CsrTemplate :: default ( ) )
319+ . create_test_certificate ( & CsrTemplate :: default ( ) , None )
297320 . await
298321 . unwrap_err ( ) ;
299322 assert_matches ! ( cert_error, CertError :: CertificateNotFound { .. } ) ;
@@ -315,7 +338,7 @@ mod tests {
315338 } ;
316339
317340 let cert_error = cmd
318- . create_test_certificate ( & CsrTemplate :: default ( ) )
341+ . create_test_certificate ( & CsrTemplate :: default ( ) , None )
319342 . await
320343 . unwrap_err ( ) ;
321344 assert_matches ! ( cert_error, CertError :: KeyNotFound { .. } ) ;
0 commit comments