|
| 1 | +# @sourceregistry/node-openssl |
| 2 | + |
| 3 | +[](https://opensource.org/licenses/Apache-2.0) |
| 4 | +[](https://github.com/SourceRegistry/node-openssl/actions/workflows/publish-npm.yml) |
| 5 | + |
| 6 | +A lightweight, promise-based TypeScript wrapper for executing **OpenSSL** CLI commands directly from Node.js, with rich |
| 7 | +buffer enhancements and a fluent, proxy-powered API. |
| 8 | + |
| 9 | +This library abstracts the `openssl` command-line tool into a clean, asynchronous interface, enabling seamless |
| 10 | +integration of common cryptographic operations such as key generation, certificate signing, hashing, and PEM parsing. |
| 11 | + |
| 12 | +## Installation |
| 13 | + |
| 14 | +Install the package using npm: |
| 15 | + |
| 16 | +```bash |
| 17 | +npm install @sourceregistry/node-openssl |
| 18 | +``` |
| 19 | + |
| 20 | +> **Note**: Ensure `openssl` is installed and available in your system's PATH. |
| 21 | +
|
| 22 | +## Usage |
| 23 | + |
| 24 | +### Getting Started |
| 25 | + |
| 26 | +The primary interface is the `openssl` tagged template function, which allows you to run any OpenSSL command using |
| 27 | +natural syntax. |
| 28 | + |
| 29 | +```typescript |
| 30 | +import {openssl} from '@sourceregistry/node-openssl'; |
| 31 | + |
| 32 | +async function main() { |
| 33 | + // Generate a 2048-bit RSA private key |
| 34 | + const key = await openssl`genpkey -algorithm RSA -outform PEM -pkeyopt rsa_keygen_bits:2048`.one(); |
| 35 | + console.log('Private Key:\n', key.data); |
| 36 | + console.log('SHA-256:', key.sha256); |
| 37 | + |
| 38 | + // Generate a self-signed certificate |
| 39 | + const cert = await openssl`req -x509 -new -key <(echo "${key.data}") -subj "/CN=localhost" -days 365 -outform PEM`.one(); |
| 40 | + console.log('Certificate:\n', cert.data); |
| 41 | + console.log('Is Certificate Chain?', cert.isChain); |
| 42 | +} |
| 43 | + |
| 44 | +main(); |
| 45 | +``` |
| 46 | + |
| 47 | +### Working with Output Buffers |
| 48 | + |
| 49 | +All command outputs are enhanced `Buffer` objects with metadata and utilities: |
| 50 | + |
| 51 | +```typescript |
| 52 | +const output = await openssl`x509 -in cert.pem -noout -text`; |
| 53 | + |
| 54 | +console.log(output.type); // e.g., "CERTIFICATE" |
| 55 | +console.log(output.mimeType); // e.g., "application/x-pkcs7-crl" |
| 56 | +console.log(output.sha1); // Base64URL-encoded SHA-1 |
| 57 | +console.log(output.md5); // Base64URL-encoded MD5 |
| 58 | +console.log(output.data); // PEM body (without headers) |
| 59 | + |
| 60 | +// Convert to Node.js crypto KeyObject |
| 61 | +const publicKey = output.toObject(); // createPublicKey(output) |
| 62 | +``` |
| 63 | + |
| 64 | +### Accessing OpenSSL Version |
| 65 | + |
| 66 | +```typescript |
| 67 | +console.log('OpenSSL Version:', openssl.version); |
| 68 | +// { major: 3, minor: 0, patch: 2, release_date: '...'} |
| 69 | +``` |
| 70 | + |
| 71 | +### File I/O and Temporary Workdir |
| 72 | + |
| 73 | +You can pass `Buffer` objects directly — they’re automatically written to temp files: |
| 74 | + |
| 75 | +```typescript |
| 76 | +const csrBuffer = Buffer.from('...'); |
| 77 | +const signedCert = await openssl`x509 -req -CA ca.crt -CAkey ca.key -in <(echo "${csrBuffer}") -outform PEM`; |
| 78 | +``` |
| 79 | + |
| 80 | +Files produced by OpenSSL (e.g., `.crt`, `.pem`) are automatically read and included in the output array. |
| 81 | + |
| 82 | +## API Overview |
| 83 | + |
| 84 | +### <code>openssl\`...`</code>(Tagged Template) |
| 85 | + |
| 86 | +Execute any OpenSSL command. Returns a `Promise<OpenSSLBuffer[]>`. |
| 87 | + |
| 88 | +```ts |
| 89 | +const outputs = await openssl`dgst -sha256 file.txt`; |
| 90 | +``` |
| 91 | + |
| 92 | +### `.one()` |
| 93 | + |
| 94 | +Convenience method to get the first output buffer: |
| 95 | + |
| 96 | +```ts |
| 97 | +const cert = await openssl`req -newkey ...`.one(); |
| 98 | +``` |
| 99 | + |
| 100 | +### `OpenSSLBuffer` |
| 101 | + |
| 102 | +Enhanced `Buffer` with: |
| 103 | + |
| 104 | +- `.sha1`, `.sha256`, `.md5`: Hashes (base64url-encoded) |
| 105 | +- `.data`: PEM body (header/footer stripped) |
| 106 | +- `.type`: PEM type (`CERTIFICATE`, `PRIVATE KEY`, etc.) |
| 107 | +- `.isChain`: `true` if multiple certs in PEM |
| 108 | +- `.certificates`: Array of full certificate blocks (if chain) |
| 109 | +- `.mimeType`: Inferred MIME type |
| 110 | +- `.toObject()`: Convert to `crypto.KeyObject` |
| 111 | + |
| 112 | +### Static Methods |
| 113 | + |
| 114 | +- `OpenSSL.exec(args)`: Low-level execution with array args |
| 115 | +- `OpenSSL.init()`: Initialize and detect OpenSSL version (is run automatically when importing the library) |
| 116 | +- `OpenSSL.AnalysePEM(buffer)`: Parse PEM metadata |
| 117 | +- `OpenSSL.TransformBuffer(buffer)`: Enhance a Buffer |
| 118 | + |
| 119 | +## Development |
| 120 | + |
| 121 | +### Prerequisites |
| 122 | + |
| 123 | +- Node.js (v22+ older might work) |
| 124 | +- OpenSSL (installed and in PATH) |
| 125 | + |
| 126 | +### Scripts |
| 127 | + |
| 128 | +- `npm run build`: Compile TypeScript to `dist/` |
| 129 | +- `npm run test`: Run unit tests (if any) |
| 130 | +- `npm run lint`: Lint code with ESLint |
| 131 | + |
| 132 | +## Contributing |
| 133 | + |
| 134 | +Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests. |
| 135 | + |
| 136 | +We aim to support all standard OpenSSL workflows with a clean, type-safe interface. |
| 137 | + |
| 138 | +## License |
| 139 | + |
| 140 | +This project is licensed under the **Apache-2.0 License**. See the [LICENSE](LICENSE) file for details. |
0 commit comments