11pub mod errors;
22pub use crate :: errors:: Error ;
33use anyhow:: anyhow;
4- use attestation_report:: { QEType , RAQuote , RAType , ReportData } ;
4+ use attestation_report:: { is_enclave_debug_enabled , QEType , RAQuote , RAType , ReportData } ;
55use crypto:: { Address , SealedEnclaveKey } ;
66use lcp_types:: {
77 deserialize_bytes,
@@ -18,13 +18,19 @@ use serde_with::serde_as;
1818use sgx_types:: sgx_report_t;
1919use std:: { path:: Path , sync:: Mutex , time:: Duration } ;
2020
21+ /// Key Manager database file name
2122pub static KEY_MANAGER_DB : & str = "km.sqlite" ;
2223
24+ /// Enclave Key Manager to manage sealed enclave key and attestation verification reports for the keys
2325pub struct EnclaveKeyManager {
2426 conn : Mutex < Connection > ,
2527}
2628
2729impl EnclaveKeyManager {
30+ /// Create a new Key Manager instance
31+ ///
32+ /// # Arguments
33+ /// - `home_dir` - The directory where the LCP's home directory is located
2834 pub fn new ( home_dir : & Path ) -> Result < Self , Error > {
2935 let km_db = home_dir. join ( KEY_MANAGER_DB ) ;
3036 let db_exists = km_db. exists ( ) ;
@@ -37,6 +43,7 @@ impl EnclaveKeyManager {
3743 Ok ( this)
3844 }
3945
46+ /// Create a new Key Manager instance with an in-memory database
4047 #[ cfg( test) ]
4148 pub fn new_in_memory ( ) -> Result < Self , Error > {
4249 let conn = Mutex :: new ( Connection :: open_in_memory ( ) ?) ;
@@ -59,6 +66,7 @@ impl EnclaveKeyManager {
5966 ek_sealed BLOB NOT NULL,
6067 mrenclave TEXT NOT NULL,
6168 report BLOB NOT NULL,
69+ enclave_debug INTEGER NOT NULL,
6270 qe_type INTEGER NOT NULL,
6371 ra_type INTEGER,
6472 ra_quote TEXT,
@@ -81,7 +89,7 @@ impl EnclaveKeyManager {
8189 . map_err ( |e| Error :: mutex_lock ( e. to_string ( ) ) ) ?;
8290 let mut stmt = conn. prepare (
8391 r#"
84- SELECT ek_sealed, mrenclave, report, qe_type, ra_quote
92+ SELECT ek_sealed, mrenclave, report, qe_type, enclave_debug, ra_quote
8593 FROM enclave_keys
8694 WHERE ek_address = ?1
8795 "# ,
@@ -118,7 +126,8 @@ impl EnclaveKeyManager {
118126 anyhow ! ( "qe_type: {:?}" , e) . into ( ) ,
119127 )
120128 } ) ?,
121- ra_quote : match row. get :: < _ , Option < String > > ( 4 ) {
129+ enclave_debug : row. get :: < _ , i64 > ( 4 ) ? != 0 ,
130+ ra_quote : match row. get :: < _ , Option < String > > ( 5 ) {
122131 Ok ( None ) => None ,
123132 Ok ( Some ( ra_quote) ) => Some ( RAQuote :: from_json ( & ra_quote) . map_err ( |e| {
124133 rusqlite:: Error :: FromSqlConversionFailure (
@@ -147,8 +156,8 @@ impl EnclaveKeyManager {
147156 . map_err ( |e| Error :: mutex_lock ( e. to_string ( ) ) ) ?;
148157 let mut stmt = conn. prepare (
149158 r#"
150- INSERT INTO enclave_keys(ek_address, ek_sealed, mrenclave, report, qe_type)
151- VALUES (?1, ?2, ?3, ?4, ?5)
159+ INSERT INTO enclave_keys(ek_address, ek_sealed, mrenclave, report, enclave_debug, qe_type)
160+ VALUES (?1, ?2, ?3, ?4, ?5, ?6 )
152161 "# ,
153162 ) ?;
154163 let rd = ReportData :: from ( report. body . report_data ) ;
@@ -157,6 +166,7 @@ impl EnclaveKeyManager {
157166 sealed_ek. to_vec( ) ,
158167 Mrenclave :: from( report. body. mr_enclave) . to_hex_string( ) ,
159168 serialize_bytes( & report) ,
169+ is_enclave_debug_enabled( & report. body) ,
160170 qe_type. as_u32( )
161171 ] ) ?;
162172 Ok ( ( ) )
@@ -188,6 +198,7 @@ impl EnclaveKeyManager {
188198 pub fn available_keys (
189199 & self ,
190200 mrenclave : Mrenclave ,
201+ enclave_debug : bool ,
191202 ra_type : Option < RAType > ,
192203 ) -> Result < Vec < SealedEnclaveKeyInfo > , Error > {
193204 let conn = self
@@ -199,25 +210,25 @@ impl EnclaveKeyManager {
199210 (
200211 conn. prepare (
201212 r#"
202- SELECT ek_address, ek_sealed, mrenclave, report, qe_type, ra_quote
213+ SELECT ek_address, ek_sealed, mrenclave, report, qe_type, enclave_debug, ra_quote
203214 FROM enclave_keys
204- WHERE attested_at IS NOT NULL AND mrenclave = ?1 AND ra_type = ?2
215+ WHERE attested_at IS NOT NULL AND mrenclave = ?1 AND enclave_debug = ?2 AND ra_type = ?3
205216 ORDER BY attested_at DESC
206217 "# ,
207218 ) ?,
208- params ! [ mrenclave. to_hex_string( ) , ra_type. as_u32( ) ] ,
219+ params ! [ mrenclave. to_hex_string( ) , enclave_debug , ra_type. as_u32( ) ] ,
209220 )
210221 } else {
211222 (
212223 conn. prepare (
213224 r#"
214- SELECT ek_address, ek_sealed, mrenclave, report, qe_type, ra_quote
225+ SELECT ek_address, ek_sealed, mrenclave, report, qe_type, enclave_debug, ra_quote
215226 FROM enclave_keys
216- WHERE attested_at IS NOT NULL AND mrenclave = ?1
227+ WHERE attested_at IS NOT NULL AND mrenclave = ?1 AND enclave_debug = ?2
217228 ORDER BY attested_at DESC
218229 "# ,
219230 ) ?,
220- params ! [ mrenclave. to_hex_string( ) ] ,
231+ params ! [ mrenclave. to_hex_string( ) , enclave_debug ] ,
221232 )
222233 } ;
223234
@@ -264,7 +275,8 @@ impl EnclaveKeyManager {
264275 anyhow ! ( "qe_type: {:?}" , e) . into ( ) ,
265276 )
266277 } ) ?,
267- ra_quote : match row. get :: < _ , Option < String > > ( 5 ) {
278+ enclave_debug : row. get :: < _ , i64 > ( 5 ) ? != 0 ,
279+ ra_quote : match row. get :: < _ , Option < String > > ( 6 ) {
268280 Ok ( None ) => None ,
269281 Ok ( Some ( ra_quote) ) => Some ( RAQuote :: from_json ( & ra_quote) . map_err ( |e| {
270282 rusqlite:: Error :: FromSqlConversionFailure (
@@ -289,7 +301,7 @@ impl EnclaveKeyManager {
289301 . map_err ( |e| Error :: mutex_lock ( e. to_string ( ) ) ) ?;
290302 let mut stmt = conn. prepare (
291303 r#"
292- SELECT ek_address, ek_sealed, mrenclave, report, qe_type, ra_quote
304+ SELECT ek_address, ek_sealed, mrenclave, report, qe_type, enclave_debug, ra_quote
293305 FROM enclave_keys
294306 ORDER BY updated_at DESC
295307 "# ,
@@ -337,7 +349,8 @@ impl EnclaveKeyManager {
337349 anyhow ! ( "qe_type: {:?}" , e) . into ( ) ,
338350 )
339351 } ) ?,
340- ra_quote : match row. get :: < _ , Option < String > > ( 5 ) {
352+ enclave_debug : row. get :: < _ , i64 > ( 5 ) ? != 0 ,
353+ ra_quote : match row. get :: < _ , Option < String > > ( 6 ) {
341354 Ok ( None ) => None ,
342355 Ok ( Some ( avr) ) => Some ( RAQuote :: from_json ( & avr) . map_err ( |e| {
343356 rusqlite:: Error :: FromSqlConversionFailure (
@@ -376,6 +389,7 @@ pub struct SealedEnclaveKeyInfo {
376389 #[ serde_as( as = "BytesTransmuter<sgx_report_t>" ) ]
377390 pub report : sgx_report_t ,
378391 pub qe_type : QEType ,
392+ pub enclave_debug : bool ,
379393 pub ra_quote : Option < RAQuote > ,
380394}
381395
@@ -461,14 +475,16 @@ mod tests {
461475 let mrenclave = create_mrenclave ( ) ;
462476 let address_0 = {
463477 let address = create_address ( ) ;
464- let report = create_report ( mrenclave, address) ;
478+ let report = create_report ( mrenclave, address, false ) ;
465479 let sealed_ek = create_sealed_sk ( ) ;
466480 assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 0 ) ;
467481 km. save ( sealed_ek, report, QEType :: QE ) . unwrap ( ) ;
468- assert ! ( km. load( address) . unwrap( ) . ra_quote. is_none( ) ) ;
482+ let eki = km. load ( address) . unwrap ( ) ;
483+ assert ! ( eki. ra_quote. is_none( ) ) ;
484+ assert ! ( !eki. enclave_debug) ;
469485 assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 1 ) ;
470486 assert_eq ! (
471- km. available_keys( mrenclave, Some ( RAType :: IAS ) )
487+ km. available_keys( mrenclave, false , Some ( RAType :: IAS ) )
472488 . unwrap( )
473489 . len( ) ,
474490 0
@@ -478,7 +494,7 @@ mod tests {
478494 assert ! ( km. load( address) . unwrap( ) . ra_quote. is_some( ) ) ;
479495 assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 1 ) ;
480496 assert_eq ! (
481- km. available_keys( mrenclave, Some ( RAType :: IAS ) )
497+ km. available_keys( mrenclave, false , Some ( RAType :: IAS ) )
482498 . unwrap( )
483499 . len( ) ,
484500 1
@@ -487,14 +503,14 @@ mod tests {
487503 } ;
488504 {
489505 let address = create_address ( ) ;
490- let report = create_report ( mrenclave, address) ;
506+ let report = create_report ( mrenclave, address, false ) ;
491507 let sealed_ek = create_sealed_sk ( ) ;
492508 assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 1 ) ;
493509 km. save ( sealed_ek, report, QEType :: QE ) . unwrap ( ) ;
494510 assert ! ( km. load( address) . unwrap( ) . ra_quote. is_none( ) ) ;
495511 assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 2 ) ;
496512 assert_eq ! (
497- km. available_keys( mrenclave, Some ( RAType :: IAS ) )
513+ km. available_keys( mrenclave, false , Some ( RAType :: IAS ) )
498514 . unwrap( )
499515 . len( ) ,
500516 1
@@ -504,29 +520,58 @@ mod tests {
504520 assert ! ( km. load( address) . unwrap( ) . ra_quote. is_some( ) ) ;
505521 assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 2 ) ;
506522 assert_eq ! (
507- km. available_keys( mrenclave, Some ( RAType :: IAS ) )
523+ km. available_keys( mrenclave, false , Some ( RAType :: IAS ) )
508524 . unwrap( )
509525 . len( ) ,
510526 2
511527 ) ;
512528 }
513529 // there are no keys available for the mrenclave
514530 assert_eq ! (
515- km. available_keys( create_mrenclave( ) , Some ( RAType :: IAS ) )
531+ km. available_keys( create_mrenclave( ) , false , Some ( RAType :: IAS ) )
516532 . unwrap( )
517533 . len( ) ,
518534 0
519535 ) ;
520536 assert_eq ! ( km. prune( 30 ) . unwrap( ) , 1 ) ;
521537 assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 1 ) ;
522538 assert_eq ! (
523- km. available_keys( mrenclave, Some ( RAType :: IAS ) )
539+ km. available_keys( mrenclave, false , Some ( RAType :: IAS ) )
524540 . unwrap( )
525541 . first( )
526542 . unwrap( )
527543 . address,
528544 address_0
529545 ) ;
546+ // create enclave_debug enabled key
547+ {
548+ let address = create_address ( ) ;
549+ let report = create_report ( mrenclave, address, true ) ;
550+ let sealed_ek = create_sealed_sk ( ) ;
551+ km. save ( sealed_ek, report, QEType :: QE ) . unwrap ( ) ;
552+ assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 2 ) ;
553+ let ki = km. load ( address) . unwrap ( ) ;
554+ assert ! ( ki. enclave_debug) ;
555+
556+ let ias_report = create_ias_report ( get_time ( Duration :: zero ( ) ) ) ;
557+ km. save_ra_quote ( address, ias_report. into ( ) ) . unwrap ( ) ;
558+ assert ! ( km. load( address) . unwrap( ) . ra_quote. is_some( ) ) ;
559+ assert_eq ! ( km. all_keys( ) . unwrap( ) . len( ) , 2 ) ;
560+ // if `enclave_debug` is true, should return only the key with enclave_debug enabled
561+ assert_eq ! (
562+ km. available_keys( mrenclave, true , Some ( RAType :: IAS ) )
563+ . unwrap( )
564+ . len( ) ,
565+ 1
566+ ) ;
567+ // if `enclave_debug` is false, should return only the key with enclave_debug disabled
568+ assert_eq ! (
569+ km. available_keys( mrenclave, false , Some ( RAType :: IAS ) )
570+ . unwrap( )
571+ . len( ) ,
572+ 1
573+ )
574+ }
530575 }
531576
532577 #[ test]
@@ -535,7 +580,7 @@ mod tests {
535580 let mrenclave = create_mrenclave ( ) ;
536581 let sealed_ek = create_sealed_sk ( ) ;
537582 let address = create_address ( ) ;
538- let report = create_report ( mrenclave, address) ;
583+ let report = create_report ( mrenclave, address, false ) ;
539584 km. save ( sealed_ek, report, QEType :: QE ) . unwrap ( ) ;
540585 let key_info = km. load ( address) . unwrap ( ) ;
541586 assert ! ( ProtoEnclaveKeyInfo :: try_from( key_info) . is_err( ) ) ;
@@ -560,10 +605,11 @@ mod tests {
560605 SealedEnclaveKey :: new_from_bytes ( & sealed_sk) . unwrap ( )
561606 }
562607
563- fn create_report ( mrenclave : Mrenclave , ek_addr : Address ) -> sgx_report_t {
608+ fn create_report ( mrenclave : Mrenclave , ek_addr : Address , enclave_debug : bool ) -> sgx_report_t {
564609 let mut report = sgx_report_t:: default ( ) ;
565610 report. body . mr_enclave = mrenclave. into ( ) ;
566611 report. body . report_data = ReportData :: new ( ek_addr, None ) . into ( ) ;
612+ report. body . attributes . flags = sgx_types:: SGX_FLAGS_DEBUG * enclave_debug as u64 ;
567613 report
568614 }
569615
@@ -574,6 +620,7 @@ mod tests {
574620 }
575621
576622 fn create_ias_report ( timestamp : DateTime < Utc > ) -> IASSignedReport {
623+ // TODO set correct quote body
577624 IASSignedReport {
578625 avr : IASAttestationVerificationReport {
579626 version : 4 ,
0 commit comments