@@ -60,13 +60,13 @@ pub enum EvidenceData {
6060 meta : Option < JsonValue > ,
6161 } ,
6262 UefiLog {
63- entries : String ,
63+ entries : Option < String > ,
6464 #[ serde( skip_serializing_if = "Option::is_none" ) ]
6565 meta : Option < JsonValue > ,
6666 } ,
6767 ImaLog {
6868 entry_count : usize ,
69- entries : String ,
69+ entries : Option < String > ,
7070 #[ serde( skip_serializing_if = "Option::is_none" ) ]
7171 meta : Option < JsonValue > ,
7272 } ,
@@ -110,10 +110,19 @@ impl TryFrom<JsonValue> for EvidenceData {
110110 as usize ;
111111 let entries = value
112112 . get ( "entries" )
113- . ok_or_else ( || "Missing entries field" . to_string ( ) ) ?
114- . as_str ( )
115- . ok_or_else ( || "Invalid entries field" . to_string ( ) ) ?
116- . to_string ( ) ;
113+ . ok_or_else ( || "Missing entries field" . to_string ( ) ) ?;
114+ let entries = if entries. is_null ( ) {
115+ None
116+ } else {
117+ Some (
118+ entries
119+ . as_str ( )
120+ . ok_or_else ( || {
121+ "Invalid entries field" . to_string ( )
122+ } ) ?
123+ . to_string ( ) ,
124+ )
125+ } ;
117126 let meta = value. get ( "meta" ) . cloned ( ) ;
118127 return Ok ( EvidenceData :: ImaLog {
119128 entry_count,
@@ -123,19 +132,21 @@ impl TryFrom<JsonValue> for EvidenceData {
123132 } else {
124133 return Err ( "Invalid entry_count field" . to_string ( ) ) ;
125134 }
126- } else if let Some ( entries ) = value. get ( "entries" ) {
127- if entries. is_string ( ) {
128- let entries = value
129- . get ( "entries" )
130- . unwrap ( ) //#[allow_ci]
131- . as_str ( )
132- . unwrap ( ) //#[allow_ci]
133- . to_string ( ) ;
134- let meta = value . get ( "meta" ) . cloned ( ) ;
135- return Ok ( EvidenceData :: UefiLog { entries , meta } ) ;
135+ } else if let Some ( entries_value ) = value. get ( "entries" ) {
136+ let entries = if entries_value . is_null ( ) {
137+ None
138+ } else if entries_value . is_string ( ) {
139+ Some (
140+ entries_value
141+ . as_str ( )
142+ . ok_or_else ( || "Invalid entries field" . to_string ( ) ) ?
143+ . to_string ( ) ,
144+ )
136145 } else {
137146 return Err ( "Invalid entries field" . to_string ( ) ) ;
138- }
147+ } ;
148+ let meta = value. get ( "meta" ) . cloned ( ) ;
149+ return Ok ( EvidenceData :: UefiLog { entries, meta } ) ;
139150 } ;
140151 Err ( "Failed to deserialize EvidenceData" . to_string ( ) )
141152 }
@@ -213,7 +224,8 @@ impl From<EvidenceData> for EvidenceCollected {
213224 } ,
214225 EvidenceData :: ImaLog { entries, meta, .. } => {
215226 // Count the number of entries (lines)
216- let entry_count = entries. lines ( ) . count ( ) ;
227+ let entry_count =
228+ entries. as_ref ( ) . map_or ( 0 , |e| e. lines ( ) . count ( ) ) ;
217229 EvidenceCollected {
218230 evidence_class : "log" . to_string ( ) ,
219231 evidence_type : "ima_log" . to_string ( ) ,
@@ -322,7 +334,7 @@ mod tests {
322334 // Test ImaLog conversion
323335 let ima_evidence = EvidenceData :: ImaLog {
324336 entry_count : 0 , // This should be recalculated
325- entries : "line1\n line2\n line3" . to_string ( ) ,
337+ entries : Some ( "line1\n line2\n line3" . to_string ( ) ) ,
326338 meta : None ,
327339 } ;
328340 let ima_collected: EvidenceCollected = ima_evidence. into ( ) ;
@@ -335,21 +347,21 @@ mod tests {
335347 } = ima_collected. data
336348 {
337349 assert_eq ! ( entry_count, 3 ) ; // Should be recalculated from lines
338- assert_eq ! ( entries, "line1\n line2\n line3" ) ;
350+ assert_eq ! ( entries, Some ( "line1\n line2\n line3" . to_string ( ) ) ) ;
339351 } else {
340352 panic ! ( "Expected ImaLog" ) ; //#[allow_ci]
341353 }
342354
343355 // Test UefiLog conversion
344356 let uefi_evidence = EvidenceData :: UefiLog {
345- entries : "uefi_entries" . to_string ( ) ,
357+ entries : Some ( "uefi_entries" . to_string ( ) ) ,
346358 meta : None ,
347359 } ;
348360 let uefi_collected: EvidenceCollected = uefi_evidence. into ( ) ;
349361 assert_eq ! ( uefi_collected. evidence_class, "log" ) ;
350362 assert_eq ! ( uefi_collected. evidence_type, "uefi_log" ) ;
351363 if let EvidenceData :: UefiLog { entries, .. } = uefi_collected. data {
352- assert_eq ! ( entries, "uefi_entries" ) ;
364+ assert_eq ! ( entries, Some ( "uefi_entries" . to_string ( ) ) ) ;
353365 } else {
354366 panic ! ( "Expected UefiLog" ) ; //#[allow_ci]
355367 }
@@ -371,7 +383,7 @@ mod tests {
371383 } ;
372384
373385 let uefi_evidence_data = EvidenceData :: UefiLog {
374- entries : "uefi_log_entries" . to_string ( ) ,
386+ entries : Some ( "uefi_log_entries" . to_string ( ) ) ,
375387 meta : None ,
376388 } ;
377389 let uefi_evidence_collected = EvidenceCollected {
@@ -382,7 +394,7 @@ mod tests {
382394
383395 let ima_evidence_data = EvidenceData :: ImaLog {
384396 entry_count : 95 ,
385- entries : "ima_log_entries" . to_string ( ) ,
397+ entries : Some ( "ima_log_entries" . to_string ( ) ) ,
386398 meta : None ,
387399 } ;
388400 let ima_evidence_collected = EvidenceCollected {
@@ -517,7 +529,10 @@ mod tests {
517529 if let EvidenceData :: UefiLog { entries, .. } =
518530 & deserialized. data . attributes . evidence_collected [ 1 ] . data
519531 {
520- assert_eq ! ( entries, "uefi_log_entries_deserialized" ) ;
532+ assert_eq ! (
533+ entries,
534+ & Some ( "uefi_log_entries_deserialized" . to_string( ) )
535+ ) ;
521536 } else {
522537 panic ! ( "Expected UefiLog" ) ; //#[allow_ci]
523538 }
@@ -536,7 +551,10 @@ mod tests {
536551 } = & deserialized. data . attributes . evidence_collected [ 2 ] . data
537552 {
538553 assert_eq ! ( * entry_count, 96 ) ;
539- assert_eq ! ( entries, "ima_log_entries_deserialized" ) ;
554+ assert_eq ! (
555+ entries,
556+ & Some ( "ima_log_entries_deserialized" . to_string( ) )
557+ ) ;
540558 } else {
541559 panic ! ( "Expected ImaLog" ) ; //#[allow_ci]
542560 }
@@ -955,7 +973,7 @@ mod tests {
955973 ) ) ,
956974 ) ,
957975 data: EvidenceData :: UefiLog {
958- entries: "uefi_log_entries" . to_string( ) ,
976+ entries: Some ( "uefi_log_entries" . to_string( ) ) ,
959977 meta: None ,
960978 } ,
961979 } ,
@@ -980,7 +998,7 @@ mod tests {
980998 ) ) ,
981999 data: EvidenceData :: ImaLog {
9821000 entry_count: 96 ,
983- entries: "ima_log_entries" . to_string( ) ,
1001+ entries: Some ( "ima_log_entries" . to_string( ) ) ,
9841002 meta: None ,
9851003 } ,
9861004 } ,
@@ -1441,7 +1459,7 @@ mod tests {
14411459 if let EvidenceData :: UefiLog { entries, .. } =
14421460 & deserialized. data . attributes . evidence [ 1 ] . data
14431461 {
1444- assert_eq ! ( entries, "uefi_log_entries" ) ;
1462+ assert_eq ! ( entries, & Some ( "uefi_log_entries" . to_string ( ) ) ) ;
14451463 } else {
14461464 panic ! ( "Expected UefiLog" ) ; //#[allow_ci]
14471465 }
@@ -1475,4 +1493,148 @@ mod tests {
14751493 "2025-08-07 12:22:17.228706 UTC"
14761494 ) ;
14771495 } //serialize_evidence_handling_response
1496+
1497+ #[ test]
1498+ fn deserialize_evidence_handling_request_null_entries_uefi ( ) {
1499+ let json = r#"{
1500+ "data": {
1501+ "type": "attestation",
1502+ "attributes": {
1503+ "evidence_collected": [
1504+ {
1505+ "evidence_class": "log",
1506+ "evidence_type": "uefi_log",
1507+ "data": {
1508+ "entries": null
1509+ }
1510+ }
1511+ ]
1512+ }
1513+ }
1514+ }"# ;
1515+ let deserialized: EvidenceHandlingRequest =
1516+ serde_json:: from_str ( json) . unwrap ( ) ; //#[allow_ci]
1517+
1518+ assert_eq ! ( deserialized. data. data_type, "attestation" ) ;
1519+ assert_eq ! ( deserialized. data. attributes. evidence_collected. len( ) , 1 ) ;
1520+ assert_eq ! (
1521+ deserialized. data. attributes. evidence_collected[ 0 ] . evidence_class,
1522+ "log"
1523+ ) ;
1524+ assert_eq ! (
1525+ deserialized. data. attributes. evidence_collected[ 0 ] . evidence_type,
1526+ "uefi_log"
1527+ ) ;
1528+ if let EvidenceData :: UefiLog { entries, .. } =
1529+ & deserialized. data . attributes . evidence_collected [ 0 ] . data
1530+ {
1531+ assert ! ( entries. is_none( ) ) ;
1532+ } else {
1533+ panic ! ( "Expected UefiLog" ) ; //#[allow_ci]
1534+ }
1535+ }
1536+
1537+ #[ test]
1538+ fn deserialize_evidence_handling_request_null_entries_ima ( ) {
1539+ let json = r#"{
1540+ "data": {
1541+ "type": "attestation",
1542+ "attributes": {
1543+ "evidence_collected": [
1544+ {
1545+ "evidence_class": "log",
1546+ "evidence_type": "ima_log",
1547+ "data": {
1548+ "entries": null,
1549+ "entry_count": 0
1550+ }
1551+ }
1552+ ]
1553+ }
1554+ }
1555+ }"# ;
1556+ let deserialized: EvidenceHandlingRequest =
1557+ serde_json:: from_str ( json) . unwrap ( ) ; //#[allow_ci]
1558+
1559+ assert_eq ! ( deserialized. data. data_type, "attestation" ) ;
1560+ assert_eq ! ( deserialized. data. attributes. evidence_collected. len( ) , 1 ) ;
1561+ assert_eq ! (
1562+ deserialized. data. attributes. evidence_collected[ 0 ] . evidence_class,
1563+ "log"
1564+ ) ;
1565+ assert_eq ! (
1566+ deserialized. data. attributes. evidence_collected[ 0 ] . evidence_type,
1567+ "ima_log"
1568+ ) ;
1569+ if let EvidenceData :: ImaLog {
1570+ entries,
1571+ entry_count,
1572+ ..
1573+ } = & deserialized. data . attributes . evidence_collected [ 0 ] . data
1574+ {
1575+ assert ! ( entries. is_none( ) ) ;
1576+ assert_eq ! ( * entry_count, 0 ) ;
1577+ } else {
1578+ panic ! ( "Expected ImaLog" ) ; //#[allow_ci]
1579+ }
1580+ }
1581+
1582+ #[ test]
1583+ fn serialize_evidence_data_null_entries ( ) {
1584+ // Test serialization of UefiLog with null entries
1585+ let uefi_evidence = EvidenceData :: UefiLog {
1586+ entries : None ,
1587+ meta : None ,
1588+ } ;
1589+ let serialized = serde_json:: to_string ( & uefi_evidence) . unwrap ( ) ; //#[allow_ci]
1590+ assert ! ( serialized. contains( "\" entries\" :null" ) ) ;
1591+
1592+ // Test serialization of ImaLog with null entries
1593+ let ima_evidence = EvidenceData :: ImaLog {
1594+ entry_count : 0 ,
1595+ entries : None ,
1596+ meta : None ,
1597+ } ;
1598+ let serialized = serde_json:: to_string ( & ima_evidence) . unwrap ( ) ; //#[allow_ci]
1599+ assert ! ( serialized. contains( "\" entries\" :null" ) ) ;
1600+ assert ! ( serialized. contains( "\" entry_count\" :0" ) ) ;
1601+ }
1602+
1603+ #[ test]
1604+ fn evidence_data_to_evidence_collected_null_entries ( ) {
1605+ // Test ImaLog with null entries conversion
1606+ let ima_evidence = EvidenceData :: ImaLog {
1607+ entry_count : 0 ,
1608+ entries : None ,
1609+ meta : None ,
1610+ } ;
1611+ let ima_collected: EvidenceCollected = ima_evidence. into ( ) ;
1612+ assert_eq ! ( ima_collected. evidence_class, "log" ) ;
1613+ assert_eq ! ( ima_collected. evidence_type, "ima_log" ) ;
1614+ if let EvidenceData :: ImaLog {
1615+ entry_count,
1616+ entries,
1617+ ..
1618+ } = ima_collected. data
1619+ {
1620+ assert_eq ! ( entry_count, 0 ) ; // Should be 0 for null entries
1621+ assert ! ( entries. is_none( ) ) ;
1622+ } else {
1623+ panic ! ( "Expected ImaLog" ) ; //#[allow_ci]
1624+ }
1625+
1626+ // Test UefiLog with null entries conversion
1627+ let uefi_evidence = EvidenceData :: UefiLog {
1628+ entries : None ,
1629+ meta : None ,
1630+ } ;
1631+ let uefi_collected: EvidenceCollected = uefi_evidence. into ( ) ;
1632+ assert_eq ! ( uefi_collected. evidence_class, "log" ) ;
1633+ assert_eq ! ( uefi_collected. evidence_type, "uefi_log" ) ;
1634+ if let EvidenceData :: UefiLog { entries, .. } = uefi_collected. data {
1635+ assert ! ( entries. is_none( ) ) ;
1636+ } else {
1637+ panic ! ( "Expected UefiLog" ) ; //#[allow_ci]
1638+ }
1639+ }
14781640}
0 commit comments