darkbio-trust 0.5.1

Dark Bio ecosystem roots of trust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
// trust-rs: dark bio ecosystem roots of trust
// Copyright 2026 Dark Bio AG. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//! Device attestations, the identities of Ark enclaves and of their emulated
//! counterparts.
//!
//! An attestation is a CWT signed by a root, binding the identity key of a
//! device to its serial and hardware details. Hardware devices are attested
//! once at manufacturing and never expire, emulated devices are attested
//! online with an expiry. Verification takes the roots the caller trusts, and
//! the set the signer belongs to decides which shape the claims must have.
//!
//! Verify an attestation against a trusted hardware root:
//!
//! ```
//! # use darkbio_crypto::cwt::{self, claims, claims::eat};
//! # use darkbio_crypto::xdsa;
//! use darkbio_trust::{Realm, device};
//! # use darkbio_trust::CRYPTO_DOMAIN_DEVICE_ATTESTATION;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # // Stand-ins for a manufacturing root and a device identity
//! # let root = xdsa::SecretKey::generate();
//! # let identity = xdsa::SecretKey::generate();
//! #
//! # let claims = device::HardwareClaims {
//! #     sub: claims::Subject { sub: "ark-0001".into() },
//! #     cnf: claims::Confirm::new(identity.public_key()),
//! #     nbf: claims::NotBefore { nbf: 1_700_000_000 },
//! #     iat: claims::IssuedAt { iat: 1_700_000_000 },
//! #     oem: eat::Oemid::new_pen(65145),
//! #     hwm: eat::HwModel { hw_model: b"Ark I".to_vec() },
//! #     hwv: eat::HwVersion::new("1.0.0".into()),
//! # };
//! # let attestation = cwt::issue(&claims, &root, CRYPTO_DOMAIN_DEVICE_ATTESTATION)?;
//! # let root = root.public_key();
//!
//! let device = device::verify(&attestation, &[root], &[], Some(1_700_000_100))?;
//! assert_eq!(device.realm, Realm::Hardware);
//! assert_eq!(device.serial, "ark-0001");
//! # assert_eq!(device.identity.fingerprint(), identity.fingerprint());
//! # Ok(())
//! # }
//! ```

use crate::{
    CRYPTO_DOMAIN_DEVICE_ATTESTATION, EMULATOR_ATTESTATION_MAX_VALIDITY, Error, Realm,
    check_validity,
};
use darkbio_crypto::cbor::Cbor;
use darkbio_crypto::cwt::claims::{self, eat};
use darkbio_crypto::{cwt, xdsa};

/// HardwareClaims are the attestation claims of a hardware Ark, issued once at
/// manufacturing and signed by a hardware root. Hardware attestations carry no
/// expiration, the identity being bound to the hardware for its lifetime.
#[derive(Cbor)]
pub struct HardwareClaims {
    /// Serial number of the device.
    #[cbor(embed)]
    pub sub: claims::Subject,
    /// xDSA identity key of the device, which the transport must prove the
    /// peer holds.
    #[cbor(embed)]
    pub cnf: claims::Confirm<xdsa::PublicKey>,
    /// Start of validity, seconds since the Unix epoch.
    #[cbor(embed)]
    pub nbf: claims::NotBefore,
    /// Time of issuance, seconds since the Unix epoch.
    #[cbor(embed)]
    pub iat: claims::IssuedAt,
    /// Manufacturer of the device.
    #[cbor(embed)]
    pub oem: eat::Oemid,
    /// Hardware model of the device.
    #[cbor(embed)]
    pub hwm: eat::HwModel,
    /// Hardware revision of the device.
    #[cbor(embed)]
    pub hwv: eat::HwVersion,
}

/// EmulatorClaims are the attestation claims of an emulated Ark, issued online
/// by the cloud sandbox and signed by an emulator root. Emulator attestations
/// always carry an expiration so emulated devices age out, their validity
/// capped at EMULATOR_ATTESTATION_MAX_VALIDITY.
#[derive(Cbor)]
pub struct EmulatorClaims {
    /// Serial number of the emulated device.
    #[cbor(embed)]
    pub sub: claims::Subject,
    /// xDSA identity key of the emulated device, which the transport must
    /// prove the peer holds.
    #[cbor(embed)]
    pub cnf: claims::Confirm<xdsa::PublicKey>,
    /// Start of validity, seconds since the Unix epoch.
    #[cbor(embed)]
    pub nbf: claims::NotBefore,
    /// End of validity, seconds since the Unix epoch, at most
    /// [`EMULATOR_ATTESTATION_MAX_VALIDITY`] after the start.
    #[cbor(embed)]
    pub exp: claims::Expiration,
    /// Time of issuance, seconds since the Unix epoch.
    #[cbor(embed)]
    pub iat: claims::IssuedAt,
    /// Manufacturer of the emulated device.
    #[cbor(embed)]
    pub oem: eat::Oemid,
    /// Hardware model of the emulated device.
    #[cbor(embed)]
    pub hwm: eat::HwModel,
    /// Hardware revision of the emulated device.
    #[cbor(embed)]
    pub hwv: eat::HwVersion,
}

/// Identity claims authenticated by a selected root. A peer must separately
/// prove possession of `identity`, typically through the wire handshake.
#[derive(Clone, Debug)]
pub struct Device {
    /// Realm determined by the root set containing the signer.
    pub realm: Realm,
    /// Attested key to use for the peer's proof of possession.
    pub identity: xdsa::PublicKey,
    /// Device serial number from the subject claim.
    pub serial: String,
    /// Manufacturer identifier qualifying the hardware model.
    pub oem: eat::Oemid,
    /// Hardware model identifier in the manufacturer's namespace.
    pub model: Vec<u8>,
    /// Hardware revision identifier.
    pub version: String,
    /// Time of issuance, seconds since the Unix epoch.
    pub issued: u64,
    /// Time of expiry, seconds since the Unix epoch, absent for hardware
    /// devices.
    pub expiry: Option<u64>,
}

/// Verifies a device attestation against the supplied hardware and emulator
/// roots. The set containing its signer determines the accepted claim shape.
/// Hardware attestations have no expiration; emulator lifetimes are capped at
/// [`EMULATOR_ATTESTATION_MAX_VALIDITY`], even without a trusted clock.
///
/// When `now` is given, the attestation must also be valid at that Unix time.
/// Callers supplying their own keys must place them in the correct, disjoint
/// root sets.
/// A signer outside both sets yields an unauthenticated [`Error::UntrustedSigner`] hint.
pub fn verify(
    attestation: &[u8],
    hardware: &[xdsa::PublicKey],
    emulator: &[xdsa::PublicKey],
    now: Option<u64>,
) -> Result<Device, Error> {
    // Find the signer among the permitted roots of trust
    let signer = cwt::signer(attestation)?;

    // Verify the attestation and retrieve the device claims
    if let Some(root) = hardware.iter().find(|root| root.fingerprint() == signer) {
        // Hardware devices must not have an expiration claim
        let claims: HardwareClaims =
            cwt::verify(attestation, root, CRYPTO_DOMAIN_DEVICE_ATTESTATION, now)?;

        return Ok(Device {
            realm: Realm::Hardware,
            identity: claims.cnf.key().clone(),
            serial: claims.sub.sub,
            oem: claims.oem,
            model: claims.hwm.hw_model,
            version: claims.hwv.version().to_string(),
            issued: claims.iat.iat,
            expiry: None,
        });
    }
    if let Some(root) = emulator.iter().find(|root| root.fingerprint() == signer) {
        // Emulators must have an expiration claim, bounded by the maximum validity
        let claims: EmulatorClaims =
            cwt::verify(attestation, root, CRYPTO_DOMAIN_DEVICE_ATTESTATION, now)?;

        check_validity(
            claims.nbf.nbf,
            claims.exp.exp,
            EMULATOR_ATTESTATION_MAX_VALIDITY,
        )?;
        return Ok(Device {
            realm: Realm::Emulator,
            identity: claims.cnf.key().clone(),
            serial: claims.sub.sub,
            oem: claims.oem,
            model: claims.hwm.hw_model,
            version: claims.hwv.version().to_string(),
            issued: claims.iat.iat,
            expiry: Some(claims.exp.exp),
        });
    }
    Err(Error::untrusted_signer(signer))
}

/// Verifies a token's signature under its embedded identity key. Only that key
/// is returned; the self-asserted identity claims confer no provisioning trust.
///
/// This does not establish whether a device has ever been onboarded or whether
/// the current presenter holds the private key. A copied token also verifies;
/// a live handshake or challenge must establish possession separately. Validity
/// timestamps are ignored, since self-asserted lifetimes confer no authority.
pub fn verify_self_signed(attestation: &[u8]) -> Result<xdsa::PublicKey, Error> {
    // Figure out the realm based on attestation shape
    let (identity, hardware) = match cwt::peek::<HardwareClaims>(attestation) {
        Ok(claims) => (claims.cnf.key().clone(), true),
        Err(_) => {
            let claims: EmulatorClaims = cwt::peek(attestation)?;
            (claims.cnf.key().clone(), false)
        }
    };
    // Ensure it's truly a self-signed attestation
    let signer = cwt::signer(attestation)?;
    if identity.fingerprint() != signer {
        return Err(Error::NotSelfSigned);
    }
    // Verify the attestation and retrieve the device claims
    match hardware {
        true => {
            cwt::verify::<HardwareClaims>(
                attestation,
                &identity,
                CRYPTO_DOMAIN_DEVICE_ATTESTATION,
                None,
            )?;
        }
        false => {
            cwt::verify::<EmulatorClaims>(
                attestation,
                &identity,
                CRYPTO_DOMAIN_DEVICE_ATTESTATION,
                None,
            )?;
        }
    }
    Ok(identity)
}

#[cfg(test)]
mod tests {
    use super::*;

    /// Attestation claims of a hardware device, valid from time 1000 onwards.
    fn hardware_claims(identity: xdsa::PublicKey) -> HardwareClaims {
        HardwareClaims {
            sub: claims::Subject {
                sub: "ark-1234".into(),
            },
            cnf: claims::Confirm::new(identity),
            nbf: claims::NotBefore { nbf: 1000 },
            iat: claims::IssuedAt { iat: 1000 },
            oem: eat::Oemid::new_pen(65145),
            hwm: eat::HwModel {
                hw_model: b"Ark I".to_vec(),
            },
            hwv: eat::HwVersion::new("Ark I - 1.0.0".into()),
        }
    }

    /// Attestation claims of an emulated device, valid for the given period.
    fn emulator_claims(identity: xdsa::PublicKey, nbf: u64, exp: u64) -> EmulatorClaims {
        EmulatorClaims {
            sub: claims::Subject {
                sub: "emu-1234".into(),
            },
            cnf: claims::Confirm::new(identity),
            nbf: claims::NotBefore { nbf },
            exp: claims::Expiration { exp },
            iat: claims::IssuedAt { iat: 1000 },
            oem: eat::Oemid::new_pen(65145),
            hwm: eat::HwModel {
                hw_model: b"Ark I".to_vec(),
            },
            hwv: eat::HwVersion::new("Ark I - 1.0.0".into()),
        }
    }

    // Tests that a hardware attestation verifies under its hardware root, yielding
    // the attested identity that never expires.
    #[test]
    fn test_hardware_verification() {
        let root = xdsa::SecretKey::generate();
        let identity = xdsa::SecretKey::generate().public_key();
        let attestation = cwt::issue(
            &hardware_claims(identity.clone()),
            &root,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();

        let device = verify(&attestation, &[root.public_key()], &[], Some(1500)).unwrap();
        assert_eq!(device.realm, Realm::Hardware, "realm mismatch");
        assert_eq!(
            device.identity.fingerprint(),
            identity.fingerprint(),
            "identity mismatch"
        );
        assert_eq!(device.serial, "ark-1234", "serial mismatch");
        assert_eq!(device.model, b"Ark I", "model mismatch");
        assert_eq!(device.version, "Ark I - 1.0.0", "version mismatch");
        assert_eq!(device.issued, 1000, "issuance mismatch");
        assert_eq!(device.expiry, None, "hardware attestation must not expire");
    }

    // Tests that an emulator attestation verifies under its emulator root,
    // yielding the attested identity along with its expiry.
    #[test]
    fn test_emulator_verification() {
        let root = xdsa::SecretKey::generate();
        let identity = xdsa::SecretKey::generate().public_key();
        let attestation = cwt::issue(
            &emulator_claims(identity.clone(), 1000, 2000),
            &root,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();

        let device = verify(&attestation, &[], &[root.public_key()], Some(1500)).unwrap();
        assert_eq!(device.realm, Realm::Emulator, "realm mismatch");
        assert_eq!(
            device.identity.fingerprint(),
            identity.fingerprint(),
            "identity mismatch"
        );
        assert_eq!(device.serial, "emu-1234", "serial mismatch");
        assert_eq!(device.expiry, Some(2000), "expiry mismatch");
    }

    // Tests that the set a root belongs to dictates the shape of the attestation,
    // an expiring attestation being rejected under a hardware root and a
    // permanent one under an emulator root, even if the signatures are valid.
    #[test]
    fn test_shape_mismatch() {
        let root = xdsa::SecretKey::generate();
        let identity = xdsa::SecretKey::generate().public_key();

        let expiring = cwt::issue(
            &emulator_claims(identity.clone(), 1000, 2000),
            &root,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();
        assert!(
            matches!(
                verify(&expiring, &[root.public_key()], &[], None),
                Err(Error::Cwt(cwt::Error::Cbor(_)))
            ),
            "hardware root accepted an expiring attestation"
        );

        let permanent = cwt::issue(
            &hardware_claims(identity),
            &root,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();
        assert!(
            matches!(
                verify(&permanent, &[], &[root.public_key()], None),
                Err(Error::Cwt(cwt::Error::Cbor(_)))
            ),
            "emulator root accepted a permanent attestation"
        );
    }

    // Tests that the signer of an attestation is matched against both root sets,
    // the containing one deciding the realm, and that an attestation from an
    // unknown signer is rejected, naming the signer.
    #[test]
    fn test_root_selection() {
        let hardware = xdsa::SecretKey::generate().public_key();
        let emulator = xdsa::SecretKey::generate();
        let identity = xdsa::SecretKey::generate().public_key();
        let attestation = cwt::issue(
            &emulator_claims(identity, 1000, 2000),
            &emulator,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();

        let device = verify(
            &attestation,
            std::slice::from_ref(&hardware),
            &[emulator.public_key()],
            None,
        )
        .unwrap();
        assert_eq!(device.realm, Realm::Emulator, "realm mismatch");

        match verify(&attestation, &[hardware], &[], None) {
            Err(Error::UntrustedSigner {
                fingerprint: signer,
                root: None,
            }) => {
                assert_eq!(
                    signer,
                    emulator.public_key().fingerprint(),
                    "signer mismatch"
                );
            }
            other => panic!("signer not rejected as unexpected, got {other:?}"),
        }
    }

    // Tests that the validity period is enforced when a time is given, hardware
    // attestations staying valid indefinitely and emulator ones expiring.
    #[test]
    fn test_validity_period() {
        let root = xdsa::SecretKey::generate();
        let identity = xdsa::SecretKey::generate().public_key();
        let attestation = cwt::issue(
            &hardware_claims(identity.clone()),
            &root,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();
        assert!(
            matches!(
                verify(&attestation, &[root.public_key()], &[], Some(999)),
                Err(Error::Cwt(cwt::Error::NotYetValid { .. }))
            ),
            "attestation accepted before validity"
        );
        verify(&attestation, &[root.public_key()], &[], Some(u64::MAX))
            .expect("hardware attestation expired");

        let attestation = cwt::issue(
            &emulator_claims(identity, 1000, 2000),
            &root,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();
        assert!(
            matches!(
                verify(&attestation, &[], &[root.public_key()], Some(2000)),
                Err(Error::Cwt(cwt::Error::AlreadyExpired { .. }))
            ),
            "attestation accepted after expiry"
        );
        verify(&attestation, &[], &[root.public_key()], None)
            .expect("timeless verification failed");
    }

    // Tests that an attestation self-signed by its embedded identity is accepted
    // in either shape, yielding the identity, and that it is never mistaken for
    // a root attested device.
    #[test]
    fn test_self_signed() {
        let secret = xdsa::SecretKey::generate();
        let identity = secret.public_key();
        let root = xdsa::SecretKey::generate().public_key();

        for attestation in [
            cwt::issue(
                &hardware_claims(identity.clone()),
                &secret,
                CRYPTO_DOMAIN_DEVICE_ATTESTATION,
            )
            .unwrap(),
            cwt::issue(
                &emulator_claims(identity.clone(), 1000, 2000),
                &secret,
                CRYPTO_DOMAIN_DEVICE_ATTESTATION,
            )
            .unwrap(),
        ] {
            assert_eq!(
                verify_self_signed(&attestation).unwrap().fingerprint(),
                identity.fingerprint(),
                "identity mismatch"
            );
            assert!(
                matches!(
                    verify(&attestation, std::slice::from_ref(&root), &[], None),
                    Err(Error::UntrustedSigner { .. })
                ),
                "self-signed attestation accepted as attested"
            );
        }
    }

    // Tests that an attestation signed by anyone other than its embedded
    // identity is not self-signed, whether by a root or by a third party.
    #[test]
    fn test_self_signed_rejects_foreign_signer() {
        let identity = xdsa::SecretKey::generate().public_key();
        let attestation = cwt::issue(
            &hardware_claims(identity),
            &xdsa::SecretKey::generate(),
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();
        assert!(
            matches!(verify_self_signed(&attestation), Err(Error::NotSelfSigned)),
            "foreign signed attestation accepted as self-signed"
        );
        assert!(
            matches!(verify_self_signed(b"junk"), Err(Error::Cwt(_))),
            "junk accepted as self-signed"
        );
    }

    // Tests that the length of an emulator attestation's validity period is
    // capped whether or not a time is given, an empty or inverted period being
    // rejected too, with the cap itself being the longest period accepted. The
    // cap is checked after the time, so a period the time already fails is
    // reported as such.
    #[test]
    fn test_emulator_validity_cap() {
        let root = xdsa::SecretKey::generate();
        let identity = xdsa::SecretKey::generate().public_key();
        let max = EMULATOR_ATTESTATION_MAX_VALIDITY.as_secs();

        for (nbf, exp, accept) in [
            (1000, 1000 + max, true),
            (1000, 1000 + max + 1, false),
            (1000, 1000, false),
            (2000, 1000, false),
        ] {
            let attestation = cwt::issue(
                &emulator_claims(identity.clone(), nbf, exp),
                &root,
                CRYPTO_DOMAIN_DEVICE_ATTESTATION,
            )
            .unwrap();

            for now in [None, Some(1500)] {
                let timely = now.is_none_or(|now| nbf <= now && now < exp);
                let result = verify(&attestation, &[], &[root.public_key()], now);
                match (accept, timely) {
                    (true, _) => {
                        result.expect("valid attestation rejected");
                    }
                    (false, true) => assert!(
                        matches!(result, Err(Error::InvalidValidity { max }) if max == EMULATOR_ATTESTATION_MAX_VALIDITY),
                        "attestation accepted with validity {nbf} to {exp} at {now:?}"
                    ),
                    (false, false) => assert!(
                        matches!(result, Err(Error::Cwt(_))),
                        "untimely attestation not rejected by the time check at {now:?}"
                    ),
                }
            }
        }
    }

    // Verification returns the device fields and applies the clock through cwt
    // when requested, while always authenticating the signature.
    #[test]
    fn test_hardware_fields() {
        let root = xdsa::SecretKey::generate();
        let roots = [root.public_key()];
        let identity = xdsa::SecretKey::generate().public_key();
        let mut claims = hardware_claims(identity.clone());
        claims.nbf.nbf = 1400;
        let mut token = cwt::issue(&claims, &root, CRYPTO_DOMAIN_DEVICE_ATTESTATION).unwrap();
        let device = verify(&token, &roots, &[], None).unwrap();
        assert_eq!(device.identity.fingerprint(), identity.fingerprint());
        assert_eq!(device.issued, 1000);
        assert_eq!(device.oem.pen(), Some(65145));
        assert!(matches!(
            verify(&token, &roots, &[], Some(1399)),
            Err(Error::Cwt(cwt::Error::NotYetValid {
                nbf: 1400,
                now: 1399
            }))
        ));
        verify(&token, &roots, &[], Some(1400)).unwrap();
        *token.last_mut().unwrap() ^= 1;
        assert!(matches!(
            verify(&token, &roots, &[], None),
            Err(Error::Cwt(_))
        ));
    }

    #[test]
    fn test_emulator_fields() {
        let root = xdsa::SecretKey::generate();
        let roots = [root.public_key()];
        let identity = xdsa::SecretKey::generate().public_key();
        let max = EMULATOR_ATTESTATION_MAX_VALIDITY.as_secs();
        let token = cwt::issue(
            &emulator_claims(identity, 1000, 1000 + max),
            &root,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();
        let device = verify(&token, &[], &roots, None).unwrap();
        assert_eq!(device.realm, Realm::Emulator);
        assert_eq!(device.expiry, Some(1000 + max));
        verify(&token, &[], &roots, Some(1000)).unwrap();
        verify(&token, &[], &roots, Some(1000 + max - 1)).unwrap();
        assert!(matches!(
            verify(&token, &[], &roots, Some(1000 + max)),
            Err(Error::Cwt(cwt::Error::AlreadyExpired { .. }))
        ));
    }

    // A forged header can name a known root. Its metadata is only a hint and
    // never authenticates the token, even when the claimed key is embedded.
    #[test]
    fn test_unverified_signer_hint() {
        let attacker = xdsa::SecretKey::generate();
        let mut token = cwt::issue(
            &hardware_claims(attacker.public_key()),
            &attacker,
            CRYPTO_DOMAIN_DEVICE_ATTESTATION,
        )
        .unwrap();
        let mut bytes = [0; 32];
        hex::decode_to_slice(
            "fe56b1de20bde6010569c90e611197356ad521c5e3d27f7afbbb65b5600bbb12",
            &mut bytes,
        )
        .unwrap();
        let claimed = xdsa::Fingerprint::from_bytes(&bytes);
        let claimed_root = crate::roots::identify(&claimed).unwrap();
        let fingerprint = attacker.fingerprint().to_bytes();
        let offsets: Vec<_> = token
            .windows(32)
            .enumerate()
            .filter(|(_, bytes)| *bytes == fingerprint)
            .map(|(i, _)| i)
            .collect();
        assert_eq!(offsets.len(), 1);
        token[offsets[0]..offsets[0] + 32].copy_from_slice(&claimed.to_bytes());
        let err = verify(&token, &[], &[], None).unwrap_err();
        assert!(
            matches!(&err, Error::UntrustedSigner { fingerprint, root: Some(info) } if *fingerprint == claimed && *info == claimed_root)
        );
        assert!(err.to_string().starts_with("attestation signed by the "));
        let roots = crate::roots::hardware(claimed_root.env);
        if !roots.is_empty() {
            assert!(matches!(
                verify(&token, roots, &[], None),
                Err(Error::Cwt(_))
            ));
        }
    }
}