@floegence/redevplugin-contracts 0.7.26 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/contracts.gen.d.ts +87 -267
- package/dist/contracts.gen.js +87 -300
- package/dist/index.d.ts +37 -121
- package/dist/release-signing.d.ts +4 -177
- package/dist/release-signing.js +21 -371
- package/package.json +2 -2
package/dist/release-signing.js
CHANGED
|
@@ -2,19 +2,11 @@ export const rootDelegationSchemaVersion = "redevplugin.release_root_delegation.
|
|
|
2
2
|
export const packageSignatureSchemaVersion = "redevplugin.package_signature.v1";
|
|
3
3
|
export const releaseMetadataSchemaVersionV8 = "redevplugin.release_metadata.v8";
|
|
4
4
|
export const releaseMetadataSchemaVersion = releaseMetadataSchemaVersionV8;
|
|
5
|
-
export const sourcePolicySchemaVersion = "redevplugin.release_source_policy.
|
|
5
|
+
export const sourcePolicySchemaVersion = "redevplugin.release_source_policy.v3";
|
|
6
6
|
export const sourcePolicyPointerSchemaVersion = "redevplugin.release_source_policy_pointer.v1";
|
|
7
7
|
export const revocationSchemaVersion = "redevplugin.release_revocation.v2";
|
|
8
8
|
export const revocationPointerSchemaVersion = "redevplugin.release_revocation_pointer.v1";
|
|
9
|
-
export const releaseSigningLedgerEvidenceSchemaVersion = "redevplugin.release_signing_ledger_evidence.v1";
|
|
10
|
-
export const signingSubjectSchemaVersion = "redevplugin.release_signing_subject.v1";
|
|
11
|
-
export const signatureEnvelopeSchemaVersion = "redevplugin.release_signature_envelope.v1";
|
|
12
|
-
export const signingLedgerSchemaVersion = "redevplugin.release_signing_ledger.v1";
|
|
13
|
-
export const signingLedgerEntrySchemaVersion = "redevplugin.release_signing_ledger_entry.v1";
|
|
14
|
-
export const signingLedgerLogLeafSchemaVersion = "redevplugin.release_signing_ledger_log_leaf.v1";
|
|
15
|
-
export const signingLedgerReceiptSchemaVersion = "redevplugin.release_signing_ledger_receipt.v1";
|
|
16
9
|
export const signatureAlgorithmEd25519 = "ed25519";
|
|
17
|
-
export const genesisPreviousEpoch = "0";
|
|
18
10
|
export const genesisPreviousDocumentSHA256 = "0".repeat(64);
|
|
19
11
|
export const signingUsages = {
|
|
20
12
|
rootDelegation: "redevplugin.release-signing.root-delegation.v1",
|
|
@@ -26,9 +18,8 @@ export const signingUsages = {
|
|
|
26
18
|
revocationPointer: "redevplugin.release-signing.revocation-pointer.v1",
|
|
27
19
|
};
|
|
28
20
|
export const defaultSourcePolicyLimits = Object.freeze({
|
|
29
|
-
document_max_lifetime_seconds:
|
|
21
|
+
document_max_lifetime_seconds: 7776000,
|
|
30
22
|
future_skew_seconds: 300,
|
|
31
|
-
activation_lease_max_seconds: 300,
|
|
32
23
|
refresh_interval_max_seconds: 60,
|
|
33
24
|
failure_teardown_deadline_seconds: 30,
|
|
34
25
|
});
|
|
@@ -65,13 +56,10 @@ const signaturePattern = /^[A-Za-z0-9+/]{86}==$/;
|
|
|
65
56
|
const delegatedUsageOrder = [
|
|
66
57
|
"package",
|
|
67
58
|
"release_metadata",
|
|
68
|
-
"host_capability_contract",
|
|
69
59
|
"revocation_document",
|
|
70
60
|
"revocation_pointer",
|
|
71
61
|
"source_policy_document",
|
|
72
62
|
"source_policy_pointer",
|
|
73
|
-
"signing_ledger",
|
|
74
|
-
"trusted_time",
|
|
75
63
|
];
|
|
76
64
|
function invalidDocument() {
|
|
77
65
|
throw new InvalidReleaseDocumentError();
|
|
@@ -267,20 +255,6 @@ function validateTimeRange(generatedAt, expiresAt, maximumMilliseconds = 0) {
|
|
|
267
255
|
invalidDocument();
|
|
268
256
|
}
|
|
269
257
|
}
|
|
270
|
-
function validateEpochChain(epoch, previousEpoch, previousDigest) {
|
|
271
|
-
if (!matchesPattern(positiveEpochPattern, epoch) || !matchesPattern(epochPattern, previousEpoch) || !matchesPattern(sha256Pattern, previousDigest)) {
|
|
272
|
-
invalidDocument();
|
|
273
|
-
}
|
|
274
|
-
if (BigInt(previousEpoch) + 1n !== BigInt(epoch))
|
|
275
|
-
invalidDocument();
|
|
276
|
-
if (previousEpoch === genesisPreviousEpoch) {
|
|
277
|
-
if (previousDigest !== genesisPreviousDocumentSHA256)
|
|
278
|
-
invalidDocument();
|
|
279
|
-
}
|
|
280
|
-
else if (previousDigest === genesisPreviousDocumentSHA256) {
|
|
281
|
-
invalidDocument();
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
258
|
function validateSortedIDs(values, minimum, maximum, lower = true) {
|
|
285
259
|
if (!Array.isArray(values) || values.length < minimum || values.length > maximum)
|
|
286
260
|
invalidDocument();
|
|
@@ -303,7 +277,8 @@ function validateRootDelegation(value, requireSignature) {
|
|
|
303
277
|
closeRootDelegation(value);
|
|
304
278
|
if (value.schema_version !== rootDelegationSchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.key_id))
|
|
305
279
|
invalidDocument();
|
|
306
|
-
|
|
280
|
+
if (!matchesPattern(positiveEpochPattern, value.root_epoch))
|
|
281
|
+
invalidDocument();
|
|
307
282
|
validateTimeRange(value.generated_at, value.expires_at);
|
|
308
283
|
if (!Array.isArray(value.delegated_keys) || value.delegated_keys.length < 1 || value.delegated_keys.length > 32)
|
|
309
284
|
invalidDocument();
|
|
@@ -321,11 +296,7 @@ function validateRootDelegation(value, requireSignature) {
|
|
|
321
296
|
invalidDocument();
|
|
322
297
|
previousUsage = rank;
|
|
323
298
|
}
|
|
324
|
-
|
|
325
|
-
const hasSourceWide = key.usages.some((usage) => usage === "signing_ledger" || usage === "trusted_time");
|
|
326
|
-
if (hasSourceWide !== sourceWide)
|
|
327
|
-
invalidDocument();
|
|
328
|
-
validateSortedIDs(key.channels, sourceWide ? 0 : 1, sourceWide ? 0 : 16);
|
|
299
|
+
validateSortedIDs(key.channels, 1, 16);
|
|
329
300
|
validateTimeRange(key.valid_from, key.valid_until);
|
|
330
301
|
if (parseCanonicalTime(key.valid_until) > parseCanonicalTime(value.expires_at))
|
|
331
302
|
invalidDocument();
|
|
@@ -445,13 +416,8 @@ function validReleaseMetadataUIProtocolPair(schemaVersion, uiProtocolVersion) {
|
|
|
445
416
|
return schemaVersion === releaseMetadataSchemaVersionV8 && uiProtocolVersion === "plugin-ui-v7";
|
|
446
417
|
}
|
|
447
418
|
function validateCapabilityContractRef(value) {
|
|
448
|
-
if (![value.publisher_id, value.contract_id
|
|
449
|
-
|
|
450
|
-
if (!matchesPattern(epochPattern, value.signature_policy_epoch) || !matchesPattern(epochPattern, value.signature_revocation_epoch))
|
|
451
|
-
invalidDocument();
|
|
452
|
-
if (![value.artifact_ref, value.manifest_ref, value.signature_ref, value.compatibility_ref, value.generated_client_ref, value.notices_ref].every(validArtifactRef))
|
|
453
|
-
invalidDocument();
|
|
454
|
-
if (![value.artifact_sha256, value.manifest_sha256, value.signature_sha256, value.compatibility_sha256, value.generated_client_sha256, value.notices_sha256].every((item) => sha256Pattern.test(item)))
|
|
419
|
+
if (![value.publisher_id, value.contract_id].every((item) => matchesPattern(legacyIDPattern, item)) ||
|
|
420
|
+
!matchesPattern(semverPattern, value.contract_version) || !sha256Pattern.test(value.artifact_sha256))
|
|
455
421
|
invalidDocument();
|
|
456
422
|
}
|
|
457
423
|
function validateSourcePolicy(value, requireSignature) {
|
|
@@ -459,7 +425,8 @@ function validateSourcePolicy(value, requireSignature) {
|
|
|
459
425
|
closeSourcePolicy(value);
|
|
460
426
|
if (value.schema_version !== sourcePolicySchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.channel) || !matchesPattern(newIDPattern, value.key_id))
|
|
461
427
|
invalidDocument();
|
|
462
|
-
|
|
428
|
+
if (!matchesPattern(positiveEpochPattern, value.epoch))
|
|
429
|
+
invalidDocument();
|
|
463
430
|
if (!matchesPattern(positiveEpochPattern, value.root_epoch) || !matchesPattern(epochPattern, value.minimum_revocation_epoch))
|
|
464
431
|
invalidDocument();
|
|
465
432
|
if (value.source_type !== "registry" && value.source_type !== "host_artifact")
|
|
@@ -483,17 +450,6 @@ function validateSourcePolicy(value, requireSignature) {
|
|
|
483
450
|
value.active_keys.revocation_pointer,
|
|
484
451
|
])
|
|
485
452
|
validateSortedIDs(keys, 1, 16);
|
|
486
|
-
validateSortedIDs(value.active_keys.host_capability_contract, 0, 16);
|
|
487
|
-
if (!Array.isArray(value.capability_publisher_scopes) || value.capability_publisher_scopes.length !== value.active_keys.host_capability_contract.length)
|
|
488
|
-
invalidDocument();
|
|
489
|
-
for (let index = 0; index < value.capability_publisher_scopes.length; index += 1) {
|
|
490
|
-
const scope = value.capability_publisher_scopes[index];
|
|
491
|
-
assertRecord(scope);
|
|
492
|
-
exactKeys(scope, ["key_id", "allowed_publishers"]);
|
|
493
|
-
if (scope.key_id !== value.active_keys.host_capability_contract[index])
|
|
494
|
-
invalidDocument();
|
|
495
|
-
validateSortedIDs(scope.allowed_publishers, 1, 1024, false);
|
|
496
|
-
}
|
|
497
453
|
if (!new Set(["allow", "review_required", "block"]).has(value.install_policy))
|
|
498
454
|
invalidDocument();
|
|
499
455
|
if (!new Set(["dev_only", "review_required", "block"]).has(value.unsigned_policy))
|
|
@@ -502,7 +458,7 @@ function validateSourcePolicy(value, requireSignature) {
|
|
|
502
458
|
invalidDocument();
|
|
503
459
|
if (canonicalJSONString(value.limits) !== canonicalJSONString(defaultSourcePolicyLimits))
|
|
504
460
|
invalidDocument();
|
|
505
|
-
validateTimeRange(value.generated_at, value.expires_at, 24 * 60 * 60 * 1000);
|
|
461
|
+
validateTimeRange(value.generated_at, value.expires_at, 90 * 24 * 60 * 60 * 1000);
|
|
506
462
|
if (requireSignature)
|
|
507
463
|
decodeBase64(value.signature, 64);
|
|
508
464
|
else if (value.signature !== "")
|
|
@@ -513,7 +469,8 @@ function validatePointer(value, expectedSchemaVersion, requireSignature) {
|
|
|
513
469
|
closePointer(value);
|
|
514
470
|
if (value.schema_version !== expectedSchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.channel) || !matchesPattern(newIDPattern, value.key_id))
|
|
515
471
|
invalidDocument();
|
|
516
|
-
|
|
472
|
+
if (!matchesPattern(positiveEpochPattern, value.epoch))
|
|
473
|
+
invalidDocument();
|
|
517
474
|
if (!validArtifactRef(value.ref) || !sha256Pattern.test(value.document_sha256) || value.document_sha256 === genesisPreviousDocumentSHA256)
|
|
518
475
|
invalidDocument();
|
|
519
476
|
validateTimeRange(value.generated_at, value.expires_at, 24 * 60 * 60 * 1000);
|
|
@@ -527,7 +484,8 @@ function validateRevocation(value, requireSignature) {
|
|
|
527
484
|
closeRevocation(value);
|
|
528
485
|
if (value.schema_version !== revocationSchemaVersion || !matchesPattern(newIDPattern, value.source_id) || !matchesPattern(newIDPattern, value.channel) || !matchesPattern(newIDPattern, value.key_id))
|
|
529
486
|
invalidDocument();
|
|
530
|
-
|
|
487
|
+
if (!matchesPattern(positiveEpochPattern, value.epoch))
|
|
488
|
+
invalidDocument();
|
|
531
489
|
if (!matchesPattern(positiveEpochPattern, value.root_epoch))
|
|
532
490
|
invalidDocument();
|
|
533
491
|
validateTimeRange(value.generated_at, value.expires_at, 24 * 60 * 60 * 1000);
|
|
@@ -550,181 +508,6 @@ function validateRevocation(value, requireSignature) {
|
|
|
550
508
|
else if (value.signature !== "")
|
|
551
509
|
invalidDocument();
|
|
552
510
|
}
|
|
553
|
-
function validateSigningLedgerEvidence(value) {
|
|
554
|
-
assertRecord(value);
|
|
555
|
-
closeSigningLedgerEvidence(value);
|
|
556
|
-
if (value.schema_version !== releaseSigningLedgerEvidenceSchemaVersion || !matchesPattern(newIDPattern, value.source_id))
|
|
557
|
-
invalidDocument();
|
|
558
|
-
if (value.channel !== undefined && !matchesPattern(newIDPattern, value.channel))
|
|
559
|
-
invalidDocument();
|
|
560
|
-
for (const digest of [
|
|
561
|
-
value.subject_identity_sha256,
|
|
562
|
-
value.signing_preimage_sha256,
|
|
563
|
-
value.signature_envelope_sha256,
|
|
564
|
-
value.receipt_sha256,
|
|
565
|
-
value.checkpoint_sha256,
|
|
566
|
-
value.inclusion_proof_sha256,
|
|
567
|
-
value.latest_proof_sha256,
|
|
568
|
-
]) {
|
|
569
|
-
if (!sha256Pattern.test(digest))
|
|
570
|
-
invalidDocument();
|
|
571
|
-
}
|
|
572
|
-
for (const reference of [
|
|
573
|
-
value.receipt_ref,
|
|
574
|
-
value.checkpoint_ref,
|
|
575
|
-
value.inclusion_proof_ref,
|
|
576
|
-
value.latest_proof_ref,
|
|
577
|
-
]) {
|
|
578
|
-
if (!validArtifactRef(reference))
|
|
579
|
-
invalidDocument();
|
|
580
|
-
}
|
|
581
|
-
if ((value.consistency_proof_ref === undefined) !== (value.consistency_proof_sha256 === undefined))
|
|
582
|
-
invalidDocument();
|
|
583
|
-
if (value.consistency_proof_ref !== undefined && (!validArtifactRef(value.consistency_proof_ref) || !sha256Pattern.test(value.consistency_proof_sha256)))
|
|
584
|
-
invalidDocument();
|
|
585
|
-
}
|
|
586
|
-
function validateSigningSubject(value) {
|
|
587
|
-
assertRecord(value);
|
|
588
|
-
closeSigningSubject(value);
|
|
589
|
-
if (value.schema_version !== signingSubjectSchemaVersion || !matchesPattern(newIDPattern, value.source_id))
|
|
590
|
-
invalidDocument();
|
|
591
|
-
if (value.usage === "root_delegation") {
|
|
592
|
-
if (!matchesPattern(positiveEpochPattern, value.root_epoch))
|
|
593
|
-
invalidDocument();
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
if (value.usage === "package" || value.usage === "release_metadata") {
|
|
597
|
-
if (!matchesPattern(newIDPattern, value.channel) || !matchesPattern(legacyIDPattern, value.publisher_id) ||
|
|
598
|
-
!matchesPattern(legacyIDPattern, value.plugin_id) || !matchesPattern(semverPattern, value.version) ||
|
|
599
|
-
!matchesPattern(sha256Pattern, value.artifact_or_metadata_identity_sha256))
|
|
600
|
-
invalidDocument();
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
if (["source_policy_document", "source_policy_pointer", "revocation_document", "revocation_pointer"].includes(value.usage)) {
|
|
604
|
-
if (!matchesPattern(newIDPattern, value.channel) || !matchesPattern(positiveEpochPattern, value.epoch))
|
|
605
|
-
invalidDocument();
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
invalidDocument();
|
|
609
|
-
}
|
|
610
|
-
function validateSignatureEnvelope(value) {
|
|
611
|
-
assertRecord(value);
|
|
612
|
-
closeSignatureEnvelope(value);
|
|
613
|
-
if (value.schema_version !== signatureEnvelopeSchemaVersion || !matchesPattern(sha256Pattern, value.subject_identity_sha256) ||
|
|
614
|
-
!matchesPattern(sha256Pattern, value.signing_preimage_sha256) || value.algorithm !== signatureAlgorithmEd25519 ||
|
|
615
|
-
!matchesPattern(newIDPattern, value.key_id))
|
|
616
|
-
invalidDocument();
|
|
617
|
-
decodeBase64(value.signature, 64);
|
|
618
|
-
}
|
|
619
|
-
function validateSigningLedgerEntry(value) {
|
|
620
|
-
assertRecord(value);
|
|
621
|
-
closeSigningLedgerEntry(value);
|
|
622
|
-
if (value.schema_version !== signingLedgerEntrySchemaVersion || !matchesPattern(sha256Pattern, value.subject_identity_sha256) ||
|
|
623
|
-
!matchesPattern(sha256Pattern, value.signing_preimage_sha256) || value.algorithm !== signatureAlgorithmEd25519 ||
|
|
624
|
-
!matchesPattern(newIDPattern, value.key_id) || !Number.isSafeInteger(value.revision) || value.revision < 1)
|
|
625
|
-
invalidDocument();
|
|
626
|
-
validateSigningSubject(value.subject);
|
|
627
|
-
const reservedAt = parseCanonicalTime(value.reserved_at);
|
|
628
|
-
if (value.state === "reserved") {
|
|
629
|
-
if (value.signature_envelope !== undefined || value.signature_envelope_sha256 !== undefined || value.finalized_at !== undefined ||
|
|
630
|
-
value.failure_code !== undefined || value.failed_at !== undefined)
|
|
631
|
-
invalidDocument();
|
|
632
|
-
return;
|
|
633
|
-
}
|
|
634
|
-
if (value.state === "finalized") {
|
|
635
|
-
if (value.signature_envelope === undefined || !matchesPattern(sha256Pattern, value.signature_envelope_sha256) ||
|
|
636
|
-
value.finalized_at === undefined || value.failure_code !== undefined || value.failed_at !== undefined)
|
|
637
|
-
invalidDocument();
|
|
638
|
-
validateSignatureEnvelope(value.signature_envelope);
|
|
639
|
-
if (value.signature_envelope.subject_identity_sha256 !== value.subject_identity_sha256 ||
|
|
640
|
-
value.signature_envelope.signing_preimage_sha256 !== value.signing_preimage_sha256 ||
|
|
641
|
-
value.signature_envelope.algorithm !== value.algorithm || value.signature_envelope.key_id !== value.key_id ||
|
|
642
|
-
parseCanonicalTime(value.finalized_at) < reservedAt)
|
|
643
|
-
invalidDocument();
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
|
-
if (value.state === "terminal_failed") {
|
|
647
|
-
if (value.signature_envelope !== undefined || value.signature_envelope_sha256 !== undefined || value.finalized_at !== undefined ||
|
|
648
|
-
value.failure_code === undefined || !["signer_rejected", "subject_conflict", "ledger_rejected"].includes(value.failure_code) ||
|
|
649
|
-
value.failed_at === undefined || parseCanonicalTime(value.failed_at) < reservedAt)
|
|
650
|
-
invalidDocument();
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
invalidDocument();
|
|
654
|
-
}
|
|
655
|
-
function validateSigningLedgerLogLeaf(value) {
|
|
656
|
-
assertRecord(value);
|
|
657
|
-
closeSigningLedgerLogLeaf(value);
|
|
658
|
-
if (value.schema_version !== signingLedgerLogLeafSchemaVersion || !matchesPattern(newIDPattern, value.source_id) ||
|
|
659
|
-
(value.channel !== undefined && !matchesPattern(newIDPattern, value.channel)) ||
|
|
660
|
-
!matchesPattern(sha256Pattern, value.subject_identity_sha256) || !matchesPattern(sha256Pattern, value.signing_preimage_sha256) ||
|
|
661
|
-
!matchesPattern(sha256Pattern, value.signature_envelope_sha256) || !Number.isSafeInteger(value.sequence) || value.sequence < 1)
|
|
662
|
-
invalidDocument();
|
|
663
|
-
}
|
|
664
|
-
function validateSigningLedgerCheckpoint(value) {
|
|
665
|
-
assertRecord(value);
|
|
666
|
-
closeSigningLedgerCheckpoint(value);
|
|
667
|
-
if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "checkpoint" || !matchesPattern(newIDPattern, value.log_id) ||
|
|
668
|
-
!Number.isSafeInteger(value.tree_size) || value.tree_size < 1 || !matchesPattern(sha256Pattern, value.log_root_hash) ||
|
|
669
|
-
!matchesPattern(sha256Pattern, value.latest_map_root_hash) || !matchesPattern(newIDPattern, value.key_id))
|
|
670
|
-
invalidDocument();
|
|
671
|
-
parseCanonicalTime(value.checkpoint_time);
|
|
672
|
-
decodeBase64(value.signature, 64);
|
|
673
|
-
}
|
|
674
|
-
function validateSigningLedgerReceipt(value) {
|
|
675
|
-
assertRecord(value);
|
|
676
|
-
closeSigningLedgerReceipt(value);
|
|
677
|
-
if (value.schema_version !== signingLedgerReceiptSchemaVersion || !matchesPattern(newIDPattern, value.log_id) ||
|
|
678
|
-
!matchesPattern(newIDPattern, value.source_id) || (value.channel !== undefined && !matchesPattern(newIDPattern, value.channel)) ||
|
|
679
|
-
!matchesPattern(sha256Pattern, value.subject_identity_sha256) || !matchesPattern(sha256Pattern, value.signing_preimage_sha256) ||
|
|
680
|
-
!matchesPattern(sha256Pattern, value.signature_envelope_sha256) || !Number.isSafeInteger(value.sequence) || value.sequence < 1 ||
|
|
681
|
-
!Number.isSafeInteger(value.leaf_index) || value.leaf_index !== value.sequence - 1 || !Number.isSafeInteger(value.tree_size) ||
|
|
682
|
-
value.tree_size < value.sequence || !matchesPattern(sha256Pattern, value.log_root_hash) ||
|
|
683
|
-
!matchesPattern(sha256Pattern, value.latest_map_root_hash) || !matchesPattern(sha256Pattern, value.checkpoint_sha256) ||
|
|
684
|
-
!matchesPattern(newIDPattern, value.key_id))
|
|
685
|
-
invalidDocument();
|
|
686
|
-
parseCanonicalTime(value.checkpoint_time);
|
|
687
|
-
decodeBase64(value.signature, 64);
|
|
688
|
-
}
|
|
689
|
-
function validateLedgerNodes(value, exact) {
|
|
690
|
-
if (!Array.isArray(value) || (exact === undefined ? value.length > 64 : value.length !== exact) ||
|
|
691
|
-
value.some((node) => !matchesPattern(sha256Pattern, node)))
|
|
692
|
-
invalidDocument();
|
|
693
|
-
}
|
|
694
|
-
function validateSigningLedgerInclusionProof(value) {
|
|
695
|
-
assertRecord(value);
|
|
696
|
-
closeSigningLedgerInclusionProof(value);
|
|
697
|
-
if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "inclusion_proof" || !matchesPattern(newIDPattern, value.log_id) ||
|
|
698
|
-
!Number.isSafeInteger(value.leaf_index) || value.leaf_index < 0 || !Number.isSafeInteger(value.tree_size) ||
|
|
699
|
-
value.tree_size < 1 || value.leaf_index >= value.tree_size)
|
|
700
|
-
invalidDocument();
|
|
701
|
-
validateLedgerNodes(value.nodes);
|
|
702
|
-
}
|
|
703
|
-
function validateSigningLedgerLatestProof(value) {
|
|
704
|
-
assertRecord(value);
|
|
705
|
-
closeSigningLedgerLatestProof(value);
|
|
706
|
-
if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "latest_proof" || !matchesPattern(newIDPattern, value.log_id) ||
|
|
707
|
-
!matchesPattern(sha256Pattern, value.subject_identity_sha256) || typeof value.present !== "boolean")
|
|
708
|
-
invalidDocument();
|
|
709
|
-
validateLedgerNodes(value.siblings, 256);
|
|
710
|
-
if (value.present) {
|
|
711
|
-
if (!Number.isSafeInteger(value.sequence) || value.sequence < 1 || !matchesPattern(sha256Pattern, value.signing_preimage_sha256) ||
|
|
712
|
-
!matchesPattern(sha256Pattern, value.signature_envelope_sha256))
|
|
713
|
-
invalidDocument();
|
|
714
|
-
}
|
|
715
|
-
else if (value.sequence !== undefined || value.signing_preimage_sha256 !== undefined || value.signature_envelope_sha256 !== undefined) {
|
|
716
|
-
invalidDocument();
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
function validateSigningLedgerConsistencyProof(value) {
|
|
720
|
-
assertRecord(value);
|
|
721
|
-
closeSigningLedgerConsistencyProof(value);
|
|
722
|
-
if (value.schema_version !== signingLedgerSchemaVersion || value.kind !== "consistency_proof" || !matchesPattern(newIDPattern, value.log_id) ||
|
|
723
|
-
!Number.isSafeInteger(value.old_tree_size) || value.old_tree_size < 1 || !Number.isSafeInteger(value.new_tree_size) ||
|
|
724
|
-
value.new_tree_size < value.old_tree_size)
|
|
725
|
-
invalidDocument();
|
|
726
|
-
validateLedgerNodes(value.nodes);
|
|
727
|
-
}
|
|
728
511
|
function decodeCanonicalDocument(raw, close, validate) {
|
|
729
512
|
const bytes = typeof raw === "string" ? textEncoder.encode(raw) : raw;
|
|
730
513
|
if (!(bytes instanceof Uint8Array) || bytes.length < 1 || bytes.length > maximumDocumentBytes)
|
|
@@ -751,7 +534,7 @@ function decodeCanonicalDocument(raw, close, validate) {
|
|
|
751
534
|
return deepFreeze(cloneJSON(parsed));
|
|
752
535
|
}
|
|
753
536
|
function closeRootDelegation(value) {
|
|
754
|
-
exactKeys(value, ["schema_version", "source_id", "root_epoch", "
|
|
537
|
+
exactKeys(value, ["schema_version", "source_id", "root_epoch", "generated_at", "expires_at", "delegated_keys", "key_id", "signature"]);
|
|
755
538
|
if (!Array.isArray(value.delegated_keys))
|
|
756
539
|
invalidDocument();
|
|
757
540
|
for (const item of value.delegated_keys) {
|
|
@@ -788,7 +571,7 @@ function closeReleaseMetadata(value) {
|
|
|
788
571
|
assertRecord(requirement);
|
|
789
572
|
exactKeys(requirement, ["capability_id", "capability_version", "contract"]);
|
|
790
573
|
assertRecord(requirement.contract);
|
|
791
|
-
exactKeys(requirement.contract, ["publisher_id", "contract_id", "contract_version", "
|
|
574
|
+
exactKeys(requirement.contract, ["publisher_id", "contract_id", "contract_version", "artifact_sha256"]);
|
|
792
575
|
}
|
|
793
576
|
}
|
|
794
577
|
}
|
|
@@ -801,17 +584,17 @@ function closeReleaseMetadata(value) {
|
|
|
801
584
|
assertRecord(value.metadata);
|
|
802
585
|
}
|
|
803
586
|
function closeSourcePolicy(value) {
|
|
804
|
-
exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "
|
|
587
|
+
exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "root_epoch", "source_type", "source_class", "allowed_publishers", "allowed_artifact_hosts", "active_keys", "require_signature", "install_policy", "unsigned_policy", "downgrade_policy", "minimum_revocation_epoch", "limits", "generated_at", "expires_at", "key_id", "signature"]);
|
|
805
588
|
assertRecord(value.active_keys);
|
|
806
|
-
exactKeys(value.active_keys, ["package", "release_metadata", "
|
|
589
|
+
exactKeys(value.active_keys, ["package", "release_metadata", "source_policy_pointer", "revocation_document", "revocation_pointer"]);
|
|
807
590
|
assertRecord(value.limits);
|
|
808
|
-
exactKeys(value.limits, ["document_max_lifetime_seconds", "future_skew_seconds", "
|
|
591
|
+
exactKeys(value.limits, ["document_max_lifetime_seconds", "future_skew_seconds", "refresh_interval_max_seconds", "failure_teardown_deadline_seconds"]);
|
|
809
592
|
}
|
|
810
593
|
function closePointer(value) {
|
|
811
|
-
exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "
|
|
594
|
+
exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "ref", "document_sha256", "generated_at", "expires_at", "key_id", "signature"]);
|
|
812
595
|
}
|
|
813
596
|
function closeRevocation(value) {
|
|
814
|
-
exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "
|
|
597
|
+
exactKeys(value, ["schema_version", "source_id", "channel", "epoch", "root_epoch", "generated_at", "expires_at", "revoked_key_ids", "revoked_releases", "key_id", "signature"]);
|
|
815
598
|
if (!Array.isArray(value.revoked_releases))
|
|
816
599
|
invalidDocument();
|
|
817
600
|
for (const item of value.revoked_releases) {
|
|
@@ -819,77 +602,6 @@ function closeRevocation(value) {
|
|
|
819
602
|
exactKeys(item, ["publisher_id", "plugin_id", "version", "release_metadata_sha256", "revoked_at"]);
|
|
820
603
|
}
|
|
821
604
|
}
|
|
822
|
-
function closeSigningLedgerEvidence(value) {
|
|
823
|
-
exactOptionalKeys(value, [
|
|
824
|
-
"schema_version",
|
|
825
|
-
"source_id",
|
|
826
|
-
"subject_identity_sha256",
|
|
827
|
-
"signing_preimage_sha256",
|
|
828
|
-
"signature_envelope_sha256",
|
|
829
|
-
"receipt_ref",
|
|
830
|
-
"receipt_sha256",
|
|
831
|
-
"checkpoint_ref",
|
|
832
|
-
"checkpoint_sha256",
|
|
833
|
-
"inclusion_proof_ref",
|
|
834
|
-
"inclusion_proof_sha256",
|
|
835
|
-
"latest_proof_ref",
|
|
836
|
-
"latest_proof_sha256",
|
|
837
|
-
], ["channel", "consistency_proof_ref", "consistency_proof_sha256"]);
|
|
838
|
-
}
|
|
839
|
-
function closeSigningSubject(value) {
|
|
840
|
-
if (value.usage === "root_delegation") {
|
|
841
|
-
exactKeys(value, ["schema_version", "usage", "source_id", "root_epoch"]);
|
|
842
|
-
}
|
|
843
|
-
else if (value.usage === "package" || value.usage === "release_metadata") {
|
|
844
|
-
exactKeys(value, ["schema_version", "usage", "source_id", "channel", "publisher_id", "plugin_id", "version", "artifact_or_metadata_identity_sha256"]);
|
|
845
|
-
}
|
|
846
|
-
else {
|
|
847
|
-
exactKeys(value, ["schema_version", "usage", "source_id", "channel", "epoch"]);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
function closeSignatureEnvelope(value) {
|
|
851
|
-
exactKeys(value, ["schema_version", "subject_identity_sha256", "signing_preimage_sha256", "algorithm", "key_id", "signature"]);
|
|
852
|
-
}
|
|
853
|
-
function closeSigningLedgerEntry(value) {
|
|
854
|
-
exactOptionalKeys(value, [
|
|
855
|
-
"schema_version", "state", "subject", "subject_identity_sha256", "signing_preimage_sha256",
|
|
856
|
-
"algorithm", "key_id", "revision", "reserved_at",
|
|
857
|
-
], ["signature_envelope", "signature_envelope_sha256", "finalized_at", "failure_code", "failed_at"]);
|
|
858
|
-
assertRecord(value.subject);
|
|
859
|
-
closeSigningSubject(value.subject);
|
|
860
|
-
if (value.signature_envelope !== undefined) {
|
|
861
|
-
assertRecord(value.signature_envelope);
|
|
862
|
-
closeSignatureEnvelope(value.signature_envelope);
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
function closeSigningLedgerLogLeaf(value) {
|
|
866
|
-
exactOptionalKeys(value, [
|
|
867
|
-
"schema_version", "source_id", "subject_identity_sha256", "signing_preimage_sha256", "signature_envelope_sha256", "sequence",
|
|
868
|
-
], ["channel"]);
|
|
869
|
-
}
|
|
870
|
-
function closeSigningLedgerCheckpoint(value) {
|
|
871
|
-
exactKeys(value, [
|
|
872
|
-
"schema_version", "kind", "log_id", "tree_size", "log_root_hash", "latest_map_root_hash", "checkpoint_time", "key_id", "signature",
|
|
873
|
-
]);
|
|
874
|
-
}
|
|
875
|
-
function closeSigningLedgerReceipt(value) {
|
|
876
|
-
exactOptionalKeys(value, [
|
|
877
|
-
"schema_version", "log_id", "source_id", "subject_identity_sha256", "signing_preimage_sha256",
|
|
878
|
-
"signature_envelope_sha256", "sequence", "leaf_index", "tree_size", "log_root_hash", "latest_map_root_hash",
|
|
879
|
-
"checkpoint_sha256", "checkpoint_time", "key_id", "signature",
|
|
880
|
-
], ["channel"]);
|
|
881
|
-
}
|
|
882
|
-
function closeSigningLedgerInclusionProof(value) {
|
|
883
|
-
exactKeys(value, ["schema_version", "kind", "log_id", "leaf_index", "tree_size", "nodes"]);
|
|
884
|
-
}
|
|
885
|
-
function closeSigningLedgerLatestProof(value) {
|
|
886
|
-
exactOptionalKeys(value, ["schema_version", "kind", "log_id", "subject_identity_sha256", "present", "siblings"], [
|
|
887
|
-
"sequence", "signing_preimage_sha256", "signature_envelope_sha256",
|
|
888
|
-
]);
|
|
889
|
-
}
|
|
890
|
-
function closeSigningLedgerConsistencyProof(value) {
|
|
891
|
-
exactKeys(value, ["schema_version", "kind", "log_id", "old_tree_size", "new_tree_size", "nodes"]);
|
|
892
|
-
}
|
|
893
605
|
export function buildRootDelegation(input, signature) {
|
|
894
606
|
requireSignatureBytes(signature);
|
|
895
607
|
const document = {
|
|
@@ -1087,61 +799,6 @@ export function decodeRevocation(raw) {
|
|
|
1087
799
|
export function decodeRevocationPointer(raw) {
|
|
1088
800
|
return decodeCanonicalDocument(raw, closePointer, (value) => validatePointer(value, revocationPointerSchemaVersion, true));
|
|
1089
801
|
}
|
|
1090
|
-
export function decodeSigningLedgerEvidence(raw) {
|
|
1091
|
-
const bytes = typeof raw === "string" ? textEncoder.encode(raw) : raw;
|
|
1092
|
-
if (!(bytes instanceof Uint8Array) || bytes.length > 64 * 1024)
|
|
1093
|
-
invalidDocument();
|
|
1094
|
-
return decodeCanonicalDocument(bytes, closeSigningLedgerEvidence, validateSigningLedgerEvidence);
|
|
1095
|
-
}
|
|
1096
|
-
export function canonicalSigningSubject(value) {
|
|
1097
|
-
validateSigningSubject(value);
|
|
1098
|
-
return canonicalJSON(value);
|
|
1099
|
-
}
|
|
1100
|
-
export function decodeSigningSubject(raw) {
|
|
1101
|
-
return decodeCanonicalDocument(raw, closeSigningSubject, validateSigningSubject);
|
|
1102
|
-
}
|
|
1103
|
-
export function canonicalSignatureEnvelope(value) {
|
|
1104
|
-
validateSignatureEnvelope(value);
|
|
1105
|
-
return canonicalJSON(value);
|
|
1106
|
-
}
|
|
1107
|
-
export function decodeSignatureEnvelope(raw) {
|
|
1108
|
-
return decodeCanonicalDocument(raw, closeSignatureEnvelope, validateSignatureEnvelope);
|
|
1109
|
-
}
|
|
1110
|
-
export function canonicalSigningLedgerEntry(value) {
|
|
1111
|
-
validateSigningLedgerEntry(value);
|
|
1112
|
-
return canonicalJSON(value);
|
|
1113
|
-
}
|
|
1114
|
-
export function decodeSigningLedgerEntry(raw) {
|
|
1115
|
-
return decodeCanonicalDocument(raw, closeSigningLedgerEntry, validateSigningLedgerEntry);
|
|
1116
|
-
}
|
|
1117
|
-
export async function verifySigningLedgerEntryBindings(value) {
|
|
1118
|
-
validateSigningLedgerEntry(value);
|
|
1119
|
-
if (await sha256Hex(canonicalSigningSubject(value.subject)) !== value.subject_identity_sha256)
|
|
1120
|
-
invalidDocument();
|
|
1121
|
-
if (value.state === "finalized") {
|
|
1122
|
-
if (value.signature_envelope === undefined || value.signature_envelope_sha256 === undefined ||
|
|
1123
|
-
await sha256Hex(canonicalSignatureEnvelope(value.signature_envelope)) !== value.signature_envelope_sha256)
|
|
1124
|
-
invalidDocument();
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
export function decodeSigningLedgerLogLeaf(raw) {
|
|
1128
|
-
return decodeCanonicalDocument(raw, closeSigningLedgerLogLeaf, validateSigningLedgerLogLeaf);
|
|
1129
|
-
}
|
|
1130
|
-
export function decodeSigningLedgerCheckpoint(raw) {
|
|
1131
|
-
return decodeCanonicalDocument(raw, closeSigningLedgerCheckpoint, validateSigningLedgerCheckpoint);
|
|
1132
|
-
}
|
|
1133
|
-
export function decodeSigningLedgerReceipt(raw) {
|
|
1134
|
-
return decodeCanonicalDocument(raw, closeSigningLedgerReceipt, validateSigningLedgerReceipt);
|
|
1135
|
-
}
|
|
1136
|
-
export function decodeSigningLedgerInclusionProof(raw) {
|
|
1137
|
-
return decodeCanonicalDocument(raw, closeSigningLedgerInclusionProof, validateSigningLedgerInclusionProof);
|
|
1138
|
-
}
|
|
1139
|
-
export function decodeSigningLedgerLatestProof(raw) {
|
|
1140
|
-
return decodeCanonicalDocument(raw, closeSigningLedgerLatestProof, validateSigningLedgerLatestProof);
|
|
1141
|
-
}
|
|
1142
|
-
export function decodeSigningLedgerConsistencyProof(raw) {
|
|
1143
|
-
return decodeCanonicalDocument(raw, closeSigningLedgerConsistencyProof, validateSigningLedgerConsistencyProof);
|
|
1144
|
-
}
|
|
1145
802
|
export function createEd25519Verifier(publicKeys, subtle) {
|
|
1146
803
|
const selectedSubtle = subtle ?? globalThis.crypto?.subtle;
|
|
1147
804
|
return async (request) => {
|
|
@@ -1190,13 +847,6 @@ async function verifyRaw(usage, keyID, preimage, signature, verifier) {
|
|
|
1190
847
|
function toArrayBuffer(value) {
|
|
1191
848
|
return Uint8Array.from(value).buffer;
|
|
1192
849
|
}
|
|
1193
|
-
async function sha256Hex(value) {
|
|
1194
|
-
const subtle = globalThis.crypto?.subtle;
|
|
1195
|
-
if (subtle === undefined)
|
|
1196
|
-
invalidDocument();
|
|
1197
|
-
const digest = new Uint8Array(await subtle.digest("SHA-256", toArrayBuffer(value)));
|
|
1198
|
-
return Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
1199
|
-
}
|
|
1200
850
|
function unsignedDocument(value) {
|
|
1201
851
|
const input = cloneJSON(value);
|
|
1202
852
|
delete input.schema_version;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@floegence/redevplugin-contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Embedded ReDevPlugin machine contracts and canonical release-signing APIs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -27,6 +27,6 @@
|
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsc -p tsconfig.json",
|
|
29
29
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
30
|
-
"test": "tsc -p tsconfig.test.json && node --test dist-test/test/*.js"
|
|
30
|
+
"test": "node ../../scripts/clean_typescript_test_output.mjs dist-test && tsc -p tsconfig.test.json && node --test dist-test/test/*.js"
|
|
31
31
|
}
|
|
32
32
|
}
|