@@ -26,12 +26,15 @@ use axum::routing::{get, post};
26
26
use axum:: Router ;
27
27
use clap:: Parser ;
28
28
use confargs:: { prefix_char_filter, Toml } ;
29
+ #[ cfg( debug_assertions) ]
30
+ use const_oid:: db:: rfc5280:: { ID_CE_BASIC_CONSTRAINTS , ID_CE_KEY_USAGE } ;
29
31
use 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 ,
32
33
} ;
33
34
use 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 } ;
35
38
use der:: { Decode , Encode , Sequence } ;
36
39
use ext:: kvm:: Kvm ;
37
40
use ext:: sgx:: Sgx ;
@@ -48,7 +51,9 @@ use tower_http::LatencyUnit;
48
51
use tracing:: { debug, Level } ;
49
52
use x509:: attr:: Attribute ;
50
53
use 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 } ;
52
57
use x509:: name:: RdnSequence ;
53
58
use x509:: request:: { CertReq , ExtensionReq } ;
54
59
use x509:: time:: { Time , Validity } ;
@@ -80,6 +85,7 @@ struct Args {
80
85
#[ clap( short, long, env = "ROCKET_ADDRESS" , default_value = "::" ) ]
81
86
addr : IpAddr ,
82
87
88
+ #[ cfg( debug_assertions) ]
83
89
#[ clap( short, long, env = "RENDER_EXTERNAL_HOSTNAME" ) ]
84
90
host : Option < String > ,
85
91
@@ -141,11 +147,22 @@ impl State {
141
147
142
148
// Validate the syntax of the files.
143
149
PrivateKeyInfo :: from_der ( key. as_ref ( ) ) ?;
150
+ #[ cfg( debug_assertions) ]
144
151
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
+ }
145
161
146
162
Ok ( State { crt, san, key } )
147
163
}
148
164
165
+ #[ cfg( debug_assertions) ]
149
166
pub fn generate ( san : Option < String > , hostname : & str ) -> anyhow:: Result < Self > {
150
167
use const_oid:: db:: rfc5912:: SECP_256_R_1 as P256 ;
151
168
@@ -219,6 +236,8 @@ async fn main() -> anyhow::Result<()> {
219
236
let args = confargs:: args :: < Toml > ( prefix_char_filter :: < '@' > )
220
237
. context ( "Failed to parse config" )
221
238
. map ( Args :: parse_from) ?;
239
+
240
+ #[ cfg( debug_assertions) ]
222
241
let state = match ( args. key , args. crt , args. host ) {
223
242
( None , None , Some ( host) ) => State :: generate ( args. san , & host) ?,
224
243
( Some ( key) , Some ( crt) , _) => State :: load ( args. san , key, crt) ?,
@@ -228,6 +247,15 @@ async fn main() -> anyhow::Result<()> {
228
247
}
229
248
} ;
230
249
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
+
231
259
#[ cfg( not( target_os = "wasi" ) ) ]
232
260
{
233
261
use std:: net:: SocketAddr ;
@@ -316,6 +344,14 @@ fn attest_request(
316
344
StatusCode :: BAD_REQUEST
317
345
} ) ?;
318
346
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
+
319
355
let mut extensions = Vec :: new ( ) ;
320
356
let mut attested = false ;
321
357
for Attribute { oid, values } in info. attributes . iter ( ) {
@@ -329,11 +365,6 @@ fn attest_request(
329
365
StatusCode :: BAD_REQUEST
330
366
} ) ?;
331
367
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
-
337
368
// Validate the extension.
338
369
let ( copy, att) = match ext. extn_id {
339
370
Kvm :: OID => ( Kvm :: default ( ) . verify ( & info, & ext, dbg) , Kvm :: ATT ) ,
@@ -471,16 +502,22 @@ async fn attest(
471
502
#[ cfg( test) ]
472
503
mod tests {
473
504
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 } ;
475
508
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 } ;
477
512
use const_oid:: ObjectIdentifier ;
478
513
use der:: { AnyRef , Encode } ;
479
514
use x509:: attr:: Attribute ;
480
515
use x509:: request:: { CertReq , CertReqInfo , ExtensionReq } ;
516
+ #[ cfg( debug_assertions) ]
481
517
use x509:: PkiPath ;
482
518
use x509:: { ext:: Extension , name:: RdnSequence } ;
483
519
520
+ #[ cfg( debug_assertions) ]
484
521
use axum:: response:: Response ;
485
522
use http:: header:: CONTENT_TYPE ;
486
523
use http:: Request ;
@@ -490,17 +527,34 @@ mod tests {
490
527
491
528
fn certificates_state ( ) -> State {
492
529
#[ 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
+
495
539
#[ cfg( target_os = "wasi" ) ]
496
540
{
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
+ } ;
499
552
500
553
State :: read ( None , key, crt) . expect ( "failed to load state" )
501
554
}
502
555
}
503
556
557
+ #[ cfg( debug_assertions) ]
504
558
fn hostname_state ( ) -> State {
505
559
State :: generate ( None , "localhost" ) . unwrap ( )
506
560
}
@@ -534,6 +588,7 @@ mod tests {
534
588
}
535
589
}
536
590
591
+ #[ cfg( debug_assertions) ]
537
592
async fn attest_response ( state : State , response : Response , multi : bool ) {
538
593
let body = hyper:: body:: to_bytes ( response. into_body ( ) ) . await . unwrap ( ) ;
539
594
@@ -591,10 +646,18 @@ mod tests {
591
646
. unwrap ( ) ;
592
647
593
648
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
+ }
596
658
}
597
659
660
+ #[ cfg( debug_assertions) ]
598
661
#[ rstest]
599
662
#[ case( PKCS10 , false ) ]
600
663
#[ case( BUNDLE , true ) ]
@@ -621,6 +684,7 @@ mod tests {
621
684
622
685
// Though similar to the above test, this is the only test which
623
686
// actually sends many CSRs, versus an array of just one CSR.
687
+ #[ cfg( debug_assertions) ]
624
688
#[ tokio:: test]
625
689
async fn kvm_hostname_many_certs ( ) {
626
690
let ext = Extension {
@@ -658,6 +722,7 @@ mod tests {
658
722
assert_eq ! ( output. issued. len( ) , five_crs. len( ) ) ;
659
723
}
660
724
725
+ #[ cfg( debug_assertions) ]
661
726
#[ rstest]
662
727
#[ case( PKCS10 , false ) ]
663
728
#[ case( BUNDLE , true ) ]
@@ -686,6 +751,7 @@ mod tests {
686
751
}
687
752
}
688
753
754
+ #[ cfg( debug_assertions) ]
689
755
#[ rstest]
690
756
#[ case( PKCS10 , false ) ]
691
757
#[ case( BUNDLE , true ) ]
@@ -715,6 +781,7 @@ mod tests {
715
781
}
716
782
}
717
783
784
+ #[ cfg( debug_assertions) ]
718
785
#[ rstest]
719
786
#[ case( PKCS10 , false ) ]
720
787
#[ case( BUNDLE , true ) ]
@@ -745,6 +812,7 @@ mod tests {
745
812
attest_response ( certificates_state ( ) , response, multi) . await ;
746
813
}
747
814
815
+ #[ cfg( debug_assertions) ]
748
816
#[ rstest]
749
817
#[ case( PKCS10 , false ) ]
750
818
#[ case( BUNDLE , true ) ]
@@ -776,6 +844,7 @@ mod tests {
776
844
attest_response ( state, response, multi) . await ;
777
845
}
778
846
847
+ #[ cfg( debug_assertions) ]
779
848
#[ rstest]
780
849
#[ case( PKCS10 , false ) ]
781
850
#[ case( BUNDLE , true ) ]
@@ -792,6 +861,7 @@ mod tests {
792
861
assert_eq ! ( response. status( ) , StatusCode :: UNAUTHORIZED ) ;
793
862
}
794
863
864
+ #[ cfg( debug_assertions) ]
795
865
#[ tokio:: test]
796
866
async fn err_no_attestation_hostname ( ) {
797
867
let request = Request :: builder ( )
@@ -805,6 +875,7 @@ mod tests {
805
875
assert_eq ! ( response. status( ) , StatusCode :: UNAUTHORIZED ) ;
806
876
}
807
877
878
+ #[ cfg( debug_assertions) ]
808
879
#[ rstest]
809
880
#[ case( false ) ]
810
881
#[ case( true ) ]
@@ -820,6 +891,7 @@ mod tests {
820
891
assert_eq ! ( response. status( ) , StatusCode :: BAD_REQUEST ) ;
821
892
}
822
893
894
+ #[ cfg( debug_assertions) ]
823
895
#[ tokio:: test]
824
896
async fn err_empty_body ( ) {
825
897
let request = Request :: builder ( )
@@ -832,6 +904,7 @@ mod tests {
832
904
assert_eq ! ( response. status( ) , StatusCode :: BAD_REQUEST ) ;
833
905
}
834
906
907
+ #[ cfg( debug_assertions) ]
835
908
#[ tokio:: test]
836
909
async fn err_bad_body ( ) {
837
910
let request = Request :: builder ( )
@@ -844,6 +917,7 @@ mod tests {
844
917
assert_eq ! ( response. status( ) , StatusCode :: BAD_REQUEST ) ;
845
918
}
846
919
920
+ #[ cfg( debug_assertions) ]
847
921
#[ tokio:: test]
848
922
async fn err_bad_csr_sig ( ) {
849
923
let mut cr = cr ( SECP_256_R_1 , vec ! [ ] , true ) ;
0 commit comments