UNPKG

@instun/sm2-multikey

Version:

A JavaScript library for generating and working with SM2Multikey key pairs and digital signatures. Compatible with both Node.js and fibjs runtimes.

662 lines (629 loc) 18.3 kB
/*! * Copyright (c) 2024 Instun, Inc. All rights reserved. */ /** * @fileoverview Proof Purpose Management for SM2 Digital Signatures * * This module implements the W3C Verifiable Credentials proof purpose model, * providing a framework for validating the intended usage of digital signatures. * It ensures that signatures are used appropriately within their intended context * and authorization scope. * * Key Features: * - Extensible proof purpose framework * - W3C standard purpose implementations * - DID-based verification * - Capability validation * - Chain of trust verification * * Security Considerations: * - Strict verification method validation * - Capability chain verification * - Status and revocation checking * - Purpose scope enforcement * - Authorization validation * * Performance Notes: * - Lazy DID document loading * - Efficient chain validation * - Cached verification results * - Early validation failures * * Usage Example: * ```javascript * import { createProofPurpose } from './purposes.js'; * * // Create a proof purpose for authentication * const purpose = createProofPurpose('authentication'); * * // Validate a proof * try { * const isValid = purpose.validate(proof, document, { * verificationMethod: 'did:example:123#key-1' * }); * console.log('Proof is valid:', isValid); * } catch (error) { * console.error('Validation failed:', error.message); * } * ``` * * Standards Compliance: * - W3C Verifiable Credentials Data Model * - W3C Decentralized Identifiers (DIDs) * - W3C Linked Data Proofs * - IETF OAuth 2.0 Capability Tokens * - GM/T 0009-2012: SM2 Digital Signature Algorithm * * @module purposes * @see {@link https://w3c.github.io/vc-data-model/#proof-purposes} * @see {@link https://w3c.github.io/did-core/} * @see {@link https://w3c-ccg.github.io/ld-proofs/} */ import { ArgumentError, OperationError, VerificationError } from '../core/errors.js'; /** * Base class for all proof purposes * * This abstract class provides the foundation for implementing different proof * purposes as defined in the W3C Verifiable Credentials specification. It * establishes a common interface and shared functionality for all purpose types. * * Processing Steps: * 1. Parameter validation * 2. Purpose term verification * 3. Proof structure validation * 4. Verification method validation * * Security Considerations: * - Input validation for all parameters * - Purpose term verification * - Error isolation and handling * - Type safety enforcement * * Performance Notes: * - Early parameter validation * - Minimal object creation * - Efficient error handling * - Reusable validation logic * * @abstract * @class */ export class ProofPurpose { /** * Create a new proof purpose * * Initializes a proof purpose with its identifying term. The term is used * to match against proof declarations and determine validation rules. * * @param {string} term - The proof purpose term (e.g., 'assertionMethod') * @throws {ArgumentError} If term is not a non-empty string * * @example * ```javascript * class CustomPurpose extends ProofPurpose { * constructor() { * super('customPurpose'); * } * } * ``` */ constructor(term) { if (!term || typeof term !== 'string') { throw new ArgumentError( 'term must be a string', 'E_INVALID_TERM' ); } this.term = term; } /** * Validate a proof against its stated purpose * * This method performs basic validation common to all proof purposes. * Subclasses should extend this method to add purpose-specific validation * logic while maintaining the base validation guarantees. * * Processing Steps: * 1. Validate input parameters * 2. Check proof structure * 3. Verify purpose declaration * 4. Match purpose term * * Security Considerations: * - Type checking for all inputs * - Null/undefined handling * - Purpose term validation * - Error isolation * * Performance Notes: * - Early validation failures * - Minimal object access * - Reusable validation * - Efficient error creation * * @param {object} proof - The proof to validate * @param {object} document - The document being proved * @param {object} [options={}] - Additional validation options * @returns {boolean} True if validation succeeds * @throws {ArgumentError} If parameters are invalid * @throws {VerificationError} If validation fails * * @example * ```javascript * const purpose = new ProofPurpose('test'); * try { * const isValid = purpose.validate({ * type: 'SM2Signature2024', * purpose: 'test', * verificationMethod: 'did:example:123#key-1' * }, document); * console.log('Validation result:', isValid); * } catch (error) { * console.error('Validation failed:', error); * } * ``` */ validate(proof, document, options = {}) { if (!proof || typeof proof !== 'object') { throw new ArgumentError( 'proof must be an object', 'E_INVALID_PROOF' ); } if (!document || typeof document !== 'object') { throw new ArgumentError( 'document must be an object', 'E_INVALID_DOCUMENT' ); } if (typeof options !== 'object') { throw new ArgumentError( 'options must be an object', 'E_INVALID_OPTIONS' ); } // Verify proof.purpose or proof.proofPurpose const purpose = proof.purpose || proof.proofPurpose; if (!purpose) { throw new VerificationError( 'proof purpose not found', 'E_PURPOSE_MISSING' ); } if (purpose !== this.term) { throw new VerificationError( `proof purpose must be "${this.term}"`, 'E_PURPOSE_MISMATCH' ); } return true; } } /** * Proof purpose for making assertions about a subject * * This purpose is used when a subject is making verifiable claims or * statements. It verifies that the signing key is authorized for making * assertions in the subject's DID document through the assertionMethod * relationship. * * Processing Steps: * 1. Base validation (ProofPurpose) * 2. Verification method presence * 3. DID document resolution * 4. assertionMethod verification * 5. Status validation * * Security Considerations: * - DID document integrity * - Key authorization scope * - Status verification * - Chain of trust validation * * Performance Notes: * - Cached DID resolution * - Early validation exit * - Minimal parsing * - Efficient lookups * * Common Use Cases: * - Issuing verifiable credentials * - Making verifiable presentations * - Creating verifiable statements * - Signing data objects * * @extends ProofPurpose * * @example * ```javascript * const purpose = new AssertionMethod(); * const isValid = purpose.validate(proof, document, { * verificationMethod: 'did:example:123#key-1', * documentLoader: customLoader * }); * ``` */ export class AssertionMethod extends ProofPurpose { constructor() { super('assertionMethod'); } /** * Validate proof purpose * * @param {object} proof - signature proof * @param {object} document - document to be validated * @param {object} options - validation options * @returns {boolean} validation result * @throws {VerificationError} if validation fails */ validate(proof, document, options) { super.validate(proof, document, options); if (!proof.verificationMethod) { throw new VerificationError( 'verificationMethod not found', 'E_VERIFICATION_METHOD_MISSING' ); } // TODO: Implement DID document parsing and verification // 1. Parse verificationMethod // 2. Verify if verificationMethod is in the DID document's assertionMethod list // 3. Verify verificationMethod status (expiration, revocation, etc.) return true; } } /** * Proof purpose for authentication * * This purpose is used when proving control over an identity through the * authentication relationship in a DID document. It ensures that the * signing key is explicitly authorized for authentication purposes. * * Processing Steps: * 1. Base validation (ProofPurpose) * 2. Verification method presence * 3. DID document resolution * 4. Authentication verification * 5. Status validation * * Security Considerations: * - Identity verification * - Key authorization scope * - Challenge verification * - Replay protection * * Performance Notes: * - Cached authentication checks * - Minimal DID resolution * - Efficient key lookup * - Quick validation path * * Common Use Cases: * - Identity verification * - Login/authentication flows * - Challenge-response protocols * - Session establishment * * @extends ProofPurpose * * @example * ```javascript * const purpose = new Authentication(); * const isValid = purpose.validate(proof, document, { * challenge: 'abc123', * domain: 'example.com' * }); * ``` */ export class Authentication extends ProofPurpose { constructor() { super('authentication'); } /** * Validate proof purpose * * @param {object} proof - signature proof * @param {object} document - document to be validated * @param {object} options - validation options * @returns {boolean} validation result * @throws {VerificationError} if validation fails */ validate(proof, document, options) { super.validate(proof, document, options); if (!proof.verificationMethod) { throw new VerificationError( 'verificationMethod not found', 'E_VERIFICATION_METHOD_MISSING' ); } // TODO: Implement DID document parsing and verification // 1. Parse verificationMethod // 2. Verify if verificationMethod is in the DID document's authentication list // 3. Verify verificationMethod status (expiration, revocation, etc.) return true; } } /** * Proof purpose for key agreement * * This purpose is used for establishing shared secrets and secure * communication channels through the keyAgreement relationship in * a DID document. It verifies key authorization for encryption * and key exchange operations. * * Processing Steps: * 1. Base validation (ProofPurpose) * 2. Verification method presence * 3. DID document resolution * 4. keyAgreement verification * 5. Key type validation * * Security Considerations: * - Key agreement protocol * - Forward secrecy * - Key freshness * - Protocol binding * * Performance Notes: * - Efficient key validation * - Minimal protocol overhead * - Cached DID lookups * - Quick failure paths * * Common Use Cases: * - Establishing encrypted channels * - Key exchange protocols * - Secure messaging setup * - End-to-end encryption * * @extends ProofPurpose * * @example * ```javascript * const purpose = new KeyAgreement(); * const isValid = purpose.validate(proof, document, { * verificationMethod: 'did:example:123#key-1', * keyType: 'SM2' * }); * ``` */ export class KeyAgreement extends ProofPurpose { constructor() { super('keyAgreement'); } /** * Validate proof purpose * * @param {object} proof - signature proof * @param {object} document - document to be validated * @param {object} options - validation options * @returns {boolean} validation result * @throws {VerificationError} if validation fails */ validate(proof, document, options) { super.validate(proof, document, options); if (!proof.verificationMethod) { throw new VerificationError( 'verificationMethod not found', 'E_VERIFICATION_METHOD_MISSING' ); } // TODO: Implement DID document parsing and verification // 1. Parse verificationMethod // 2. Verify if verificationMethod is in the DID document's keyAgreement list // 3. Verify verificationMethod status (expiration, revocation, etc.) return true; } } /** * Proof purpose for capability invocation * * This purpose is used when exercising authorized capabilities through * the capabilityInvocation relationship. It verifies the authorization * to invoke a capability and validates the entire capability chain. * * Processing Steps: * 1. Base validation (ProofPurpose) * 2. Verification method presence * 3. DID document resolution * 4. Capability chain validation * 5. Invocation verification * * Security Considerations: * - Capability chain integrity * - Authorization scope * - Delegation depth * - Revocation status * * Performance Notes: * - Cached chain validation * - Efficient graph traversal * - Quick authorization check * - Minimal recursion * * Common Use Cases: * - Exercising delegated permissions * - Accessing controlled resources * - Executing authorized actions * - API access control * * @extends ProofPurpose * * @example * ```javascript * const purpose = new CapabilityInvocation(); * const isValid = purpose.validate(proof, document, { * capability: 'did:example:123/capabilities/1', * action: 'read' * }); * ``` */ export class CapabilityInvocation extends ProofPurpose { constructor() { super('capabilityInvocation'); } /** * Validate proof purpose * * @param {object} proof - signature proof * @param {object} document - document to be validated * @param {object} options - validation options * @returns {boolean} validation result * @throws {VerificationError} if validation fails */ validate(proof, document, options) { super.validate(proof, document, options); if (!proof.verificationMethod) { throw new VerificationError( 'verificationMethod not found', 'E_VERIFICATION_METHOD_MISSING' ); } // TODO: Implement DID document parsing and verification // 1. Parse verificationMethod // 2. Verify if verificationMethod is in the DID document's capabilityInvocation list // 3. Verify verificationMethod status (expiration, revocation, etc.) // 4. Verify capability chain return true; } } /** * Proof purpose for capability delegation * * This purpose is used when delegating capabilities to others through * the capabilityDelegation relationship. It verifies the authority * to delegate capabilities and validates the delegation chain. * * Processing Steps: * 1. Base validation (ProofPurpose) * 2. Verification method presence * 3. DID document resolution * 4. Delegation chain validation * 5. Authority verification * * Security Considerations: * - Delegation authority * - Chain of trust * - Scope limitations * - Revocation handling * * Performance Notes: * - Efficient chain traversal * - Cached authority checks * - Quick validation path * - Minimal recursion * * Common Use Cases: * - Delegating permissions * - Creating capability chains * - Authorization transfer * - Access management * * @extends ProofPurpose * * @example * ```javascript * const purpose = new CapabilityDelegation(); * const isValid = purpose.validate(proof, document, { * delegator: 'did:example:123', * scope: ['read', 'write'] * }); * ``` */ export class CapabilityDelegation extends ProofPurpose { constructor() { super('capabilityDelegation'); } /** * Validate proof purpose * * @param {object} proof - signature proof * @param {object} document - document to be validated * @param {object} options - validation options * @returns {boolean} validation result * @throws {VerificationError} if validation fails */ validate(proof, document, options) { super.validate(proof, document, options); if (!proof.verificationMethod) { throw new VerificationError( 'verificationMethod not found', 'E_VERIFICATION_METHOD_MISSING' ); } // TODO: Implement DID document parsing and verification // 1. Parse verificationMethod // 2. Verify if verificationMethod is in the DID document's capabilityDelegation list // 3. Verify verificationMethod status (expiration, revocation, etc.) // 4. Verify delegation chain return true; } } /** * Factory function to create proof purpose instances * * This function instantiates the appropriate proof purpose class based * on the provided term. It provides a convenient way to create purpose * instances while ensuring proper initialization and validation. * * Processing Steps: * 1. Validate input term * 2. Match purpose type * 3. Create instance * 4. Validate creation * * Security Considerations: * - Input validation * - Type safety * - Instance validation * - Error handling * * Performance Notes: * - Single instance creation * - Minimal validation * - Quick type matching * - Efficient error paths * * Supported Terms: * - assertionMethod: For making verifiable claims * - authentication: For identity verification * - keyAgreement: For secure key exchange * - capabilityInvocation: For using capabilities * - capabilityDelegation: For delegating capabilities * * @param {string} term - The proof purpose term * @returns {ProofPurpose} An instance of the appropriate proof purpose class * @throws {OperationError} If the term is not supported * * @example * ```javascript * // Create an authentication purpose * const authPurpose = createProofPurpose('authentication'); * * // Create a capability invocation purpose * const capPurpose = createProofPurpose('capabilityInvocation'); * * // Validate a proof * const isValid = authPurpose.validate(proof, document, { * verificationMethod: 'did:example:123#key-1' * }); * ``` */ export function createProofPurpose(term) { switch (term) { case 'assertionMethod': return new AssertionMethod(); case 'authentication': return new Authentication(); case 'keyAgreement': return new KeyAgreement(); case 'capabilityInvocation': return new CapabilityInvocation(); case 'capabilityDelegation': return new CapabilityDelegation(); default: throw new OperationError( `unsupported proof purpose: ${term}`, 'E_UNSUPPORTED_PURPOSE' ); } }