Skip to content

Commit bcc878f

Browse files
committed
Revert Pattern B (key endorsement via countersignature)
Pattern B was added in 776873b alongside Pattern A but is no longer in scope. This commit drops the entire Pattern B surface: - spec: removes Section 12.2 (Key Endorsement via Countersignature) and Section 12.2.1 (Issuance Workflows), trims the Section 6.4 pointer back to Section 12.1 only, and removes the corresponding TOC entries. - impl: removes src/endorse.rs, removes verify::key_endorsements, and drops the related exports from lib.rs. - tests: removes all pattern_b_* tests and the issue_endorsement / embed_endorsement coverage from tests/multi_signer.rs. - README: removes the Pattern B paragraphs and code snippets from the Trust patterns section, leaving only Pattern A. Pattern A (self-binding key attestations) is unchanged. https://claude.ai/code/session_01ST4PcjqvobURus32WuyEi5
1 parent 776873b commit bcc878f

6 files changed

Lines changed: 8 additions & 834 deletions

File tree

reference/PCF-SIG-v1.0/README.md

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ for report in verify_all_with_recheck(&mut c)? {
7777

7878
## Trust patterns
7979

80-
The profile defines two non-X.509 ways for an application to express trust;
81-
both are described in spec Section 12.
80+
The profile describes one non-X.509 way for an application to express trust
81+
in spec Section 12.
8282

8383
**Pattern A — self-binding key attestations.** Carry a JWT, SCITT statement,
8484
or custom signed envelope as an application-private TLV entry (tag range
@@ -88,49 +88,6 @@ JWT `cnf.jkt`); otherwise the binding is meaningless because the fingerprint
8888
covers only `key_data`, not the TLV. The application verifies the
8989
attestation independently of PCF-SIG.
9090

91-
**Pattern B — key endorsement via countersignature.** A "CA" emits a
92-
`PCFSIG_SIG` partition whose manifest covers the leaf signer's `PCFSIG_KEY`
93-
partition by uid. Verifiers report it like any other signature; the
94-
application checks whether any trusted CA fingerprint endorses the leaf key.
95-
96-
```rust
97-
use pcf_sig::{key_endorsements, verify_all_with_recheck};
98-
99-
let reports = verify_all_with_recheck(&mut container)?;
100-
let endorsers = key_endorsements(&mut container, &reports, &leaf_fingerprint)?;
101-
let trusted = endorsers.iter().any(|fp| my_trusted_ca_set.contains(fp));
102-
# Ok::<(), pcf_sig::Error>(())
103-
```
104-
105-
For Pattern B the CA does NOT need the leaf's PCF file. The stateless
106-
workflow (spec 12.2.1 W2): the client sends only the leaf key bytes plus the
107-
planned partition identity; the CA returns a self-contained response that
108-
the client embeds locally.
109-
110-
```rust
111-
use pcf_sig::{embed_endorsement, issue_endorsement, EndorsementRequest, KeyFormat};
112-
use pcf::HashAlgo;
113-
114-
// CA side (stateless; no I/O, no file):
115-
let request = EndorsementRequest {
116-
key_format: KeyFormat::Ed25519Raw,
117-
key_data: leaf_public_key_bytes,
118-
intended_uid: agreed_uid, // stable across leaf and CA
119-
intended_label: agreed_label,
120-
data_hash_algo: HashAlgo::Sha256,
121-
};
122-
let response = issue_endorsement(&ca_signer, &request, signed_at)?;
123-
124-
// Client side: embed into the local container:
125-
embed_endorsement(&mut container, &response, ca_key_uid, ca_sig_uid, "ca-key", "ca-sig")?;
126-
# Ok::<(), pcf_sig::Error>(())
127-
```
128-
129-
Because the response commits to the leaf `PCFSIG_KEY` bytes (not to any file
130-
location), a client may also cache and re-use the same response across many
131-
PCF files in which the leaf KEY partition is reproduced byte-identical
132-
(workflow W3, license pattern).
133-
13491
## Relocation stability
13592

13693
The central property: a PCFSIG_SIG signature remains valid across any

reference/PCF-SIG-v1.0/src/endorse.rs

Lines changed: 0 additions & 182 deletions
This file was deleted.

reference/PCF-SIG-v1.0/src/lib.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
5050
mod algo;
5151
pub mod consts;
52-
mod endorse;
5352
mod error;
5453
mod key;
5554
mod manifest;
@@ -59,10 +58,6 @@ mod verify;
5958

6059
pub use algo::{KeyFormat, SigAlgo};
6160
pub use consts::*;
62-
pub use endorse::{
63-
embed_endorsement, expected_leaf_key_data_hash, fingerprint_of, issue_endorsement,
64-
EndorsementRequest, EndorsementResponse,
65-
};
6661
pub use error::{Error, Result};
6762
pub use key::{compute_fingerprint, KeyMetadata, KeyRecord};
6863
pub use manifest::{is_crypto_hash, Manifest, SignedEntry};
@@ -71,6 +66,6 @@ pub use sign::{
7166
ensure_key_partition, sign_partitions, signed_entry_from_partition, SigningMaterial,
7267
};
7368
pub use verify::{
74-
key_endorsements, verify_all, verify_all_with_recheck, DataRecheck, EntryReport, EntryVerdict,
75-
ManifestVerdict, SignatureReport, UnverifiableReason,
69+
verify_all, verify_all_with_recheck, DataRecheck, EntryReport, EntryVerdict, ManifestVerdict,
70+
SignatureReport, UnverifiableReason,
7671
};

reference/PCF-SIG-v1.0/src/verify.rs

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -98,63 +98,6 @@ pub enum DataRecheck {
9898
Recompute,
9999
}
100100

101-
/// Find every signer whose Valid signature in `reports` countersigns the
102-
/// PCFSIG_KEY partition whose fingerprint is `leaf_key_fingerprint` (spec
103-
/// Section 12.2). Returns the deduplicated `signer_key_fingerprint`s of those
104-
/// signers, in first-seen order. Self-endorsement (a signer endorsing its own
105-
/// key) is filtered out as semantically vacuous.
106-
///
107-
/// The container is consulted to locate the leaf PCFSIG_KEY partition by
108-
/// fingerprint; if no such partition exists in the file the result is empty.
109-
///
110-
/// The reports passed in MUST come from [`verify_all`] or
111-
/// [`verify_all_with_recheck`] on the same container; the function does not
112-
/// re-verify any signatures.
113-
pub fn key_endorsements<S: Read + Write + Seek>(
114-
container: &mut Container<S>,
115-
reports: &[SignatureReport],
116-
leaf_key_fingerprint: &[u8; FINGERPRINT_SIZE],
117-
) -> Result<Vec<[u8; FINGERPRINT_SIZE]>> {
118-
// 1. Locate the leaf PCFSIG_KEY partition's PCF uid by fingerprint.
119-
let entries = container.entries()?;
120-
let mut leaf_key_uid: Option<[u8; UID_SIZE]> = None;
121-
for e in &entries {
122-
if e.partition_type == TYPE_PCFSIG_KEY {
123-
let data = container.read_partition_data(e)?;
124-
if let Ok(rec) = KeyRecord::from_bytes(&data) {
125-
if &rec.fingerprint == leaf_key_fingerprint {
126-
leaf_key_uid = Some(e.uid);
127-
break;
128-
}
129-
}
130-
}
131-
}
132-
let leaf_key_uid = match leaf_key_uid {
133-
Some(u) => u,
134-
None => return Ok(Vec::new()),
135-
};
136-
137-
// 2. Scan reports for Valid signatures whose manifests cover that uid.
138-
let mut endorsers: Vec<[u8; FINGERPRINT_SIZE]> = Vec::new();
139-
for r in reports {
140-
if !matches!(r.verdict, ManifestVerdict::Valid) {
141-
continue;
142-
}
143-
if &r.signer_key_fingerprint == leaf_key_fingerprint {
144-
// Self-endorsement is semantically empty.
145-
continue;
146-
}
147-
let endorses = r
148-
.entries
149-
.iter()
150-
.any(|er| er.uid == leaf_key_uid && matches!(er.verdict, EntryVerdict::Valid));
151-
if endorses && !endorsers.contains(&r.signer_key_fingerprint) {
152-
endorsers.push(r.signer_key_fingerprint);
153-
}
154-
}
155-
Ok(endorsers)
156-
}
157-
158101
/// Verify every PCFSIG_SIG partition in `container` and return one report
159102
/// each. Returns an empty vector if the container has no signatures.
160103
pub fn verify_all<S: Read + Write + Seek>(

0 commit comments

Comments
 (0)