Coverage Report

Created: 2025-10-28 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spdm-rs/spdmlib/src/crypto/x509v3.rs
Line
Count
Source
1
// Copyright (c) 2023 Intel Corporation
2
//
3
// SPDX-License-Identifier: Apache-2.0 or MIT
4
5
use crate::error::{SpdmResult, SPDM_STATUS_VERIF_FAIL};
6
use crate::protocol::SpdmBaseAsymAlgo;
7
8
// Key Usage: Digital Signature Bit;
9
const RFC_5280_KEY_USAGE_DIGITAL_SIGNATURE_BIT: u8 = 0x80;
10
// reference: https://www.itu.int/rec/T-REC-X.690/en
11
// TAG
12
const ASN1_TAG_CLASS_UNIVERSAL_MASK: u8 = 0x0;
13
const ASN1_TAG_CLASS_CONTEXT_SPECIFIC_MASK: u8 = 0x80;
14
15
const ASN1_FORM_CONSTRUCTED_MASK: u8 = 0x20;
16
17
const ASN1_TAG_BOOLEAN: u8 = 0x1;
18
const ASN1_TAG_NUMBER_INTEGER: u8 = 0x2;
19
const ASN1_TAG_BIT_STRING: u8 = 0x3;
20
const ASN1_TAG_OCTET_STRING: u8 = 0x4;
21
const ASN1_TAG_NUMBER_OBJECT_IDENTIFIER: u8 = 0x6;
22
const ASN1_TAG_NUMBER_SEQUENCE: u8 = 0x10;
23
24
const ASN1_TAG_SEQUENCE: u8 =
25
    ASN1_TAG_CLASS_UNIVERSAL_MASK | ASN1_FORM_CONSTRUCTED_MASK | ASN1_TAG_NUMBER_SEQUENCE;
26
const ASN1_TAG_EXPLICIT_EXTENSION: u8 = 0xA3;
27
const ASN1_TAG_EXTN_VALUE: u8 = 0x04;
28
const ASN1_LENGTH_MULTI_OCTET_MASK: u8 = 0x80;
29
const ASN1_LENGTH_ONE_OCTET: u8 = 0x81;
30
const ASN1_LENGTH_TWO_OCTET: u8 = 0x82;
31
32
const X509V3_VERSION: u8 = 2;
33
const OID_RSA_SHA256RSA: &[u8] = &[0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0bu8];
34
const OID_RSA_SHA384RSA: &[u8] = &[0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0cu8];
35
const OID_RSA_SHA512RSA: &[u8] = &[0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0du8];
36
const OID_ECDSA_SHA256: &[u8] = &[0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02u8];
37
const OID_ECDSA_SHA384: &[u8] = &[0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03u8];
38
const OID_DMTF_SPDM_DEVICE_INFO: &[u8] =
39
    &[0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x01];
40
const OID_DMTF_SPDM_HARDWARE_IDENTITY: &[u8] =
41
    &[0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x02];
42
const OID_DMTF_SPDM_EKU_RESPONDER_AUTH: &[u8] =
43
    &[0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x03];
44
const OID_DMTF_SPDM_EKU_REQUESTER_AUTH: &[u8] =
45
    &[0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x04];
46
const OID_DMTF_MUTABLE_CERTIFICATE: &[u8] =
47
    &[0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x05];
48
const OID_DMTF_SPDM_EXTENSION: &[u8] =
49
    &[0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x06];
50
const OID_KEY_USAGE: &[u8] = &[0x55, 0x1D, 0x0F];
51
const OID_SUBJECT_ALTERNATIVE_NAME: &[u8] = &[0x55, 0x1D, 0x11];
52
const OID_EXT_KEY_USAGE: &[u8] = &[0x55, 0x1D, 0x25];
53
54
// reference: https://www.rfc-editor.org/rfc/rfc5280.txt
55
// IN DER encoded certificate chain slice
56
// OUT Ok certificate count
57
// OUT Error Mulformed certificate found
58
// checked:
59
// 1. version should be x509v3.
60
// 2. the algorithm is match for leaf certificate
61
// 3. no more or less bytes found
62
0
pub fn check_cert_chain_format(
63
0
    cert_chain: &[u8],
64
0
    base_asym_algo: SpdmBaseAsymAlgo,
65
0
) -> SpdmResult<usize> {
66
0
    let mut cc_walker = 0usize;
67
0
    let mut cert_count = 0usize;
68
0
    let cert_chain_size = cert_chain.len();
69
70
0
    while cc_walker < cert_chain_size {
71
0
        cc_walker = cc_walker + check_cert_format(&cert_chain[cc_walker..], base_asym_algo)?;
72
0
        cert_count += 1;
73
    }
74
75
0
    if cc_walker == cert_chain_size {
76
0
        Ok(cert_count)
77
    } else {
78
0
        Err(SPDM_STATUS_VERIF_FAIL)
79
    }
80
0
}
81
82
// IN DER encoded certificate slice
83
// OUT Ok cert size
84
// OUT Error Mulformed certificate found
85
0
fn check_cert_format(cert: &[u8], base_asym_algo: SpdmBaseAsymAlgo) -> SpdmResult<usize> {
86
0
    let mut c_walker = 0usize;
87
0
    let len = cert.len();
88
89
0
    check_tag_is_sequence(cert)?;
90
0
    c_walker += 1;
91
92
0
    let (body_size, bytes_consumed) = check_length(&cert[c_walker..])?;
93
0
    c_walker += bytes_consumed;
94
95
0
    if len == c_walker + body_size {
96
0
        c_walker += check_tbs_certificate(&cert[c_walker..], base_asym_algo, true)?;
97
0
        c_walker += check_signature_algorithm(&cert[c_walker..], base_asym_algo, true)?;
98
    } else {
99
0
        c_walker += check_tbs_certificate(&cert[c_walker..], base_asym_algo, false)?;
100
0
        c_walker += check_signature_algorithm(&cert[c_walker..], base_asym_algo, false)?;
101
    }
102
103
0
    c_walker += check_signature_value(&cert[c_walker..], base_asym_algo)?;
104
105
0
    if c_walker == 1 + bytes_consumed + body_size {
106
0
        Ok(c_walker)
107
    } else {
108
0
        Err(SPDM_STATUS_VERIF_FAIL)
109
    }
110
0
}
111
112
0
fn check_tbs_certificate(
113
0
    data: &[u8],
114
0
    base_asym_algo: SpdmBaseAsymAlgo,
115
0
    is_leaf_cert: bool,
116
0
) -> SpdmResult<usize> {
117
0
    let mut t_walker = 0usize;
118
0
    let len = data.len();
119
120
0
    check_tag_is_sequence(data)?;
121
0
    t_walker += 1;
122
123
0
    let (tbs_length, bytes_consumed) = check_length(&data[t_walker..])?;
124
0
    t_walker += bytes_consumed;
125
126
0
    let length_before_tbs = t_walker;
127
128
0
    if len < t_walker + tbs_length {
129
0
        return Err(SPDM_STATUS_VERIF_FAIL);
130
0
    }
131
132
    // version         [0]  EXPLICIT Version DEFAULT v1,
133
0
    let bytes_consumed = check_version(&data[t_walker..])?;
134
0
    t_walker += bytes_consumed;
135
136
    // serialNumber         CertificateSerialNumber,
137
0
    let bytes_consumed = check_and_skip_common_tag(&data[t_walker..])?;
138
0
    t_walker += bytes_consumed;
139
140
    // signature            AlgorithmIdentifier,
141
0
    check_tag_is_sequence(&data[t_walker..])?;
142
0
    t_walker += 1;
143
0
    let (signature_id_length, bytes_consumed) = check_length(&data[t_walker..])?;
144
0
    t_walker += bytes_consumed;
145
146
0
    if is_leaf_cert {
147
0
        check_object_identifier(&data[t_walker..], get_oid_by_base_asym_algo(base_asym_algo))?;
148
    } else {
149
0
        check_object_identifier(&data[t_walker..], None)?;
150
    }
151
0
    t_walker += signature_id_length;
152
    // issuer               Name,
153
0
    let bytes_consumed = check_name(&data[t_walker..])?;
154
0
    t_walker += bytes_consumed;
155
156
    // validity             Validity,
157
0
    let bytes_consumed = check_validity(&data[t_walker..])?;
158
0
    t_walker += bytes_consumed;
159
160
    // subject              Name,
161
0
    let bytes_consumed = check_name(&data[t_walker..])?;
162
0
    t_walker += bytes_consumed;
163
164
    // subjectPublicKeyInfo SubjectPublicKeyInfo,
165
0
    let bytes_consumed = check_public_key_info(&data[t_walker..])?;
166
0
    t_walker += bytes_consumed;
167
168
    // issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
169
    // subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
170
    // extensions      [3]  EXPLICIT Extensions OPTIONAL
171
172
    // key_usage             EXTENSIONS,
173
0
    let (bytes_consumed, extension_data) = check_and_get_extensions(&data[t_walker..])?;
174
0
    let (find_key_usage, key_usage_value) = get_key_usage_value(extension_data)?;
175
    // The digitalSignature bit SHOULD asserted when subject public key is used for verifying digital signatures
176
    // in an entity authentication service, a data origin authentication service, and/or an integrity service.
177
0
    let check_extensions_success = !(find_key_usage
178
0
        && (RFC_5280_KEY_USAGE_DIGITAL_SIGNATURE_BIT & key_usage_value
179
0
            != RFC_5280_KEY_USAGE_DIGITAL_SIGNATURE_BIT));
180
    // when key usage digitalSignature bit unset, it SHOULD return false.
181
182
    //extensions            EXTENSIONS,
183
0
    let check_extn_spdm_success = check_extensions_spdm_oid(extension_data, is_leaf_cert)?;
184
0
    t_walker += bytes_consumed;
185
186
0
    if (t_walker == length_before_tbs + tbs_length)
187
0
        && check_extensions_success
188
0
        && check_extn_spdm_success
189
    {
190
0
        Ok(length_before_tbs + tbs_length)
191
    } else {
192
0
        Err(SPDM_STATUS_VERIF_FAIL)
193
    }
194
0
}
195
196
0
fn check_signature_algorithm(
197
0
    data: &[u8],
198
0
    base_asym_algo: SpdmBaseAsymAlgo,
199
0
    is_leaf_cert: bool,
200
0
) -> SpdmResult<usize> {
201
0
    let mut s_walker = 0usize;
202
    // signature            AlgorithmIdentifier,
203
0
    check_tag_is_sequence(&data[s_walker..])?;
204
0
    s_walker += 1;
205
0
    let (signature_id_length, bytes_consumed) = check_length(&data[s_walker..])?;
206
0
    s_walker += bytes_consumed;
207
208
0
    if is_leaf_cert {
209
0
        check_object_identifier(&data[s_walker..], get_oid_by_base_asym_algo(base_asym_algo))?;
210
    } else {
211
0
        check_object_identifier(&data[s_walker..], None)?;
212
    }
213
214
0
    Ok(s_walker + signature_id_length)
215
0
}
216
217
0
fn check_signature_value(data: &[u8], _base_asym_algo: SpdmBaseAsymAlgo) -> SpdmResult<usize> {
218
0
    check_and_skip_common_tag(data)
219
0
}
220
221
0
fn check_tag_is_sequence(data: &[u8]) -> SpdmResult {
222
0
    if data.is_empty() {
223
0
        Err(SPDM_STATUS_VERIF_FAIL)
224
0
    } else if data[0] == ASN1_TAG_SEQUENCE {
225
0
        Ok(())
226
    } else {
227
0
        Err(SPDM_STATUS_VERIF_FAIL)
228
    }
229
0
}
230
231
0
fn check_tag_is_num_oid(data: &[u8]) -> SpdmResult {
232
0
    if data.is_empty() {
233
0
        Err(SPDM_STATUS_VERIF_FAIL)
234
0
    } else if data[0] == ASN1_TAG_NUMBER_OBJECT_IDENTIFIER {
235
0
        Ok(())
236
    } else {
237
0
        Err(SPDM_STATUS_VERIF_FAIL)
238
    }
239
0
}
240
241
0
fn check_tag_is_bool(data: &[u8]) -> SpdmResult {
242
0
    if data.is_empty() {
243
0
        Err(SPDM_STATUS_VERIF_FAIL)
244
0
    } else if data[0] == ASN1_TAG_BOOLEAN {
245
0
        Ok(())
246
    } else {
247
0
        Err(SPDM_STATUS_VERIF_FAIL)
248
    }
249
0
}
250
251
0
fn check_tag_is_octet_string(data: &[u8]) -> SpdmResult {
252
0
    if data.is_empty() {
253
0
        Err(SPDM_STATUS_VERIF_FAIL)
254
0
    } else if data[0] == ASN1_TAG_OCTET_STRING {
255
0
        Ok(())
256
    } else {
257
0
        Err(SPDM_STATUS_VERIF_FAIL)
258
    }
259
0
}
260
261
// IN bytes slice
262
// OUT Ok (length, bytes consumed)
263
// OUT Error Mulformed certificate found
264
0
fn check_length(data: &[u8]) -> SpdmResult<(usize, usize)> {
265
0
    let len = data.len();
266
0
    if len < 1 {
267
0
        Err(SPDM_STATUS_VERIF_FAIL)
268
    } else {
269
0
        let length_byte0 = data[0];
270
0
        let (length, byte_comsumed) = match length_byte0 {
271
0
            n if (n & ASN1_LENGTH_MULTI_OCTET_MASK) == 0 => (n as usize, 1),
272
            ASN1_LENGTH_ONE_OCTET => {
273
0
                if len < 2 {
274
0
                    return Err(SPDM_STATUS_VERIF_FAIL);
275
                } else {
276
0
                    let second_byte = data[1] as usize;
277
0
                    if second_byte < 0x80 {
278
0
                        return Err(SPDM_STATUS_VERIF_FAIL); // Not the canonical encoding.
279
                    } else {
280
0
                        (second_byte, 2)
281
                    }
282
                }
283
            }
284
            ASN1_LENGTH_TWO_OCTET => {
285
0
                if len < 3 {
286
0
                    return Err(SPDM_STATUS_VERIF_FAIL);
287
                } else {
288
0
                    let second_byte = data[1] as usize;
289
0
                    let third_byte = data[2] as usize;
290
291
0
                    let combined = (second_byte << 8) | third_byte;
292
0
                    if combined < 0x100 {
293
0
                        return Err(SPDM_STATUS_VERIF_FAIL); // Not the canonical encoding.
294
                    } else {
295
0
                        (combined, 3)
296
                    }
297
                }
298
            }
299
            _ => {
300
0
                return Err(SPDM_STATUS_VERIF_FAIL); // spdm-rs don't support longer lengths.
301
            }
302
        };
303
304
0
        if len < byte_comsumed + length {
305
0
            Err(SPDM_STATUS_VERIF_FAIL)
306
        } else {
307
0
            Ok((length, byte_comsumed))
308
        }
309
    }
310
0
}
311
312
0
fn check_version(data: &[u8]) -> SpdmResult<usize> {
313
0
    let len = data.len();
314
0
    if len < 5
315
0
        || data[0] != (ASN1_TAG_CLASS_CONTEXT_SPECIFIC_MASK | ASN1_FORM_CONSTRUCTED_MASK)
316
0
        || data[1] != 3
317
0
        || data[2] != ASN1_TAG_NUMBER_INTEGER
318
0
        || data[3] != 1
319
    {
320
0
        Err(SPDM_STATUS_VERIF_FAIL)
321
    } else {
322
0
        let version = data[4];
323
0
        if version == X509V3_VERSION {
324
0
            Ok(5)
325
        } else {
326
0
            Err(SPDM_STATUS_VERIF_FAIL)
327
        }
328
    }
329
0
}
330
331
0
fn check_object_identifier(data: &[u8], oid: Option<&'static [u8]>) -> SpdmResult<usize> {
332
0
    let len = data.len();
333
0
    if len < 2 || data[0] != ASN1_TAG_NUMBER_OBJECT_IDENTIFIER {
334
0
        Err(SPDM_STATUS_VERIF_FAIL)
335
    } else {
336
0
        let oid_length = data[1];
337
0
        if len < oid_length as usize + 2 || oid_length >= 0x80 {
338
0
            Err(SPDM_STATUS_VERIF_FAIL)
339
0
        } else if let Some(oid) = oid {
340
0
            if object_identifiers_are_same(&data[2..2 + oid_length as usize], oid) {
341
0
                Ok(oid_length as usize + 2)
342
            } else {
343
0
                Err(SPDM_STATUS_VERIF_FAIL)
344
            }
345
        } else {
346
0
            Ok(oid_length as usize + 2)
347
        }
348
    }
349
0
}
350
351
0
fn check_name(data: &[u8]) -> SpdmResult<usize> {
352
0
    check_and_skip_common_sequence(data)
353
0
}
354
355
0
fn check_validity(data: &[u8]) -> SpdmResult<usize> {
356
0
    check_and_skip_common_sequence(data)
357
0
}
358
359
0
fn check_public_key_info(data: &[u8]) -> SpdmResult<usize> {
360
0
    check_and_skip_common_sequence(data)
361
0
}
362
363
0
fn check_and_get_extensions(data: &[u8]) -> SpdmResult<(usize, &[u8])> {
364
0
    let len = data.len();
365
0
    if len < 1 || data[0] != ASN1_TAG_EXPLICIT_EXTENSION {
366
0
        Ok((len, &data[0..]))
367
    } else {
368
0
        let (payload_length, bytes_consumed) = check_length(&data[1..])?;
369
0
        if len < 1 + bytes_consumed + payload_length {
370
0
            Err(SPDM_STATUS_VERIF_FAIL)
371
        } else {
372
0
            Ok((
373
0
                1 + bytes_consumed + payload_length,
374
0
                &data[1 + bytes_consumed..1 + bytes_consumed + payload_length],
375
0
            ))
376
        }
377
    }
378
0
}
379
380
0
fn get_key_usage_value(data: &[u8]) -> SpdmResult<(bool, u8)> {
381
0
    let mut find_key_usage = false;
382
0
    let len = data.len();
383
0
    let key_usage_oid_len = OID_KEY_USAGE.len();
384
0
    if len < 1 || data[0] != ASN1_TAG_SEQUENCE {
385
0
        return Err(SPDM_STATUS_VERIF_FAIL);
386
0
    }
387
0
    let (data_length, bytes_consumed) = check_length(&data[1..])?;
388
0
    if len < 1 + data_length + bytes_consumed {
389
0
        Err(SPDM_STATUS_VERIF_FAIL)
390
    } else {
391
0
        let mut index = 1 + bytes_consumed;
392
        // search KEY_Usage OID in Extensions Sequence
393
0
        while index < len {
394
0
            if index + 1 >= len {
395
0
                return Err(SPDM_STATUS_VERIF_FAIL);
396
0
            }
397
0
            let (payload_length, bytes_consumed) = check_length(&data[index + 1..])?;
398
0
            if bytes_consumed + payload_length > len - (index + 1) {
399
0
                return Err(SPDM_STATUS_VERIF_FAIL);
400
0
            }
401
            // search in sequence, skip bytes consumed
402
0
            if data[index] == ASN1_TAG_SEQUENCE {
403
0
                index += 1 + bytes_consumed;
404
0
                continue;
405
0
            } else if data[index] == ASN1_TAG_NUMBER_OBJECT_IDENTIFIER
406
0
                && payload_length == key_usage_oid_len
407
0
                && object_identifiers_are_same(
408
0
                    &data[index + 1 + bytes_consumed..index + 1 + bytes_consumed + payload_length],
409
0
                    OID_KEY_USAGE,
410
                )
411
            {
412
0
                index += 1 + bytes_consumed + payload_length;
413
0
                if index >= len {
414
0
                    return Err(SPDM_STATUS_VERIF_FAIL);
415
0
                }
416
417
0
                if data[index] == ASN1_TAG_EXTN_VALUE {
418
0
                    if index + 1 >= len {
419
0
                        return Err(SPDM_STATUS_VERIF_FAIL);
420
0
                    }
421
0
                    let (_, extnvalue_consumed) = check_length(&data[index + 1..])?;
422
0
                    index += 1 + extnvalue_consumed;
423
424
0
                    if index >= len {
425
0
                        return Err(SPDM_STATUS_VERIF_FAIL);
426
0
                    }
427
428
0
                    if data[index] == ASN1_TAG_BIT_STRING {
429
0
                        if index + 1 >= len {
430
0
                            return Err(SPDM_STATUS_VERIF_FAIL);
431
0
                        }
432
0
                        let (string_length, string_consumed) = check_length(&data[index + 1..])?;
433
0
                        index += string_consumed + string_length;
434
435
0
                        if index >= len {
436
0
                            return Err(SPDM_STATUS_VERIF_FAIL);
437
0
                        }
438
0
                        find_key_usage = true;
439
0
                    } else {
440
0
                        find_key_usage = false;
441
0
                    }
442
0
                    break;
443
                } else {
444
0
                    return Err(SPDM_STATUS_VERIF_FAIL);
445
                }
446
            } else {
447
                // if not Sequence or OID tag, skip
448
0
                index += 1 + bytes_consumed + payload_length;
449
0
                continue;
450
            }
451
        }
452
0
        if find_key_usage {
453
0
            Ok((true, data[index]))
454
        } else {
455
0
            Ok((false, 0x00))
456
        }
457
    }
458
0
}
459
460
0
fn check_extensions_spdm_oid(extensions: &[u8], is_leaf_cert: bool) -> SpdmResult<bool> {
461
0
    let mut responder_auth_oid_find_success = false;
462
0
    let mut requester_auth_oid_find_success = false;
463
0
    let len = extensions.len();
464
0
    if len < 1 || extensions[0] != ASN1_TAG_SEQUENCE {
465
0
        Err(SPDM_STATUS_VERIF_FAIL)
466
    } else {
467
0
        let (payload_length, sequences_bytes_consumed) = check_length(&extensions[1..])?;
468
0
        let extn_sequences = &extensions[1 + sequences_bytes_consumed..];
469
0
        let sequences_len = extn_sequences.len();
470
0
        if sequences_len < payload_length {
471
0
            Err(SPDM_STATUS_VERIF_FAIL)
472
        } else {
473
0
            let mut index = 0;
474
0
            while index < payload_length {
475
0
                let (extnid, extn_sequence_len) = check_and_get_extn_id(&extn_sequences[index..])?;
476
0
                if extn_sequence_len > payload_length - index {
477
0
                    return Err(SPDM_STATUS_VERIF_FAIL);
478
0
                }
479
                // find the first level extension identifiy from extensions sequence
480
0
                if object_identifiers_are_same(extnid, OID_SUBJECT_ALTERNATIVE_NAME) {
481
0
                    if find_target_object_identifier_in_single_extension(
482
0
                        &extn_sequences[index..index + extn_sequence_len],
483
0
                        OID_DMTF_SPDM_DEVICE_INFO,
484
0
                    )? {
485
0
                        info!("find id-DMTF-device-info OID\n");
486
0
                    }
487
0
                    index += extn_sequence_len;
488
0
                    continue;
489
0
                } else if object_identifiers_are_same(extnid, OID_EXT_KEY_USAGE) {
490
0
                    if find_target_object_identifier_in_single_extension(
491
0
                        &extn_sequences[index..index + extn_sequence_len],
492
0
                        OID_DMTF_SPDM_EKU_RESPONDER_AUTH,
493
0
                    )? {
494
0
                        responder_auth_oid_find_success = true;
495
0
                        info!("find id-DMTF-eku-responder-auth OID\n");
496
0
                    } else if find_target_object_identifier_in_single_extension(
497
0
                        &extn_sequences[index..index + extn_sequence_len],
498
0
                        OID_DMTF_SPDM_EKU_REQUESTER_AUTH,
499
0
                    )? {
500
0
                        requester_auth_oid_find_success = true;
501
0
                        info!("find id-DMTF-eku-requester-auth OID\n");
502
0
                    }
503
0
                    index += extn_sequence_len;
504
0
                    continue;
505
0
                } else if object_identifiers_are_same(extnid, OID_DMTF_SPDM_EXTENSION) {
506
0
                    if find_target_object_identifier_in_single_extension(
507
0
                        &extn_sequences[index..index + extn_sequence_len],
508
0
                        OID_DMTF_MUTABLE_CERTIFICATE,
509
0
                    )? {
510
0
                        info!("find id-DMTF-mutable-certificate OID\n");
511
0
                    } else if find_target_object_identifier_in_single_extension(
512
0
                        &extn_sequences[index..index + extn_sequence_len],
513
0
                        OID_DMTF_SPDM_HARDWARE_IDENTITY,
514
0
                    )? {
515
0
                        info!("find id-DMTF-hardware-identity OID\n");
516
0
                    }
517
0
                    index += extn_sequence_len;
518
0
                    continue;
519
                } else {
520
0
                    index += extn_sequence_len;
521
0
                    continue;
522
                }
523
            }
524
            // if not the leaf certificate, reuester/responder auth OIDs SHOULD not be presented.
525
0
            Ok(!(!is_leaf_cert
526
0
                && (responder_auth_oid_find_success || requester_auth_oid_find_success)))
527
        }
528
    }
529
0
}
530
531
// IN  (sequences slice, target oid)
532
// OUT true when find target oid
533
// OUT false when not find target oid
534
0
fn find_target_object_identifier_in_single_extension(
535
0
    data: &[u8],
536
0
    target_oid: &[u8],
537
0
) -> SpdmResult<bool> {
538
0
    let mut target_oid_find_success = false;
539
0
    let len = data.len();
540
0
    let target_oid_len = target_oid.len();
541
0
    if len < 1 {
542
0
        Err(SPDM_STATUS_VERIF_FAIL)
543
0
    } else if len < target_oid_len {
544
0
        target_oid_find_success = false;
545
0
        Ok(target_oid_find_success)
546
    } else {
547
0
        let mut index = 0;
548
0
        while index < len - target_oid_len {
549
0
            if index + 1 >= len {
550
0
                return Err(SPDM_STATUS_VERIF_FAIL);
551
0
            }
552
0
            let (payload_length, bytes_consumed) = check_length(&data[index + 1..])?;
553
0
            if bytes_consumed + payload_length > len - (index + 1) {
554
0
                return Err(SPDM_STATUS_VERIF_FAIL);
555
0
            }
556
0
            if data[index] == ASN1_TAG_NUMBER_OBJECT_IDENTIFIER {
557
0
                if object_identifiers_are_same(
558
0
                    &data[index + 1 + bytes_consumed..index + 1 + bytes_consumed + payload_length],
559
0
                    target_oid,
560
0
                ) && payload_length == target_oid_len
561
                {
562
0
                    target_oid_find_success = true;
563
0
                    break;
564
                } else {
565
0
                    index += 1 + bytes_consumed + payload_length;
566
0
                    continue;
567
                }
568
0
            } else if data[index] == ASN1_TAG_SEQUENCE || data[index] == ASN1_TAG_EXTN_VALUE {
569
0
                index += 1 + bytes_consumed;
570
0
                continue;
571
            } else {
572
0
                index += 1 + bytes_consumed + payload_length;
573
0
                continue;
574
            }
575
        }
576
0
        Ok(target_oid_find_success)
577
    }
578
0
}
579
580
// IN  extension sequences slice
581
// OUT true when find hardware oid
582
// OUT false when not find hardware oid
583
0
fn find_target_object_identifier_in_extensions(data: &[u8], target_oid: &[u8]) -> SpdmResult<bool> {
584
0
    let len = data.len();
585
0
    let mut walker = 0usize;
586
0
    if walker >= len {
587
0
        return Err(SPDM_STATUS_VERIF_FAIL);
588
0
    }
589
590
0
    check_tag_is_sequence(&data[walker..])?;
591
0
    walker += 1;
592
0
    if walker >= len {
593
0
        return Err(SPDM_STATUS_VERIF_FAIL);
594
0
    }
595
596
0
    let (payload_length, bytes_consumed) = check_length(&data[walker..])?;
597
0
    walker += bytes_consumed;
598
0
    if payload_length > len - walker {
599
0
        return Err(SPDM_STATUS_VERIF_FAIL);
600
0
    }
601
602
0
    let data = &data[walker..walker + payload_length];
603
0
    let len = payload_length;
604
0
    walker = 0;
605
0
    while walker < len {
606
0
        check_tag_is_sequence(&data[walker..])?;
607
0
        walker += 1;
608
0
        if walker >= len {
609
0
            return Err(SPDM_STATUS_VERIF_FAIL);
610
0
        }
611
612
0
        let (extension_length, bytes_consumed) = check_length(&data[walker..])?;
613
0
        walker += bytes_consumed;
614
0
        if walker >= len {
615
0
            return Err(SPDM_STATUS_VERIF_FAIL);
616
0
        }
617
618
0
        let next_ext_walker = walker + extension_length;
619
620
0
        check_tag_is_num_oid(&data[walker..])?;
621
0
        walker += 1;
622
0
        if walker >= len {
623
0
            return Err(SPDM_STATUS_VERIF_FAIL);
624
0
        }
625
626
0
        let (payload_length, bytes_consumed) = check_length(&data[walker..])?;
627
0
        walker += bytes_consumed;
628
0
        if walker >= len {
629
0
            return Err(SPDM_STATUS_VERIF_FAIL);
630
0
        }
631
632
0
        if walker + payload_length < len
633
0
            && object_identifiers_are_same(
634
0
                &data[walker..walker + payload_length],
635
0
                OID_DMTF_SPDM_EXTENSION,
636
            )
637
        {
638
0
            walker += payload_length;
639
0
            if walker >= len {
640
0
                return Err(SPDM_STATUS_VERIF_FAIL);
641
0
            }
642
643
            // check critical, it is optional
644
0
            if check_tag_is_bool(&data[walker..]).is_ok() {
645
0
                walker += 3; // tag, length, value
646
0
                if walker >= len {
647
0
                    return Err(SPDM_STATUS_VERIF_FAIL);
648
0
                }
649
0
            }
650
651
            // next find hardware oid
652
0
            check_tag_is_octet_string(&data[walker..])?;
653
0
            walker += 1;
654
0
            if walker >= len {
655
0
                return Err(SPDM_STATUS_VERIF_FAIL);
656
0
            }
657
658
0
            let (_, bytes_consumed) = check_length(&data[walker..])?;
659
0
            walker += bytes_consumed;
660
0
            if walker >= len {
661
0
                return Err(SPDM_STATUS_VERIF_FAIL);
662
0
            }
663
664
            // sequence
665
0
            check_tag_is_sequence(&data[walker..])?;
666
0
            walker += 1;
667
0
            if walker >= len {
668
0
                return Err(SPDM_STATUS_VERIF_FAIL);
669
0
            }
670
671
0
            let (_, bytes_consumed) = check_length(&data[walker..])?;
672
0
            walker += bytes_consumed;
673
0
            if walker >= len {
674
0
                return Err(SPDM_STATUS_VERIF_FAIL);
675
0
            }
676
677
            // sequence
678
0
            check_tag_is_sequence(&data[walker..])?;
679
0
            walker += 1;
680
0
            if walker >= len {
681
0
                return Err(SPDM_STATUS_VERIF_FAIL);
682
0
            }
683
684
0
            let (_, bytes_consumed) = check_length(&data[walker..])?;
685
0
            walker += bytes_consumed;
686
0
            if walker >= len {
687
0
                return Err(SPDM_STATUS_VERIF_FAIL);
688
0
            }
689
690
0
            check_tag_is_num_oid(&data[walker..])?;
691
0
            walker += 1;
692
0
            if walker >= len {
693
0
                return Err(SPDM_STATUS_VERIF_FAIL);
694
0
            }
695
696
0
            let (target_oid_length, bytes_consumed) = check_length(&data[walker..])?;
697
0
            walker += bytes_consumed;
698
0
            if walker >= len {
699
0
                return Err(SPDM_STATUS_VERIF_FAIL);
700
0
            }
701
702
0
            if target_oid_length != target_oid.len() {
703
0
                return Err(SPDM_STATUS_VERIF_FAIL);
704
0
            }
705
706
0
            if walker + target_oid_length <= len
707
0
                && object_identifiers_are_same(
708
0
                    &data[walker..walker + target_oid_length],
709
0
                    target_oid,
710
                )
711
            {
712
0
                return Ok(true);
713
0
            }
714
0
        }
715
716
0
        walker = next_ext_walker;
717
    }
718
719
0
    Ok(false)
720
0
}
721
722
// IN extension sequence slice
723
// OUT Ok (extnID, extn sequence length)
724
// OUT Error not found extnID, verify fail
725
0
fn check_and_get_extn_id(extn_sequences: &[u8]) -> SpdmResult<(&[u8], usize)> {
726
0
    let len = extn_sequences.len();
727
0
    if len < 1 || extn_sequences[0] != ASN1_TAG_SEQUENCE {
728
0
        Err(SPDM_STATUS_VERIF_FAIL)
729
    } else {
730
0
        let (extn_payload_length, extn_bytes_consumed) = check_length(&extn_sequences[1..])?;
731
0
        if len < 1 + extn_bytes_consumed + extn_payload_length {
732
0
            Err(SPDM_STATUS_VERIF_FAIL)
733
        } else {
734
            // extnID is the first item in the extension sequence and the tag is Object identifier
735
0
            let extn_id = &extn_sequences[1 + extn_bytes_consumed..];
736
0
            if extn_id.is_empty() || extn_id[0] != ASN1_TAG_NUMBER_OBJECT_IDENTIFIER {
737
0
                Err(SPDM_STATUS_VERIF_FAIL)
738
            } else {
739
0
                let (extn_id_length, extn_id_bytes_consumed) = check_length(&extn_id[1..])?;
740
0
                Ok((
741
0
                    &extn_id
742
0
                        [1 + extn_id_bytes_consumed..1 + extn_id_bytes_consumed + extn_id_length],
743
0
                    1 + extn_bytes_consumed + extn_payload_length,
744
0
                ))
745
            }
746
        }
747
    }
748
0
}
749
750
0
fn check_and_skip_common_sequence(data: &[u8]) -> SpdmResult<usize> {
751
0
    let len = data.len();
752
0
    if len < 1 || data[0] != ASN1_TAG_SEQUENCE {
753
0
        Err(SPDM_STATUS_VERIF_FAIL)
754
    } else {
755
0
        let (payload_length, bytes_consumed) = check_length(&data[1..])?;
756
0
        if len < 1 + bytes_consumed + payload_length {
757
0
            Err(SPDM_STATUS_VERIF_FAIL)
758
        } else {
759
0
            Ok(1 + bytes_consumed + payload_length)
760
        }
761
    }
762
0
}
763
764
0
fn check_and_skip_common_tag(data: &[u8]) -> SpdmResult<usize> {
765
0
    let len = data.len();
766
0
    if len < 1 {
767
0
        Err(SPDM_STATUS_VERIF_FAIL)
768
    } else {
769
0
        let (payload_length, bytes_consumed) = check_length(&data[1..])?;
770
0
        if len < 1 + bytes_consumed + payload_length {
771
0
            Err(SPDM_STATUS_VERIF_FAIL)
772
        } else {
773
0
            Ok(1 + bytes_consumed + payload_length)
774
        }
775
    }
776
0
}
777
778
0
fn check_and_get_common_tag(data: &[u8]) -> SpdmResult<(usize, &[u8])> {
779
0
    let len = data.len();
780
0
    if len < 1 {
781
0
        Err(SPDM_STATUS_VERIF_FAIL)
782
    } else {
783
0
        let (payload_length, bytes_consumed) = check_length(&data[1..])?;
784
0
        if len < 1 + bytes_consumed + payload_length {
785
0
            Err(SPDM_STATUS_VERIF_FAIL)
786
        } else {
787
0
            Ok((
788
0
                1 + bytes_consumed + payload_length,
789
0
                &data[1 + bytes_consumed..1 + bytes_consumed + payload_length],
790
0
            ))
791
        }
792
    }
793
0
}
794
795
0
fn get_oid_by_base_asym_algo(base_asym_algo: SpdmBaseAsymAlgo) -> Option<&'static [u8]> {
796
0
    match base_asym_algo {
797
0
        SpdmBaseAsymAlgo::TPM_ALG_RSASSA_2048 => Some(OID_RSA_SHA256RSA),
798
0
        SpdmBaseAsymAlgo::TPM_ALG_RSAPSS_2048 => Some(OID_RSA_SHA256RSA),
799
0
        SpdmBaseAsymAlgo::TPM_ALG_RSASSA_3072 => Some(OID_RSA_SHA384RSA),
800
0
        SpdmBaseAsymAlgo::TPM_ALG_RSAPSS_3072 => Some(OID_RSA_SHA384RSA),
801
0
        SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256 => Some(OID_ECDSA_SHA256),
802
0
        SpdmBaseAsymAlgo::TPM_ALG_RSASSA_4096 => Some(OID_RSA_SHA512RSA),
803
0
        SpdmBaseAsymAlgo::TPM_ALG_RSAPSS_4096 => Some(OID_RSA_SHA512RSA),
804
0
        SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384 => Some(OID_ECDSA_SHA384),
805
0
        _ => None,
806
    }
807
0
}
808
809
0
fn object_identifiers_are_same(a: &[u8], b: &[u8]) -> bool {
810
0
    if a.len() != b.len() {
811
0
        false
812
    } else {
813
0
        for (ai, bi) in a.iter().zip(b.iter()) {
814
0
            match ai.cmp(bi) {
815
0
                core::cmp::Ordering::Equal => continue,
816
0
                _ => return false,
817
            }
818
        }
819
0
        true
820
    }
821
0
}
822
823
// test root cert by checking issuer name == subject name
824
0
pub fn is_root_certificate(cert: &[u8]) -> SpdmResult {
825
0
    let mut c_walker = 0usize;
826
827
0
    check_tag_is_sequence(cert)?;
828
0
    c_walker += 1;
829
830
0
    let (_, bytes_consumed) = check_length(&cert[c_walker..])?;
831
0
    c_walker += bytes_consumed;
832
833
    // tbs
834
0
    let data = &cert[c_walker..];
835
0
    let mut t_walker = 0usize;
836
0
    let len = data.len();
837
838
0
    check_tag_is_sequence(data)?;
839
0
    t_walker += 1;
840
841
0
    let (tbs_length, bytes_consumed) = check_length(&data[t_walker..])?;
842
0
    t_walker += bytes_consumed;
843
844
0
    if len < t_walker + tbs_length {
845
0
        return Err(SPDM_STATUS_VERIF_FAIL);
846
0
    }
847
848
    // version         [0]  EXPLICIT Version DEFAULT v1,
849
0
    let bytes_consumed = check_version(&data[t_walker..])?;
850
0
    t_walker += bytes_consumed;
851
852
    // serialNumber         CertificateSerialNumber,
853
0
    let bytes_consumed = check_and_skip_common_tag(&data[t_walker..])?;
854
0
    t_walker += bytes_consumed;
855
856
    // signature            AlgorithmIdentifier,
857
0
    check_tag_is_sequence(&data[t_walker..])?;
858
0
    t_walker += 1;
859
0
    let (signature_id_length, bytes_consumed) = check_length(&data[t_walker..])?;
860
0
    t_walker += bytes_consumed;
861
862
0
    check_object_identifier(&data[t_walker..], None)?;
863
864
0
    t_walker += signature_id_length;
865
    // issuer               Name,
866
0
    let (bytes_consumed, issuer) = check_and_get_common_tag(&data[t_walker..])?;
867
0
    t_walker += bytes_consumed;
868
869
    // validity             Validity,
870
0
    let bytes_consumed = check_validity(&data[t_walker..])?;
871
0
    t_walker += bytes_consumed;
872
873
    // subject              Name,
874
0
    let (_, subject) = check_and_get_common_tag(&data[t_walker..])?;
875
876
0
    if subject == issuer {
877
0
        Ok(())
878
    } else {
879
0
        Err(SPDM_STATUS_VERIF_FAIL)
880
    }
881
0
}
882
883
// verify alias and device model by searching hardware oid in leaf cert
884
0
pub fn check_leaf_certificate(cert: &[u8], is_alias_cert_model: bool) -> SpdmResult {
885
0
    let mut c_walker = 0usize;
886
887
0
    check_tag_is_sequence(cert)?;
888
0
    c_walker += 1;
889
890
0
    let (_, bytes_consumed) = check_length(&cert[c_walker..])?;
891
0
    c_walker += bytes_consumed;
892
893
    // tbs
894
0
    let data = &cert[c_walker..];
895
0
    let mut t_walker = 0usize;
896
0
    let len = data.len();
897
898
0
    check_tag_is_sequence(data)?;
899
0
    t_walker += 1;
900
901
0
    let (tbs_length, bytes_consumed) = check_length(&data[t_walker..])?;
902
0
    t_walker += bytes_consumed;
903
904
0
    if len < t_walker + tbs_length {
905
0
        return Err(SPDM_STATUS_VERIF_FAIL);
906
0
    }
907
908
    // version         [0]  EXPLICIT Version DEFAULT v1,
909
0
    let bytes_consumed = check_version(&data[t_walker..])?;
910
0
    t_walker += bytes_consumed;
911
912
    // serialNumber         CertificateSerialNumber,
913
0
    let bytes_consumed = check_and_skip_common_tag(&data[t_walker..])?;
914
0
    t_walker += bytes_consumed;
915
916
    // signature            AlgorithmIdentifier,
917
0
    check_tag_is_sequence(&data[t_walker..])?;
918
0
    t_walker += 1;
919
0
    let (signature_id_length, bytes_consumed) = check_length(&data[t_walker..])?;
920
0
    t_walker += bytes_consumed;
921
922
0
    check_object_identifier(&data[t_walker..], None)?;
923
0
    t_walker += signature_id_length;
924
925
    // issuer               Name,
926
0
    let bytes_consumed = check_name(&data[t_walker..])?;
927
0
    t_walker += bytes_consumed;
928
929
    // validity             Validity,
930
0
    let bytes_consumed = check_validity(&data[t_walker..])?;
931
0
    t_walker += bytes_consumed;
932
933
    // subject              Name,
934
0
    let bytes_consumed = check_name(&data[t_walker..])?;
935
0
    t_walker += bytes_consumed;
936
937
    // subjectPublicKeyInfo SubjectPublicKeyInfo,
938
0
    let bytes_consumed = check_public_key_info(&data[t_walker..])?;
939
0
    t_walker += bytes_consumed;
940
941
    //extensions            EXTENSIONS,
942
0
    let (_, extension_data) = check_and_get_extensions(&data[t_walker..])?;
943
944
0
    if is_alias_cert_model
945
0
        && find_target_object_identifier_in_extensions(
946
0
            extension_data,
947
0
            OID_DMTF_SPDM_HARDWARE_IDENTITY,
948
0
        )?
949
    {
950
0
        info!("Hardware identity OID shall not be present in alias cert!\n");
951
0
        Err(SPDM_STATUS_VERIF_FAIL)
952
0
    } else if !is_alias_cert_model
953
0
        && !find_target_object_identifier_in_extensions(
954
0
            extension_data,
955
0
            OID_DMTF_SPDM_HARDWARE_IDENTITY,
956
0
        )?
957
    {
958
0
        info!("Hardware identity OID should be present in device cert!\n");
959
0
        Ok(())
960
    } else {
961
0
        Ok(())
962
    }
963
0
}
964
965
#[cfg(test)]
966
mod tests {
967
    extern crate std;
968
    use super::*;
969
970
    #[test]
971
    fn test_case0_object_identifiers_are_same() {
972
        let lt = [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0bu8];
973
        let lt_wrong1 = [0x2b, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0bu8];
974
        let lt_wrong2 = [0x2b, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0xb0u8];
975
        let lt_empty: [u8; 0] = [];
976
        assert!(object_identifiers_are_same(&lt, OID_RSA_SHA256RSA));
977
        assert!(!object_identifiers_are_same(&lt, OID_RSA_SHA384RSA));
978
        assert!(!object_identifiers_are_same(&lt_wrong1, OID_RSA_SHA256RSA));
979
        assert!(!object_identifiers_are_same(&lt_wrong2, OID_RSA_SHA256RSA));
980
        assert!(!object_identifiers_are_same(&lt_empty, OID_RSA_SHA384RSA));
981
    }
982
983
    #[test]
984
    fn test_case0_get_oid_by_base_asym_algo() {
985
        assert_eq!(
986
            get_oid_by_base_asym_algo(SpdmBaseAsymAlgo::TPM_ALG_RSASSA_2048),
987
            Some(OID_RSA_SHA256RSA)
988
        );
989
        assert_eq!(
990
            get_oid_by_base_asym_algo(SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256),
991
            Some(OID_ECDSA_SHA256)
992
        );
993
    }
994
995
    #[test]
996
    fn test_case0_check_and_skip_common_tag() {
997
        let sq1 = [
998
            0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, 0x00, 0xD7, 0x9C, 0x7F, 0x26, 0x91, 0x34,
999
            0xA5, 0x2B, 0x79, 0xEA, 0x66, 0x15, 0x00, 0x88, 0x0A, 0x4D, 0xE7, 0xAD, 0x71, 0xC6,
1000
            0x2E, 0xE4, 0x7E, 0x37, 0xE1, 0x86, 0xEB, 0xE8, 0x55, 0xB0, 0x2F, 0xC5, 0xF3, 0xA9,
1001
            0xE0, 0x90, 0xF9, 0x0B, 0x82, 0xC5, 0xDF, 0x4A, 0x35, 0x9A, 0x0D, 0x35, 0x38, 0x4B,
1002
            0x02, 0x30, 0x40, 0xA7, 0xFE, 0x70, 0x39, 0x7B, 0x4B, 0xD7, 0xC2, 0x28, 0x72, 0x93,
1003
            0x93, 0x0C, 0x62, 0x12, 0x14, 0xF0, 0x70, 0x74, 0x0F, 0xFC, 0xB1, 0x21, 0x60, 0x40,
1004
            0x6D, 0x13, 0xA3, 0x59, 0x0E, 0x27, 0x06, 0xC1, 0x73, 0x4E, 0xCA, 0x40, 0x4C, 0x2D,
1005
            0xF5, 0x96, 0x48, 0x66, 0x05, 0xB1, 0xA6, 0x08,
1006
        ];
1007
        let sq2 = [0xA0, 0x03, 0x02, 0x01, 0x02];
1008
        let sq3 = [0x01, 0x01, 0xFF];
1009
        let sq4 = [0x01, 0x01, 0xFF, 0xAA];
1010
        let sq1_wrong = [0x01, 0x02, 0xFF];
1011
        assert_eq!(check_and_skip_common_tag(&sq1), Ok(106));
1012
        assert_eq!(check_and_skip_common_tag(&sq2), Ok(5));
1013
        assert_eq!(check_and_skip_common_tag(&sq3), Ok(3));
1014
        assert_eq!(check_and_skip_common_tag(&sq4), Ok(3));
1015
        assert_eq!(
1016
            check_and_skip_common_tag(&sq1_wrong),
1017
            Err(SPDM_STATUS_VERIF_FAIL)
1018
        );
1019
    }
1020
1021
    #[test]
1022
    fn test_case0_check_object_identifier() {
1023
        let oid1 = [0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03];
1024
        let oid2 = [0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02];
1025
        let oid3 = [
1026
            0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B,
1027
        ];
1028
        let oid1_wrong = [
1029
            0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03,
1030
        ];
1031
        let oid2_wrong = [0x06, 0x08, 0x2A, 0x86];
1032
        let oid3_wrong: [u8; 0] = [];
1033
        assert_eq!(
1034
            check_object_identifier(&oid1, Some(OID_ECDSA_SHA384)),
1035
            Ok(10)
1036
        );
1037
        assert_eq!(
1038
            check_object_identifier(&oid2, Some(OID_ECDSA_SHA256)),
1039
            Ok(10)
1040
        );
1041
        assert_eq!(
1042
            check_object_identifier(&oid3, Some(OID_RSA_SHA256RSA)),
1043
            Ok(11)
1044
        );
1045
        assert_eq!(
1046
            check_object_identifier(&oid1_wrong, Some(OID_ECDSA_SHA384)),
1047
            Err(SPDM_STATUS_VERIF_FAIL)
1048
        );
1049
        assert_eq!(
1050
            check_object_identifier(&oid2_wrong, Some(OID_ECDSA_SHA384)),
1051
            Err(SPDM_STATUS_VERIF_FAIL)
1052
        );
1053
        assert_eq!(
1054
            check_object_identifier(&oid3_wrong, Some(OID_ECDSA_SHA384)),
1055
            Err(SPDM_STATUS_VERIF_FAIL)
1056
        );
1057
    }
1058
1059
    #[test]
1060
    fn test_case0_check_version() {
1061
        let v1 = [0xA0, 0x03, 0x02, 0x01, 0x02];
1062
        let v1_wrong = [0xA0, 0x03, 0x02, 0x01, 0x01];
1063
        let v2_wrong = [0x30, 0x03, 0x02, 0x01, 0x02];
1064
        let v3_wrong = [0xA0, 0x03, 0x02, 0x01];
1065
        assert_eq!(check_version(&v1), Ok(5));
1066
        assert_eq!(check_version(&v1_wrong), Err(SPDM_STATUS_VERIF_FAIL));
1067
        assert_eq!(check_version(&v2_wrong), Err(SPDM_STATUS_VERIF_FAIL));
1068
        assert_eq!(check_version(&v3_wrong), Err(SPDM_STATUS_VERIF_FAIL));
1069
    }
1070
1071
    #[test]
1072
    fn test_case0_check_length() {
1073
        let l1 = [0x03, 0x1, 0x2, 0x3];
1074
        let l2 = [
1075
            0x81, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1076
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1077
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1078
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1079
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1080
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1081
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1082
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1083
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1084
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1085
        ];
1086
        let l3 = [
1087
            0x82, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1088
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1089
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1090
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1091
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1092
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1093
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1094
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1095
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1098
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1099
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1102
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1103
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1104
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1105
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1106
        ];
1107
        let l1_wrong = [0x80];
1108
        let l2_wrong = [0x81];
1109
        let l3_wrong = [0x82, 0x01];
1110
        let mut l4_wrong = [0u8; 1 + 3 + 0x10000];
1111
        l4_wrong[0] = 0x83;
1112
        l4_wrong[1] = 0x01;
1113
        l4_wrong[1] = 0x00;
1114
        l4_wrong[1] = 0x00;
1115
        assert_eq!(check_length(&l1), Ok((3, 1)));
1116
        assert_eq!(check_length(&l2), Ok((0x82, 2)));
1117
        assert_eq!(check_length(&l3), Ok((0x101, 3)));
1118
        assert_eq!(check_length(&l1_wrong), Err(SPDM_STATUS_VERIF_FAIL));
1119
        assert_eq!(check_length(&l2_wrong), Err(SPDM_STATUS_VERIF_FAIL));
1120
        assert_eq!(check_length(&l3_wrong), Err(SPDM_STATUS_VERIF_FAIL));
1121
        assert_eq!(check_length(&l4_wrong), Err(SPDM_STATUS_VERIF_FAIL));
1122
    }
1123
1124
    #[test]
1125
    fn test_case0_check_tag_is_sequence() {
1126
        let l1 = [0x30];
1127
        let l1_wrong = [0x80];
1128
        let l2_wrong = [0x81];
1129
        let l3_wrong = [0x82, 0x01];
1130
        assert_eq!(check_tag_is_sequence(&l1), Ok(()));
1131
        assert_eq!(
1132
            check_tag_is_sequence(&l1_wrong),
1133
            Err(SPDM_STATUS_VERIF_FAIL)
1134
        );
1135
        assert_eq!(
1136
            check_tag_is_sequence(&l2_wrong),
1137
            Err(SPDM_STATUS_VERIF_FAIL)
1138
        );
1139
        assert_eq!(
1140
            check_tag_is_sequence(&l3_wrong),
1141
            Err(SPDM_STATUS_VERIF_FAIL)
1142
        );
1143
    }
1144
1145
    #[test]
1146
    fn test_case0_check_signature_algorithm() {
1147
        let s1 = [
1148
            0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03,
1149
        ];
1150
        let s1_wrong = [
1151
            0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03,
1152
        ];
1153
        let s2_wrong = [0x06, 0x08, 0x2A, 0x86];
1154
        let s3_wrong: [u8; 0] = [];
1155
        assert_eq!(
1156
            check_signature_algorithm(&s1, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384, true),
1157
            Ok(12)
1158
        );
1159
        assert_eq!(
1160
            check_signature_algorithm(&s1, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384, false),
1161
            Ok(12)
1162
        );
1163
        assert_eq!(
1164
            check_signature_algorithm(&s1, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256, false),
1165
            Ok(12)
1166
        );
1167
        assert_eq!(
1168
            check_signature_algorithm(&s1, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256, true),
1169
            Err(SPDM_STATUS_VERIF_FAIL)
1170
        );
1171
        assert_eq!(
1172
            check_signature_algorithm(
1173
                &s1_wrong,
1174
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1175
                false
1176
            ),
1177
            Err(SPDM_STATUS_VERIF_FAIL)
1178
        );
1179
        assert_eq!(
1180
            check_signature_algorithm(
1181
                &s2_wrong,
1182
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1183
                false
1184
            ),
1185
            Err(SPDM_STATUS_VERIF_FAIL)
1186
        );
1187
        assert_eq!(
1188
            check_signature_algorithm(
1189
                &s3_wrong,
1190
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1191
                false
1192
            ),
1193
            Err(SPDM_STATUS_VERIF_FAIL)
1194
        );
1195
    }
1196
1197
    #[test]
1198
    fn test_case0_check_tbs_certificate() {
1199
        let t1 = std::fs::read("../test_key/ecp384/ca.cert.der").expect("unable to read ca cert!");
1200
        let t2 =
1201
            std::fs::read("../test_key/ecp384/inter.cert.der").expect("unable to read inter cert!");
1202
        let t3 = std::fs::read("../test_key/ecp384/end_responder.cert.der")
1203
            .expect("unable to read leaf cert!");
1204
1205
        let t1_wrong = [0x30, 0x82, 0x01, 0xA8, 0xA0];
1206
1207
        assert_eq!(
1208
            check_tbs_certificate(
1209
                &t1[4..],
1210
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1211
                false
1212
            ),
1213
            Ok(350)
1214
        );
1215
        assert_eq!(
1216
            check_tbs_certificate(
1217
                &t2[4..],
1218
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1219
                false
1220
            ),
1221
            Ok(357)
1222
        );
1223
        assert_eq!(
1224
            check_tbs_certificate(
1225
                &t3[4..],
1226
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1227
                false
1228
            ),
1229
            Ok(464)
1230
        );
1231
        assert_eq!(
1232
            check_tbs_certificate(
1233
                &t3[4..],
1234
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256,
1235
                false
1236
            ),
1237
            Ok(464)
1238
        );
1239
        assert_eq!(
1240
            check_tbs_certificate(
1241
                &t3[4..],
1242
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1243
                true
1244
            ),
1245
            Ok(464)
1246
        );
1247
        assert_eq!(
1248
            check_tbs_certificate(
1249
                &t3[4..],
1250
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256,
1251
                true
1252
            ),
1253
            Err(SPDM_STATUS_VERIF_FAIL)
1254
        );
1255
        assert_eq!(
1256
            check_tbs_certificate(
1257
                &t1_wrong,
1258
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1259
                false
1260
            ),
1261
            Err(SPDM_STATUS_VERIF_FAIL)
1262
        );
1263
        assert_eq!(
1264
            check_tbs_certificate(
1265
                &t1_wrong,
1266
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384,
1267
                true
1268
            ),
1269
            Err(SPDM_STATUS_VERIF_FAIL)
1270
        );
1271
    }
1272
1273
    #[test]
1274
    fn test_case1_check_tbs_certificate() {
1275
        let t1 = std::fs::read("../test_key/rsa2048/end_requester_with_spdm_rsp_eku.cert.der")
1276
            .expect("unable to read leaf cert!");
1277
        let t2 = std::fs::read("../test_key/rsa2048/end_responder_with_spdm_req_eku.cert.der")
1278
            .expect("unable to read leaf cert!");
1279
1280
        assert_eq!(
1281
            check_tbs_certificate(&t1[4..], SpdmBaseAsymAlgo::TPM_ALG_RSASSA_2048, true),
1282
            Ok(562)
1283
        );
1284
        assert_eq!(
1285
            check_tbs_certificate(&t1[4..], SpdmBaseAsymAlgo::TPM_ALG_RSASSA_2048, false),
1286
            Err(SPDM_STATUS_VERIF_FAIL)
1287
        );
1288
        assert_eq!(
1289
            check_tbs_certificate(&t2[4..], SpdmBaseAsymAlgo::TPM_ALG_RSASSA_2048, true),
1290
            Ok(562)
1291
        );
1292
        assert_eq!(
1293
            check_tbs_certificate(&t2[4..], SpdmBaseAsymAlgo::TPM_ALG_RSASSA_2048, false),
1294
            Err(SPDM_STATUS_VERIF_FAIL)
1295
        );
1296
    }
1297
1298
    #[test]
1299
    fn test_case0_check_cert_format() {
1300
        let c1 = std::fs::read("../test_key/ecp384/ca.cert.der").expect("unable to read ca cert!");
1301
        let c2 =
1302
            std::fs::read("../test_key/ecp384/inter.cert.der").expect("unable to read inter cert!");
1303
        let c3 = std::fs::read("../test_key/ecp384/end_responder.cert.der")
1304
            .expect("unable to read leaf cert!");
1305
1306
        let c1_wrong = [0x30u8, 0x82, 0x01, 0xA8, 0xA0];
1307
1308
        assert_eq!(
1309
            check_cert_format(&c1, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384),
1310
            Ok(472)
1311
        );
1312
        assert_eq!(
1313
            check_cert_format(&c2, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384),
1314
            Ok(480)
1315
        );
1316
        assert_eq!(
1317
            check_cert_format(&c3, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384),
1318
            Ok(587)
1319
        );
1320
        assert_eq!(
1321
            check_cert_format(&c3, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256),
1322
            Err(SPDM_STATUS_VERIF_FAIL)
1323
        );
1324
        assert_eq!(
1325
            check_cert_format(&c1_wrong, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384),
1326
            Err(SPDM_STATUS_VERIF_FAIL)
1327
        );
1328
    }
1329
1330
    #[test]
1331
    fn test_case0_check_cert_chain_format() {
1332
        let ct1 = std::fs::read("../test_key/ecp256/bundle_responder.certchain.der")
1333
            .expect("unable to read ca cert!");
1334
        let ct2 = std::fs::read("../test_key/ecp384/bundle_responder.certchain.der")
1335
            .expect("unable to read ca cert!");
1336
        let ct3 = std::fs::read("../test_key/rsa2048/bundle_responder.certchain.der")
1337
            .expect("unable to read ca cert!");
1338
        let ct4 = std::fs::read("../test_key/rsa3072/bundle_responder.certchain.der")
1339
            .expect("unable to read ca cert!");
1340
        let ct5 = std::fs::read("../test_key/rsa4096/bundle_responder.certchain.der")
1341
            .expect("unable to read ca cert!");
1342
1343
        let ct1_wrong = [0x30, 0x82, 0x01, 0xA8, 0xA0];
1344
1345
        assert_eq!(
1346
            check_cert_chain_format(&ct1, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256),
1347
            Ok(3)
1348
        );
1349
        assert_eq!(
1350
            check_cert_chain_format(&ct2, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384),
1351
            Ok(3)
1352
        );
1353
        assert_eq!(
1354
            check_cert_chain_format(&ct3, SpdmBaseAsymAlgo::TPM_ALG_RSASSA_2048),
1355
            Ok(3)
1356
        );
1357
        assert_eq!(
1358
            check_cert_chain_format(&ct4, SpdmBaseAsymAlgo::TPM_ALG_RSASSA_3072),
1359
            Ok(3)
1360
        );
1361
        assert_eq!(
1362
            check_cert_chain_format(&ct5, SpdmBaseAsymAlgo::TPM_ALG_RSASSA_4096),
1363
            Ok(3)
1364
        );
1365
        assert_eq!(
1366
            check_cert_chain_format(&ct3, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P256),
1367
            Err(SPDM_STATUS_VERIF_FAIL)
1368
        );
1369
        assert_eq!(
1370
            check_cert_chain_format(&ct1_wrong, SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384),
1371
            Err(SPDM_STATUS_VERIF_FAIL)
1372
        );
1373
    }
1374
1375
    #[test]
1376
    fn test_case0_is_root_certificate() {
1377
        let ca1 = std::fs::read("../test_key/ecp256/ca.cert.der").expect("unable to read ca cert!");
1378
        let ca2 =
1379
            std::fs::read("../test_key/ecp256/ca1.cert.der").expect("unable to read ca1 cert!");
1380
        let inter1 =
1381
            std::fs::read("../test_key/ecp256/inter.cert.der").expect("unable to read inter cert!");
1382
        let end1 = std::fs::read("../test_key/ecp256/end_requester1.cert.der")
1383
            .expect("unable to read end cert!");
1384
        let end2 = std::fs::read("../test_key/ecp256/end_responder1.cert.der")
1385
            .expect("unable to read end cert!");
1386
1387
        let ct1_wrong = [0x30, 0x82, 0x01, 0xA8, 0xA0];
1388
1389
        assert!(is_root_certificate(&ca1).is_ok());
1390
        assert!(is_root_certificate(&ca2).is_ok());
1391
1392
        assert!(is_root_certificate(&inter1).is_err());
1393
        assert!(is_root_certificate(&end1).is_err());
1394
        assert!(is_root_certificate(&end2).is_err());
1395
        assert!(is_root_certificate(&ct1_wrong).is_err());
1396
    }
1397
1398
    #[test]
1399
    fn test_case0_get_key_usage_value() {
1400
        let key_usage1 = &[
1401
            0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x05, 0xE0,
1402
        ];
1403
        let key_usage2_wrong = &[
1404
            0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, 0x04, 0x03, 0x02, 0x05, 0xE0,
1405
        ];
1406
        let key_usage3_wrong = &[0x30, 0x0B];
1407
        let key_usage4_wrong = &[
1408
            0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x05,
1409
        ];
1410
        assert_eq!(get_key_usage_value(key_usage1), Ok((true, 0xE0)));
1411
        assert_eq!(get_key_usage_value(key_usage2_wrong), Ok((false, 0x00)));
1412
        assert_eq!(
1413
            get_key_usage_value(key_usage3_wrong),
1414
            Err(SPDM_STATUS_VERIF_FAIL)
1415
        );
1416
        assert_eq!(
1417
            get_key_usage_value(key_usage4_wrong),
1418
            Err(SPDM_STATUS_VERIF_FAIL)
1419
        );
1420
    }
1421
1422
    #[test]
1423
    fn test_case1_get_key_usage_value() {
1424
        let key_usage1 = std::fs::read("../test_key/ecp384/end_responder.cert.der")
1425
            .expect("unable to read leaf cert!");
1426
        let key_usage2 =
1427
            std::fs::read("../test_key/rsa2048/end_requester_with_spdm_rsp_eku.cert.der")
1428
                .expect("unable to read leaf cert!");
1429
        let key_usage3 =
1430
            std::fs::read("../test_key/rsa2048/end_responder_with_spdm_req_eku.cert.der")
1431
                .expect("unable to read leaf cert!");
1432
1433
        let key_usage1_wrong = &[
1434
            0x30, 0x0, 0x30, 0x0, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x8, 0x0, 0x30, 0x6, 0x6, 0x6, 0x6,
1435
            0x20, 0x6, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x6, 0x6, 0x20, 0x26, 0x0, 0x30, 0x0, 0x30,
1436
            0x20, 0x30, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x20,
1437
            0x30, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
1438
            0x16, 0x16, 0x16, 0x16, 0x4, 0x30, 0x32, 0x10, 0x2, 0x8, 0x0, 0x30, 0x6, 0x6, 0x6, 0x6,
1439
            0x20, 0x6, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x6, 0x6, 0x20, 0x26, 0x0, 0x30, 0x0, 0x30,
1440
            0x21, 0x30, 0x4, 0x30, 0xa0, 0x1, 0x2, 0x8, 0x0, 0xbb, 0x0, 0x30, 0x2, 0x8, 0x0, 0x0,
1441
            0x0, 0x0, 0x0, 0xbb, 0x6, 0x6, 0x6, 0x6, 0x20, 0x26, 0x0, 0x6, 0x3, 0x55, 0x1d, 0xf,
1442
        ];
1443
        let key_usage2_wrong = &[
1444
            0x30, 0x0, 0x30, 0x0, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x8, 0x0, 0x30, 0x6, 0x6, 0x6, 0x6,
1445
            0x20, 0x6, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x6, 0x6, 0x20, 0x26, 0x0, 0x30, 0x0, 0x30,
1446
            0x20, 0x30, 0x4, 0x30, 0x32, 0x10, 0x2, 0x8, 0x0, 0x30, 0x6, 0x6, 0x6, 0x6, 0x20, 0x6,
1447
            0x0, 0x30, 0x66, 0x30, 0x0, 0x30, 0x6, 0x6, 0x20, 0x26, 0x0, 0x30, 0x0, 0x30, 0x20,
1448
            0x30, 0x4, 0x30, 0x32, 0x10, 0x30, 0x31, 0x31, 0x31, 0x31, 0x6, 0x20, 0x26, 0x0, 0x30,
1449
            0x0, 0x30, 0x31, 0x31, 0x31, 0xff, 0xff, 0xff, 0xff, 0x0, 0x8, 0x6, 0x27, 0x3, 0x55,
1450
            0x1d, 0xf, 0x4, 0x0, 0x30, 0x0, 0x30, 0x0, 0xa0, 0x3, 0x2, 0x1, 0x26, 0x0, 0x0, 0x0,
1451
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x6, 0x3, 0x55, 0x1d, 0xf,
1452
        ];
1453
1454
        assert_eq!(
1455
            get_key_usage_value(&key_usage1[280..]),
1456
            Ok((true, key_usage1[309]))
1457
        );
1458
        assert_eq!(
1459
            get_key_usage_value(&key_usage2[450..]),
1460
            Ok((true, key_usage2[478]))
1461
        );
1462
        assert_eq!(
1463
            get_key_usage_value(&key_usage3[450..]),
1464
            Ok((true, key_usage3[478]))
1465
        );
1466
        assert_eq!(
1467
            get_key_usage_value(key_usage1_wrong),
1468
            Err(SPDM_STATUS_VERIF_FAIL)
1469
        );
1470
        assert_eq!(
1471
            get_key_usage_value(key_usage2_wrong),
1472
            Err(SPDM_STATUS_VERIF_FAIL)
1473
        );
1474
    }
1475
1476
    #[test]
1477
    fn test_case0_check_extensions_spdm_oid() {
1478
        let e1 = std::fs::read("../test_key/ecp384/end_responder.cert.der")
1479
            .expect("unable to read leaf cert!");
1480
        let e2 = std::fs::read("../test_key/rsa2048/end_requester_with_spdm_rsp_eku.cert.der")
1481
            .expect("unable to read leaf cert!");
1482
        let e3 = std::fs::read("../test_key/rsa2048/end_responder_with_spdm_req_eku.cert.der")
1483
            .expect("unable to read leaf cert!");
1484
        assert_eq!(check_extensions_spdm_oid(&e1[280..], false), Ok(true));
1485
        assert_eq!(check_extensions_spdm_oid(&e1[280..], true), Ok(true));
1486
        assert_eq!(check_extensions_spdm_oid(&e2[450..], true), Ok(true));
1487
        assert_eq!(check_extensions_spdm_oid(&e2[450..], false), Ok(false));
1488
        assert_eq!(check_extensions_spdm_oid(&e3[450..], true), Ok(true));
1489
        assert_eq!(check_extensions_spdm_oid(&e3[450..], false), Ok(false));
1490
    }
1491
1492
    #[test]
1493
    fn test_case0_check_and_get_extn_id() {
1494
        let extension_s1 = &[
1495
            0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00,
1496
        ];
1497
        let extension_s2 = &[
1498
            0x30, 0x2A, 0x06, 0x03, 0x55, 0x1D, 0x25, 0x01, 0x01, 0xFF, 0x04, 0x20, 0x30, 0x1E,
1499
            0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2B, 0x06,
1500
            0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07,
1501
            0x03, 0x09,
1502
        ];
1503
        let extension_s3_wrong = &[
1504
            0x30, 0x0D, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00,
1505
        ];
1506
        let extension_sa4_wrong = &[
1507
            0x30, 0x0C, 0x05, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00,
1508
        ];
1509
        let oid1: &[u8] = &[0x55, 0x1D, 0x13];
1510
        let oid2: &[u8] = &[0x55, 0x1D, 0x25];
1511
        assert_eq!(check_and_get_extn_id(extension_s1), Ok((oid1, 14)));
1512
        assert_eq!(check_and_get_extn_id(extension_s2), Ok((oid2, 44)));
1513
        assert_eq!(
1514
            check_and_get_extn_id(extension_s3_wrong),
1515
            Err(SPDM_STATUS_VERIF_FAIL)
1516
        );
1517
        assert_eq!(
1518
            check_and_get_extn_id(extension_sa4_wrong),
1519
            Err(SPDM_STATUS_VERIF_FAIL)
1520
        );
1521
    }
1522
1523
    #[test]
1524
    fn test_case0_find_target_object_identifiers() {
1525
        let extension_s1 = &[
1526
            0x30, 0x0C, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00,
1527
        ];
1528
        let extension_s2 = &[
1529
            0x04, 0x2C, 0x30, 0x2A, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
1530
            0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2B, 0x06,
1531
            0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83,
1532
            0x1C, 0x82, 0x12, 0x04,
1533
        ];
1534
        let extension_s3_wrong = &[
1535
            0x30, 0x0D, 0x06, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x03, 0x30, 0x00,
1536
            0x00,
1537
        ];
1538
        let extension_sa4_wrong = &[
1539
            0x30, 0x0C, 0x05, 0x03, 0x55, 0x1D, 0x13, 0x01, 0x01, 0xFF, 0x04, 0x02, 0x30, 0x00,
1540
        ];
1541
        assert_eq!(
1542
            find_target_object_identifier_in_single_extension(extension_s1, &[0x55, 0x1D, 0x13]),
1543
            Ok(true)
1544
        );
1545
        assert_eq!(
1546
            find_target_object_identifier_in_single_extension(
1547
                extension_s2,
1548
                &[0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x04]
1549
            ),
1550
            Ok(true)
1551
        );
1552
        assert_eq!(
1553
            find_target_object_identifier_in_single_extension(
1554
                extension_s3_wrong,
1555
                &[0x55, 0x1D, 0x14]
1556
            ),
1557
            Ok(false)
1558
        );
1559
        assert_eq!(
1560
            find_target_object_identifier_in_single_extension(
1561
                extension_sa4_wrong,
1562
                &[0x55, 0x1D, 0x13]
1563
            ),
1564
            Ok(false)
1565
        );
1566
    }
1567
1568
    #[test]
1569
    fn test_case0_check_leaf_certificate() {
1570
        let end1 = std::fs::read("../test_key/rsa2048/end_responder_with_spdm_rsp_eku.cert.der")
1571
            .expect("unable to read end cert!");
1572
        let end2 = std::fs::read("../test_key/ecp384/end_responder.cert.der")
1573
            .expect("unable to read end cert!");
1574
1575
        let ct1_wrong = [0x30, 0x82, 0x01, 0xA8, 0xA0];
1576
1577
        assert!(check_leaf_certificate(&end1, true).is_ok());
1578
        assert!(check_leaf_certificate(&end1, false).is_ok());
1579
        assert!(check_leaf_certificate(&end2, false).is_ok());
1580
        assert!(check_leaf_certificate(&end2, true).is_err());
1581
        assert!(check_leaf_certificate(&ct1_wrong, true).is_err());
1582
        assert!(check_leaf_certificate(&ct1_wrong, false).is_err());
1583
    }
1584
1585
    #[test]
1586
    fn test_check_length_short_form() {
1587
        let data = [0x03, 0x01, 0x02, 0x03];
1588
        assert_eq!(check_length(&data), Ok((3, 1)));
1589
    }
1590
1591
    #[test]
1592
    fn test_check_length_short_form_large_than_128() {
1593
        let data = [0x80];
1594
        assert_eq!(check_length(&data), Err(SPDM_STATUS_VERIF_FAIL));
1595
    }
1596
1597
    #[test]
1598
    fn test_check_length_long_form() {
1599
        let data = [
1600
            0x81, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1601
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1602
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1603
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1604
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1605
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1606
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1607
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1608
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1609
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1610
        ];
1611
        assert_eq!(check_length(&data), Ok((0x80, 2)));
1612
    }
1613
1614
    #[test]
1615
    fn test_check_length_long_form_smaller_than_128() {
1616
        let data: [u8; 2] = [0x81, 0x7F];
1617
        assert_eq!(check_length(&data), Err(SPDM_STATUS_VERIF_FAIL));
1618
    }
1619
1620
    #[test]
1621
    fn test_check_length_overflow_the_length_of_k_octets_bytes_is_less_than_k() {
1622
        // First Octet  +   k          + l octets
1623
        // bit0..=6 k       Length l
1624
        // k = 5
1625
        // length(k(octets)) < 5
1626
        let data = [0x85, 0xFF, 0xFF, 0xFF, 0xFF];
1627
        assert_eq!(check_length(&data), Err(SPDM_STATUS_VERIF_FAIL));
1628
    }
1629
1630
    #[test]
1631
    fn test_check_cert_format_large_length() {
1632
        let cert = std::fs::read("../test_key/ecp384/bundle_requester.certchain.der")
1633
            .expect("unable to read ca cert!");
1634
        let mut malformed_cert = cert.clone();
1635
        malformed_cert[1] = 0x88;
1636
        for i in 2..10 {
1637
            malformed_cert[i] = 0xff;
1638
        }
1639
        assert_eq!(
1640
            check_cert_format(
1641
                &malformed_cert,
1642
                SpdmBaseAsymAlgo::TPM_ALG_ECDSA_ECC_NIST_P384
1643
            ),
1644
            Err(SPDM_STATUS_VERIF_FAIL)
1645
        );
1646
    }
1647
}