@@ -18,7 +18,7 @@ use opentitanlib::test_utils::init::InitializeTest;
1818use opentitanlib:: uart:: console:: UartConsole ;
1919use opentitanlib:: util:: file:: FromReader ;
2020
21- use ot_certs:: template:: { CertificateExtension , Value } ;
21+ use ot_certs:: template:: { AttributeType , CertificateExtension , Name , SubjectPublicKeyInfo , Value } ;
2222use ot_certs:: x509;
2323
2424#[ derive( Debug , Parser ) ]
@@ -68,6 +68,23 @@ fn get_base64_blob(haystack: &str, rx: &str) -> Result<Vec<u8>> {
6868 Ok ( bin)
6969}
7070
71+ fn check_public_key ( key : & SubjectPublicKeyInfo , id : & [ u8 ] , subject : & Name ) -> Result < bool > {
72+ let SubjectPublicKeyInfo :: EcPublicKey ( info) = key;
73+
74+ let mut material = Vec :: new ( ) ;
75+ material. extend ( & info. public_key . x . get_value ( ) . to_bytes_be ( ) ) ;
76+ material. extend ( & info. public_key . y . get_value ( ) . to_bytes_be ( ) ) ;
77+ let hash = sha256:: sha256 ( & material) . to_be_bytes ( ) ;
78+ let keyid = & hash[ ..20 ] ;
79+ log:: info!( "computed id = {:?}" , hex:: encode( keyid) ) ;
80+ log:: info!( " id = {:?}" , hex:: encode( id) ) ;
81+
82+ let name = subject[ 0 ] [ & AttributeType :: SerialNumber ] . get_value ( ) ;
83+ log:: info!( " subject = {:?}" , name) ;
84+
85+ Ok ( keyid == id && & hex:: encode ( keyid) == name)
86+ }
87+
7188fn attestation_test ( opts : & Opts , transport : & TransportWrapper ) -> Result < ( ) > {
7289 let uart = transport. uart ( "console" ) ?;
7390 let capture = UartConsole :: wait_for (
@@ -91,20 +108,26 @@ fn attestation_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> {
91108
92109 let image = Image :: read_from_file ( opts. init . bootstrap . bootstrap . as_deref ( ) . unwrap ( ) ) ?;
93110
94- // TODO: determine the correct endianness for expressing these measurements.
95111 let measurements = image
96112 . subimages ( ) ?
97113 . iter ( )
98- . map ( |s| s. compute_digest ( ) . unwrap ( ) . to_le_bytes ( ) )
114+ . map ( |s| s. compute_digest ( ) . unwrap ( ) . to_be_bytes ( ) )
99115 . collect :: < Vec < _ > > ( ) ;
100116 let owner_measurements = [
101117 // The owner page digests should not include the signature or seal fields.
102- sha256:: sha256 ( & owner_page_0[ 0 ..OwnerBlock :: SIGNATURE_OFFSET ] ) . to_le_bytes ( ) ,
103- sha256:: sha256 ( & owner_page_1[ 0 ..OwnerBlock :: SIGNATURE_OFFSET ] ) . to_le_bytes ( ) ,
118+ sha256:: sha256 ( & owner_page_0[ 0 ..OwnerBlock :: SIGNATURE_OFFSET ] ) . to_be_bytes ( ) ,
119+ sha256:: sha256 ( & owner_page_1[ 0 ..OwnerBlock :: SIGNATURE_OFFSET ] ) . to_be_bytes ( ) ,
104120 ] ;
105121
106122 let CertificateExtension :: DiceTcbInfo ( dice) = & cdi0. private_extensions [ 0 ] ;
107- log:: info!( "Checking CDI_0 (ROM_EXT) DICE Extension: {dice:#?}" ) ;
123+ log:: info!( "Checking CDI_0 (ROM_EXT) DICE certificate: {cdi0:#?}" ) ;
124+ // Check that the subject key and subject key identifiers match.
125+ log:: info!( "Subject key:" ) ;
126+ assert ! ( check_public_key(
127+ & cdi0. subject_public_key_info,
128+ cdi0. subject_key_identifier. get_value( ) ,
129+ & cdi0. subject,
130+ ) ?) ;
108131 assert_eq ! ( dice. model. get_value( ) , "ROM_EXT" ) ;
109132 assert_eq ! ( dice. vendor. get_value( ) , "OpenTitan" ) ;
110133 assert_eq ! ( dice. layer. get_value( ) , & BigUint :: from( 1u8 ) ) ;
@@ -113,7 +136,21 @@ fn attestation_test(opts: &Opts, transport: &TransportWrapper) -> Result<()> {
113136 assert_eq ! ( fw_ids[ 0 ] . digest. get_value( ) , & measurements[ 0 ] ) ;
114137
115138 let CertificateExtension :: DiceTcbInfo ( dice) = & cdi1. private_extensions [ 0 ] ;
116- log:: info!( "Checking CDI_1 (Owner) DICE Extension: {dice:#?}" ) ;
139+ log:: info!( "Checking CDI_1 (Owner) DICE certificate: {cdi1:#?}" ) ;
140+ // Check that the subject key and subject key identifiers match.
141+ log:: info!( "Subject key:" ) ;
142+ assert ! ( check_public_key(
143+ & cdi1. subject_public_key_info,
144+ cdi1. subject_key_identifier. get_value( ) ,
145+ & cdi1. subject,
146+ ) ?) ;
147+ // Check that the authority key identifier of CDI_1 is the subject key of CDI_0.
148+ log:: info!( "Issuer key:" ) ;
149+ assert ! ( check_public_key(
150+ & cdi0. subject_public_key_info,
151+ cdi1. authority_key_identifier. get_value( ) ,
152+ & cdi1. issuer,
153+ ) ?) ;
117154 assert_eq ! ( dice. model. get_value( ) , "Owner" ) ;
118155 assert_eq ! ( dice. vendor. get_value( ) , "OpenTitan" ) ;
119156 assert_eq ! ( dice. layer. get_value( ) , & BigUint :: from( 2u8 ) ) ;
0 commit comments