@@ -159,12 +159,12 @@ struct Keys {
159159}
160160
161161impl Keys {
162- async fn generate ( domain : & str ) -> Result < Self > {
162+ async fn generate ( domain : & str , quote_enabled : bool ) -> Result < Self > {
163163 let tmp_ca_key = KeyPair :: generate_for ( & PKCS_ECDSA_P256_SHA256 ) ?;
164164 let ca_key = KeyPair :: generate_for ( & PKCS_ECDSA_P256_SHA256 ) ?;
165165 let rpc_key = KeyPair :: generate_for ( & PKCS_ECDSA_P256_SHA256 ) ?;
166166 let k256_key = SigningKey :: random ( & mut rand:: rngs:: OsRng ) ;
167- Self :: from_keys ( tmp_ca_key, ca_key, rpc_key, k256_key, domain) . await
167+ Self :: from_keys ( tmp_ca_key, ca_key, rpc_key, k256_key, domain, quote_enabled ) . await
168168 }
169169
170170 async fn from_keys (
@@ -173,6 +173,7 @@ impl Keys {
173173 rpc_key : KeyPair ,
174174 k256_key : SigningKey ,
175175 domain : & str ,
176+ quote_enabled : bool ,
176177 ) -> Result < Self > {
177178 let tmp_ca_cert = CertRequest :: builder ( )
178179 . org_name ( "Dstack" )
@@ -190,20 +191,25 @@ impl Keys {
190191 . key ( & ca_key)
191192 . build ( )
192193 . self_signed ( ) ?;
193- let pubkey = rpc_key. public_key_der ( ) ;
194- let report_data = QuoteContentType :: RaTlsCert . to_report_data ( & pubkey) ;
195- let response = app_attest ( report_data. to_vec ( ) )
196- . await
197- . context ( "Failed to get quote" ) ?;
198- let attestation = VersionedAttestation :: from_scale ( & response. attestation )
199- . context ( "Invalid attestation" ) ?;
194+ let attestation = if quote_enabled {
195+ let pubkey = rpc_key. public_key_der ( ) ;
196+ let report_data = QuoteContentType :: RaTlsCert . to_report_data ( & pubkey) ;
197+ let response = app_attest ( report_data. to_vec ( ) )
198+ . await
199+ . context ( "Failed to get quote" ) ?;
200+ let attestation = VersionedAttestation :: from_scale ( & response. attestation )
201+ . context ( "Invalid attestation" ) ?;
202+ Some ( attestation)
203+ } else {
204+ None
205+ } ;
200206
201207 // Sign WWW server cert with KMS cert
202208 let rpc_cert = CertRequest :: builder ( )
203209 . subject ( domain)
204210 . alt_names ( & [ domain. to_string ( ) ] )
205211 . special_usage ( "kms:rpc" )
206- . maybe_attestation ( Some ( & attestation) )
212+ . maybe_attestation ( attestation. as_ref ( ) )
207213 . key ( & rpc_key)
208214 . build ( )
209215 . signed_by ( & ca_cert, & ca_key) ?;
@@ -308,6 +314,16 @@ impl Keys {
308314 }
309315}
310316
317+ fn validate_domain ( domain : & str , source : & str ) -> Result < String > {
318+ let domain = domain. trim ( ) ;
319+ if domain. is_empty ( ) {
320+ return Err ( anyhow:: anyhow!(
321+ "invalid domain from {source}: empty or whitespace-only"
322+ ) ) ;
323+ }
324+ Ok ( domain. to_string ( ) )
325+ }
326+
311327pub ( crate ) async fn update_certs ( cfg : & KmsConfig ) -> Result < ( ) > {
312328 // Read existing keys
313329 let tmp_ca_key = KeyPair :: from_pem ( & fs:: read_to_string ( cfg. tmp_ca_key ( ) ) ?) ?;
@@ -318,17 +334,26 @@ pub(crate) async fn update_certs(cfg: &KmsConfig) -> Result<()> {
318334 let k256_key_bytes = fs:: read ( cfg. k256_key ( ) ) ?;
319335 let k256_key = SigningKey :: from_slice ( & k256_key_bytes) ?;
320336
321- let domain = if cfg. onboard . auto_bootstrap_domain . is_empty ( ) {
322- fs:: read_to_string ( cfg. rpc_domain ( ) ) ?
337+ let domain = if cfg. onboard . auto_bootstrap_domain . trim ( ) . is_empty ( ) {
338+ validate_domain ( & fs:: read_to_string ( cfg. rpc_domain ( ) ) ? , "stored rpc_domain" ) ?
323339 } else {
324- cfg. onboard . auto_bootstrap_domain . clone ( )
340+ validate_domain (
341+ & cfg. onboard . auto_bootstrap_domain ,
342+ "core.onboard.auto_bootstrap_domain" ,
343+ ) ?
325344 } ;
326- let domain = domain. trim ( ) ;
327345
328346 // Regenerate certificates using existing keys
329- let keys = Keys :: from_keys ( tmp_ca_key, ca_key, rpc_key, k256_key, domain)
330- . await
331- . context ( "Failed to regenerate certificates" ) ?;
347+ let keys = Keys :: from_keys (
348+ tmp_ca_key,
349+ ca_key,
350+ rpc_key,
351+ k256_key,
352+ & domain,
353+ cfg. onboard . quote_enabled ,
354+ )
355+ . await
356+ . context ( "Failed to regenerate certificates" ) ?;
332357
333358 // Write the new certificates to files
334359 keys. store_certs ( cfg) ?;
@@ -347,9 +372,13 @@ pub(crate) async fn auto_onboard_keys(cfg: &KmsConfig) -> Result<()> {
347372 } else {
348373 format ! ( "{source_url}/prpc" )
349374 } ;
375+ let domain = validate_domain (
376+ & cfg. onboard . auto_bootstrap_domain ,
377+ "core.onboard.auto_bootstrap_domain" ,
378+ ) ?;
350379 let keys = Keys :: onboard (
351380 & source_url,
352- & cfg . onboard . auto_bootstrap_domain ,
381+ & domain ,
353382 cfg. onboard . quote_enabled ,
354383 cfg. pccs_url . clone ( ) ,
355384 )
@@ -363,7 +392,11 @@ pub(crate) async fn bootstrap_keys(cfg: &KmsConfig) -> Result<()> {
363392 ensure_self_kms_allowed ( cfg)
364393 . await
365394 . context ( "KMS is not allowed to auto-bootstrap" ) ?;
366- let keys = Keys :: generate ( & cfg. onboard . auto_bootstrap_domain )
395+ let domain = validate_domain (
396+ & cfg. onboard . auto_bootstrap_domain ,
397+ "core.onboard.auto_bootstrap_domain" ,
398+ ) ?;
399+ let keys = Keys :: generate ( & domain, cfg. onboard . quote_enabled )
367400 . await
368401 . context ( "Failed to generate keys" ) ?;
369402 keys. store ( cfg) ?;
0 commit comments