Thank you for your interest in contributing to PKI-Lite! This guide will help you understand the project structure and maintain consistency with the existing codebase.
PKI-Lite is designed to be:
packages/
├── pki-lite/ # Core PKI functionality
│ ├── src/
│ │ ├── adobe/ # Adobe-specific signature formats
│ │ ├── algorithms/ # Cryptographic algorithm implementations
│ │ ├── asn1/ # ASN.1 type implementations
│ │ ├── core/ # Core utilities and base classes
│ │ ├── keys/ # Key management (public/private keys)
│ │ ├── ocsp/ # Online Certificate Status Protocol
│ │ ├── pkcs5/ # PKCS#5 standard implementation
│ │ ├── pkcs7/ # PKCS#7 standard implementation
│ │ ├── pkcs12/ # PKCS#12 standard implementation
│ │ ├── revocation/ # Certificate revocation (CRL)
│ │ ├── timestamp/ # RFC 3161 time stamping
│ │ └── x509/ # X.509 certificate operations
│ └── test/ # Integration and acceptance tests
└── pki-lite-crypto-extended/ # Extended crypto algorithms
All classes representing ASN.1 structures must include the ASN.1 definition in their JSDoc:
/**
* Represents an X.509 certificate.
*
* @asn
* ```asn
* Certificate ::= SEQUENCE {
* tbsCertificate TBSCertificate,
* signatureAlgorithm AlgorithmIdentifier,
* signatureValue BIT STRING
* }
* ```
*/
export class Certificate extends PkiBase<Certificate> {
// Implementation...
}
Every source file must have a corresponding test file in the same directory:
src/x509/Certificate.ts
src/x509/Certificate.test.ts
Tests should cover:
All new features and public APIs must include practical examples in the examples/
folder:
examples/
├── certificates/
│ ├── create-self-signed.ts
│ ├── validate-certificate.ts
│ └── certificate-chain.ts
├── signatures/
│ ├── digital-signature.ts
│ └── timestamp-signature.ts
└── README.md
Examples should:
Follow this structure for all PKI classes:
export class YourClass extends PkiBase<YourClass> {
// 1. Public properties (ASN.1 fields)
public field1: Type1
public field2: Type2
// 2. Constructor
constructor(options: { field1: Type1; field2: Type2 }) {
super()
this.field1 = options.field1
this.field2 = options.field2
}
// 3. Static factory methods
static fromAsn1(asn1: Asn1Any): YourClass {
/* ... */
}
static fromDer(der: Uint8Array): YourClass {
/* ... */
}
static fromPem(pem: string): YourClass {
/* ... */
}
// 4. Instance methods
toAsn1(): Asn1Any {
/* ... */
}
toDer(): Uint8Array {
/* ... */
}
toPem(): string {
/* ... */
}
toString(): string {
/* ... */
}
}
First, add the algorithm OID to src/core/OIDs.ts
:
export const OIDs = {
// ... existing OIDs
newAlgorithm: '1.2.3.4.5.6.7',
} as const
If the algorithm requires parameters, create a new class in src/algorithms/
:
/**
* Parameters for NewAlgorithm.
*
* @asn
* ```asn
* NewAlgorithmParams ::= SEQUENCE {
* parameter1 INTEGER,
* parameter2 OCTET STRING OPTIONAL
* }
* ```
*/
export class NewAlgorithmParams extends PkiBase<NewAlgorithmParams> {
parameter1: number
parameter2?: Uint8Array
// ... follow standard class structure
}
Add support in src/algorithms/AlgorithmIdentifier.ts
:
// In the parseParameters method:
case OIDs.newAlgorithm:
return NewAlgorithmParams.fromAsn1(parametersAsn1)
// In the createParameters method:
case OIDs.newAlgorithm:
return (parameters as NewAlgorithmParams).toAsn1()
Add crypto provider support in the appropriate crypto provider files:
// For core algorithms, update WebCryptoProvider
// For extended algorithms, update WebCryptoExtendedProvider
async newAlgorithmOperation(
data: Uint8Array,
key: CryptoKey,
params: NewAlgorithmParams
): Promise<Uint8Array> {
// Implementation using Web Crypto API or fallback library
}
Create comprehensive tests covering:
describe('NewAlgorithm', () => {
test('should parse parameters correctly', () => {
// Test parameter parsing
})
test('should perform crypto operations', async () => {
// Test actual cryptographic operations
})
test('should handle edge cases', () => {
// Test error conditions
})
})
# Install dependencies
pnpm install
# Compile all packages
pnpm compile
# Run all tests
pnpm test
# Run tests for specific package
cd packages/pki-lite
pnpm test:unit
# Run tests in specific environment
pnpm test --project=node # Node.js environment
pnpm test --project=browser # Browser environment
# Watch mode during development
pnpm test:watch
# Format code with Prettier
pnpm format
# Lint code
pnpm lint
# Type check
pnpm type-check
Note: This project uses Prettier for code formatting. All code is automatically formatted on commit via pre-commit hooks.
feat: add new algorithm
, fix: resolve parsing issue
, docs: update contributing guide
)Follow the Conventional Commits specification:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Examples:
feat(x509): add certificate validation method
fix(algorithms): resolve RSA-PSS parameter parsing
docs: add usage examples for PKCS#7
test(ocsp): add integration tests for OCSP client
If you have questions about contributing, please:
Thank you for helping make PKI-Lite better!