@@ -26,12 +26,15 @@ use axum::routing::{get, post};
2626use  axum:: Router ; 
2727use  clap:: Parser ; 
2828use  confargs:: { prefix_char_filter,  Toml } ; 
29+ #[ cfg( debug_assertions) ]  
30+ use  const_oid:: db:: rfc5280:: { ID_CE_BASIC_CONSTRAINTS ,  ID_CE_KEY_USAGE } ; 
2931use  const_oid:: db:: rfc5280:: { 
30-     ID_CE_BASIC_CONSTRAINTS ,  ID_CE_EXT_KEY_USAGE ,  ID_CE_KEY_USAGE ,  ID_CE_SUBJECT_ALT_NAME , 
31-     ID_KP_CLIENT_AUTH ,  ID_KP_SERVER_AUTH , 
32+     ID_CE_EXT_KEY_USAGE ,  ID_CE_SUBJECT_ALT_NAME ,  ID_KP_CLIENT_AUTH ,  ID_KP_SERVER_AUTH , 
3233} ; 
3334use  const_oid:: db:: rfc5912:: ID_EXTENSION_REQ ; 
34- use  der:: asn1:: { GeneralizedTime ,  Ia5StringRef ,  UIntRef } ; 
35+ #[ cfg( debug_assertions) ]  
36+ use  der:: asn1:: GeneralizedTime ; 
37+ use  der:: asn1:: { Ia5StringRef ,  UIntRef } ; 
3538use  der:: { Decode ,  Encode ,  Sequence } ; 
3639use  ext:: kvm:: Kvm ; 
3740use  ext:: sgx:: Sgx ; 
@@ -48,7 +51,9 @@ use tower_http::LatencyUnit;
4851use  tracing:: { debug,  Level } ; 
4952use  x509:: attr:: Attribute ; 
5053use  x509:: ext:: pkix:: name:: GeneralName ; 
51- use  x509:: ext:: pkix:: { BasicConstraints ,  ExtendedKeyUsage ,  KeyUsage ,  KeyUsages ,  SubjectAltName } ; 
54+ #[ cfg( debug_assertions) ]  
55+ use  x509:: ext:: pkix:: { BasicConstraints ,  KeyUsage ,  KeyUsages } ; 
56+ use  x509:: ext:: pkix:: { ExtendedKeyUsage ,  SubjectAltName } ; 
5257use  x509:: name:: RdnSequence ; 
5358use  x509:: request:: { CertReq ,  ExtensionReq } ; 
5459use  x509:: time:: { Time ,  Validity } ; 
@@ -80,6 +85,7 @@ struct Args {
8085    #[ clap( short,  long,  env = "ROCKET_ADDRESS" ,  default_value = "::" ) ]  
8186    addr :  IpAddr , 
8287
88+     #[ cfg( debug_assertions) ]  
8389    #[ clap( short,  long,  env = "RENDER_EXTERNAL_HOSTNAME" ) ]  
8490    host :  Option < String > , 
8591
@@ -141,11 +147,22 @@ impl State {
141147
142148        // Validate the syntax of the files. 
143149        PrivateKeyInfo :: from_der ( key. as_ref ( ) ) ?; 
150+         #[ cfg( debug_assertions) ]  
144151        Certificate :: from_der ( crt. as_ref ( ) ) ?; 
152+         #[ cfg( not( debug_assertions) ) ]  
153+         { 
154+             let  cert = Certificate :: from_der ( crt. as_ref ( ) ) ?; 
155+             let  iss = & cert. tbs_certificate ; 
156+             if  iss. issuer_unique_id  == iss. subject_unique_id  && iss. issuer  == iss. subject  { 
157+                 // A self-signed certificate is not appropriate for Release mode. 
158+                 return  Err ( anyhow ! ( "invalid certificate" ) ) ; 
159+             } 
160+         } 
145161
146162        Ok ( State  {  crt,  san,  key } ) 
147163    } 
148164
165+     #[ cfg( debug_assertions) ]  
149166    pub  fn  generate ( san :  Option < String > ,  hostname :  & str )  -> anyhow:: Result < Self >  { 
150167        use  const_oid:: db:: rfc5912:: SECP_256_R_1  as  P256 ; 
151168
@@ -219,6 +236,8 @@ async fn main() -> anyhow::Result<()> {
219236    let  args = confargs:: args :: < Toml > ( prefix_char_filter :: < '@' > ) 
220237        . context ( "Failed to parse config" ) 
221238        . map ( Args :: parse_from) ?; 
239+ 
240+     #[ cfg( debug_assertions) ]  
222241    let  state = match  ( args. key ,  args. crt ,  args. host )  { 
223242        ( None ,  None ,  Some ( host) )  => State :: generate ( args. san ,  & host) ?, 
224243        ( Some ( key) ,  Some ( crt) ,  _)  => State :: load ( args. san ,  key,  crt) ?, 
@@ -228,6 +247,15 @@ async fn main() -> anyhow::Result<()> {
228247        } 
229248    } ; 
230249
250+     #[ cfg( not( debug_assertions) ) ]  
251+     let  state = match  ( args. key ,  args. crt )  { 
252+         ( Some ( key) ,  Some ( crt) )  => State :: load ( args. san ,  key,  crt) ?, 
253+         _ => { 
254+             eprintln ! ( "Specify the public key `--crt` and private key `--key`.\n Run with `--help` for more information." ) ; 
255+             return  Err ( anyhow ! ( "invalid configuration" ) ) ; 
256+         } 
257+     } ; 
258+ 
231259    #[ cfg( not( target_os = "wasi" ) ) ]  
232260    { 
233261        use  std:: net:: SocketAddr ; 
@@ -316,6 +344,14 @@ fn attest_request(
316344        StatusCode :: BAD_REQUEST 
317345    } ) ?; 
318346
347+     let  dbg = if  cfg ! ( debug_assertions)  { 
348+         // If the issuer is self-signed, we are in debug mode. 
349+         let  iss = & issuer. tbs_certificate ; 
350+         iss. issuer_unique_id  == iss. subject_unique_id  && iss. issuer  == iss. subject 
351+     }  else  { 
352+         false 
353+     } ; 
354+ 
319355    let  mut  extensions = Vec :: new ( ) ; 
320356    let  mut  attested = false ; 
321357    for  Attribute  {  oid,  values }  in  info. attributes . iter ( )  { 
@@ -329,11 +365,6 @@ fn attest_request(
329365                StatusCode :: BAD_REQUEST 
330366            } ) ?; 
331367            for  ext in  Vec :: from ( ereq)  { 
332-                 // If the issuer is self-signed, we are in debug mode. 
333-                 let  iss = & issuer. tbs_certificate ; 
334-                 let  dbg = iss. issuer_unique_id  == iss. subject_unique_id ; 
335-                 let  dbg = dbg && iss. issuer  == iss. subject ; 
336- 
337368                // Validate the extension. 
338369                let  ( copy,  att)  = match  ext. extn_id  { 
339370                    Kvm :: OID  => ( Kvm :: default ( ) . verify ( & info,  & ext,  dbg) ,  Kvm :: ATT ) , 
@@ -471,16 +502,22 @@ async fn attest(
471502#[ cfg( test) ]  
472503mod  tests { 
473504    mod  attest { 
474-         use  crate :: ext:: { kvm:: Kvm ,  sgx:: Sgx ,  snp:: Snp ,  ExtVerifier } ; 
505+         use  crate :: ext:: { kvm:: Kvm ,  ExtVerifier } ; 
506+         #[ cfg( debug_assertions) ]  
507+         use  crate :: ext:: { sgx:: Sgx ,  snp:: Snp } ; 
475508        use  crate :: * ; 
476-         use  const_oid:: db:: rfc5912:: { ID_EXTENSION_REQ ,  SECP_256_R_1 ,  SECP_384_R_1 } ; 
509+         #[ cfg( debug_assertions) ]  
510+         use  const_oid:: db:: rfc5912:: SECP_384_R_1 ; 
511+         use  const_oid:: db:: rfc5912:: { ID_EXTENSION_REQ ,  SECP_256_R_1 } ; 
477512        use  const_oid:: ObjectIdentifier ; 
478513        use  der:: { AnyRef ,  Encode } ; 
479514        use  x509:: attr:: Attribute ; 
480515        use  x509:: request:: { CertReq ,  CertReqInfo ,  ExtensionReq } ; 
516+         #[ cfg( debug_assertions) ]  
481517        use  x509:: PkiPath ; 
482518        use  x509:: { ext:: Extension ,  name:: RdnSequence } ; 
483519
520+         #[ cfg( debug_assertions) ]  
484521        use  axum:: response:: Response ; 
485522        use  http:: header:: CONTENT_TYPE ; 
486523        use  http:: Request ; 
@@ -490,17 +527,34 @@ mod tests {
490527
491528        fn  certificates_state ( )  -> State  { 
492529            #[ cfg( not( target_os = "wasi" ) ) ]  
493-             return  State :: load ( None ,  "testdata/ca.key" ,  "testdata/ca.crt" ) 
494-                 . expect ( "failed to load state" ) ; 
530+             { 
531+                 #[ cfg( debug_assertions) ]  
532+                 return  State :: load ( None ,  "testdata/ca.key" ,  "testdata/ca.crt" ) 
533+                     . expect ( "failed to load state" ) ; 
534+                 #[ cfg( not( debug_assertions) ) ]  
535+                 return  State :: load ( None ,  "testdata/test.key" ,  "testdata/test.crt" ) 
536+                     . expect ( "failed to load state" ) ; 
537+             } 
538+ 
495539            #[ cfg( target_os = "wasi" ) ]  
496540            { 
497-                 let  crt = std:: io:: BufReader :: new ( include_bytes ! ( "../testdata/ca.crt" ) . as_slice ( ) ) ; 
498-                 let  key = std:: io:: BufReader :: new ( include_bytes ! ( "../testdata/ca.key" ) . as_slice ( ) ) ; 
541+                 let  ( crt,  key)  = if  cfg ! ( debug_assertions)  { 
542+                     ( 
543+                         std:: io:: BufReader :: new ( include_bytes ! ( "../testdata/ca.crt" ) . as_slice ( ) ) , 
544+                         std:: io:: BufReader :: new ( include_bytes ! ( "../testdata/ca.key" ) . as_slice ( ) ) , 
545+                     ) 
546+                 }  else  { 
547+                     ( 
548+                         std:: io:: BufReader :: new ( include_bytes ! ( "../testdata/test.crt" ) . as_slice ( ) ) , 
549+                         std:: io:: BufReader :: new ( include_bytes ! ( "../testdata/test.key" ) . as_slice ( ) ) , 
550+                     ) 
551+                 } ; 
499552
500553                State :: read ( None ,  key,  crt) . expect ( "failed to load state" ) 
501554            } 
502555        } 
503556
557+         #[ cfg( debug_assertions) ]  
504558        fn  hostname_state ( )  -> State  { 
505559            State :: generate ( None ,  "localhost" ) . unwrap ( ) 
506560        } 
@@ -534,6 +588,7 @@ mod tests {
534588            } 
535589        } 
536590
591+         #[ cfg( debug_assertions) ]  
537592        async  fn  attest_response ( state :  State ,  response :  Response ,  multi :  bool )  { 
538593            let  body = hyper:: body:: to_bytes ( response. into_body ( ) ) . await . unwrap ( ) ; 
539594
@@ -591,10 +646,18 @@ mod tests {
591646                . unwrap ( ) ; 
592647
593648            let  response = app ( certificates_state ( ) ) . oneshot ( request) . await . unwrap ( ) ; 
594-             assert_eq ! ( response. status( ) ,  StatusCode :: OK ) ; 
595-             attest_response ( certificates_state ( ) ,  response,  multi) . await ; 
649+             #[ cfg( debug_assertions) ]  
650+             { 
651+                 assert_eq ! ( response. status( ) ,  StatusCode :: OK ) ; 
652+                 attest_response ( certificates_state ( ) ,  response,  multi) . await ; 
653+             } 
654+             #[ cfg( not( debug_assertions) ) ]  
655+             { 
656+                 assert_eq ! ( response. status( ) ,  StatusCode :: BAD_REQUEST ) ; 
657+             } 
596658        } 
597659
660+         #[ cfg( debug_assertions) ]  
598661        #[ rstest]  
599662        #[ case( PKCS10 ,  false ) ]  
600663        #[ case( BUNDLE ,  true ) ]  
@@ -621,6 +684,7 @@ mod tests {
621684
622685        // Though similar to the above test, this is the only test which 
623686        // actually sends many CSRs, versus an array of just one CSR. 
687+         #[ cfg( debug_assertions) ]  
624688        #[ tokio:: test]  
625689        async  fn  kvm_hostname_many_certs ( )  { 
626690            let  ext = Extension  { 
@@ -658,6 +722,7 @@ mod tests {
658722            assert_eq ! ( output. issued. len( ) ,  five_crs. len( ) ) ; 
659723        } 
660724
725+         #[ cfg( debug_assertions) ]  
661726        #[ rstest]  
662727        #[ case( PKCS10 ,  false ) ]  
663728        #[ case( BUNDLE ,  true ) ]  
@@ -686,6 +751,7 @@ mod tests {
686751            } 
687752        } 
688753
754+         #[ cfg( debug_assertions) ]  
689755        #[ rstest]  
690756        #[ case( PKCS10 ,  false ) ]  
691757        #[ case( BUNDLE ,  true ) ]  
@@ -715,6 +781,7 @@ mod tests {
715781            } 
716782        } 
717783
784+         #[ cfg( debug_assertions) ]  
718785        #[ rstest]  
719786        #[ case( PKCS10 ,  false ) ]  
720787        #[ case( BUNDLE ,  true ) ]  
@@ -745,6 +812,7 @@ mod tests {
745812            attest_response ( certificates_state ( ) ,  response,  multi) . await ; 
746813        } 
747814
815+         #[ cfg( debug_assertions) ]  
748816        #[ rstest]  
749817        #[ case( PKCS10 ,  false ) ]  
750818        #[ case( BUNDLE ,  true ) ]  
@@ -776,6 +844,7 @@ mod tests {
776844            attest_response ( state,  response,  multi) . await ; 
777845        } 
778846
847+         #[ cfg( debug_assertions) ]  
779848        #[ rstest]  
780849        #[ case( PKCS10 ,  false ) ]  
781850        #[ case( BUNDLE ,  true ) ]  
@@ -792,6 +861,7 @@ mod tests {
792861            assert_eq ! ( response. status( ) ,  StatusCode :: UNAUTHORIZED ) ; 
793862        } 
794863
864+         #[ cfg( debug_assertions) ]  
795865        #[ tokio:: test]  
796866        async  fn  err_no_attestation_hostname ( )  { 
797867            let  request = Request :: builder ( ) 
@@ -805,6 +875,7 @@ mod tests {
805875            assert_eq ! ( response. status( ) ,  StatusCode :: UNAUTHORIZED ) ; 
806876        } 
807877
878+         #[ cfg( debug_assertions) ]  
808879        #[ rstest]  
809880        #[ case( false ) ]  
810881        #[ case( true ) ]  
@@ -820,6 +891,7 @@ mod tests {
820891            assert_eq ! ( response. status( ) ,  StatusCode :: BAD_REQUEST ) ; 
821892        } 
822893
894+         #[ cfg( debug_assertions) ]  
823895        #[ tokio:: test]  
824896        async  fn  err_empty_body ( )  { 
825897            let  request = Request :: builder ( ) 
@@ -832,6 +904,7 @@ mod tests {
832904            assert_eq ! ( response. status( ) ,  StatusCode :: BAD_REQUEST ) ; 
833905        } 
834906
907+         #[ cfg( debug_assertions) ]  
835908        #[ tokio:: test]  
836909        async  fn  err_bad_body ( )  { 
837910            let  request = Request :: builder ( ) 
@@ -844,6 +917,7 @@ mod tests {
844917            assert_eq ! ( response. status( ) ,  StatusCode :: BAD_REQUEST ) ; 
845918        } 
846919
920+         #[ cfg( debug_assertions) ]  
847921        #[ tokio:: test]  
848922        async  fn  err_bad_csr_sig ( )  { 
849923            let  mut  cr = cr ( SECP_256_R_1 ,  vec ! [ ] ,  true ) ; 
0 commit comments