mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 20:06:37 +00:00
3b5164032a
A RustFS cluster device needs a durable identity before it can exchange a one-time registration token for a certificate. This adds the device-side half of that exchange, which rustfs/connect already verifies. `connect::identity` builds the canonical registration transcript frozen by protocol/agent/v1/registration-proof.md, signs it as low-S ES256, and emits the PKCS#10 certificate request Connect consumes for its SubjectPublicKeyInfo. `connect::identity_store` seals the P-256 key at mode 0600 and publishes it through a no-clobber link, so a retry or a concurrent start returns the original identity rather than minting a second one, and a corrupt or widened key is refused rather than silently replaced. The protocol fixture set is copied here byte-identically because fixture-sets.json names this repository as the consumer copy; the tests verify it against its own manifests and cross-verify Connect-produced ECDSA proofs against transcripts rebuilt locally. Nothing starts a task or touches the S3 data path: an unenrolled deployment generates no key and holds no identity.
196 lines
5.7 KiB
JSON
196 lines
5.7 KiB
JSON
{
|
|
"protocolVersion": "v1",
|
|
"fixtureSet": "auth",
|
|
"fixture": "reject-vectors",
|
|
"description": "Presented certificates that must not authenticate. A credential that is known but unusable still resolves, so the rejection can be audited against a device instead of being reported as an unknown certificate.",
|
|
"vectors": [
|
|
{
|
|
"name": "revoked credential",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": "revoke"
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "matching",
|
|
"certificateFingerprint": "matching"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": true,
|
|
"authenticationEffective": false,
|
|
"reason": "CREDENTIAL_REVOKED"
|
|
}
|
|
},
|
|
{
|
|
"name": "compromised credential",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": "markCompromised"
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "matching",
|
|
"certificateFingerprint": "matching"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": true,
|
|
"authenticationEffective": false,
|
|
"reason": "CREDENTIAL_COMPROMISED"
|
|
}
|
|
},
|
|
{
|
|
"name": "credential whose validity window has closed",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -86460,
|
|
"validUntilOffsetSeconds": -60,
|
|
"transition": null
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "matching",
|
|
"certificateFingerprint": "matching"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": true,
|
|
"authenticationEffective": false,
|
|
"reason": "CREDENTIAL_EXPIRED"
|
|
}
|
|
},
|
|
{
|
|
"name": "credential whose validity window has not opened",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": 3600,
|
|
"validUntilOffsetSeconds": 90000,
|
|
"transition": null
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "matching",
|
|
"certificateFingerprint": "matching"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": true,
|
|
"authenticationEffective": false,
|
|
"reason": "CREDENTIAL_NOT_YET_VALID"
|
|
}
|
|
},
|
|
{
|
|
"name": "intact credential on a disabled cluster",
|
|
"clusterState": "DISABLED",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": null
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "matching",
|
|
"certificateFingerprint": "matching"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": true,
|
|
"authenticationEffective": false,
|
|
"reason": "CLUSTER_DISABLED"
|
|
}
|
|
},
|
|
{
|
|
"name": "intact credential on a deleted cluster",
|
|
"clusterState": "DELETED",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": null
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "matching",
|
|
"certificateFingerprint": "matching"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": true,
|
|
"authenticationEffective": false,
|
|
"reason": "CLUSTER_DELETED"
|
|
}
|
|
},
|
|
{
|
|
"name": "certificate Connect never issued",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": null
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "unrelated",
|
|
"certificateFingerprint": "unrelated"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": false,
|
|
"authenticationEffective": false,
|
|
"reason": "CLIENT_CERTIFICATE_UNKNOWN"
|
|
}
|
|
},
|
|
{
|
|
"name": "issued serial presented with a substituted certificate",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": null
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "matching",
|
|
"certificateFingerprint": "unrelated"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": false,
|
|
"authenticationEffective": false,
|
|
"reason": "CLIENT_CERTIFICATE_UNKNOWN"
|
|
}
|
|
},
|
|
{
|
|
"name": "issued certificate presented under a substituted serial",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": null
|
|
},
|
|
"presented": {
|
|
"credential": "current",
|
|
"serial": "unrelated",
|
|
"certificateFingerprint": "matching"
|
|
},
|
|
"expected": {
|
|
"credentialResolved": false,
|
|
"authenticationEffective": false,
|
|
"reason": "CLIENT_CERTIFICATE_UNKNOWN"
|
|
}
|
|
}
|
|
],
|
|
"tenantVector": {
|
|
"name": "authenticated device reaching a resource owned by another organization",
|
|
"description": "The certificate is valid and its credential is effective. Only the stored organization decides what the device may reach, and the certificate carries no organization identifier to contradict it.",
|
|
"clusterState": "ACTIVE",
|
|
"credential": {
|
|
"validFromOffsetSeconds": -3600,
|
|
"validUntilOffsetSeconds": 82800,
|
|
"transition": null
|
|
},
|
|
"expected": {
|
|
"credentialResolved": true,
|
|
"authenticationEffective": true,
|
|
"resolvedIdentityBelongsToForeignOrganization": false,
|
|
"reason": "TENANT_MISMATCH"
|
|
}
|
|
}
|
|
}
|