MCPcopy Index your code
hub / github.com/digitalbazaar/forge

github.com/digitalbazaar/forge @v1.4.0 sqlite

repository ↗ · DeepWiki ↗ · release v1.4.0 ↗
427 symbols 852 edges 114 files 79 documented · 19%
README

Forge

NPM

Main Checks

A native implementation of [TLS][] (and various other cryptographic tools) in [JavaScript][].

Introduction

The Forge software is a fully native implementation of the [TLS][] protocol in JavaScript, a set of cryptography utilities, and a set of tools for developing Web Apps that utilize many network resources.

Performance

Forge is fast. Benchmarks against other popular JavaScript cryptography libraries can be found here:

  • http://dominictarr.github.io/crypto-bench/
  • http://cryptojs.altervista.org/test/simulate-threading-speed_test.html

Documentation

API

Transports

Ciphers

PKI

Message Digests

Utilities

Other


Installation

Note: Please see the Security Considerations section before using packaging systems and pre-built files.

Forge uses a [CommonJS][] module structure with a build process for browser bundles. The older [0.6.x][] branch with standalone files is available but will not be regularly updated.

Node.js

If you want to use forge with [Node.js][], it is available through npm:

https://www.npmjs.com/package/node-forge

Installation:

npm install node-forge

You can then use forge as a regular module:

var forge = require('node-forge');

The npm package includes pre-built forge.min.js, forge.all.min.js, and prime.worker.min.js using the [UMD][] format.

jsDelivr CDN

To use it via jsDelivr include this in your html:

<script src="https://cdn.jsdelivr.net/npm/node-forge@1.0.0/dist/forge.min.js"></script>

unpkg CDN

To use it via unpkg include this in your html:

<script src="https://unpkg.com/node-forge@1.0.0/dist/forge.min.js"></script>

Development Requirements

The core JavaScript has the following requirements to build and test:

  • Building a browser bundle:
  • Node.js
  • npm
  • Testing
  • Node.js
  • npm
  • Chrome, Firefox, Safari (optional)

Some special networking features can optionally use a Flash component. See the Flash README for details.

Building for a web browser

To create single file bundles for use with browsers run the following:

npm install
npm run build

This will create single non-minimized and minimized files that can be included in the browser:

dist/forge.js
dist/forge.min.js

A bundle that adds some utilities and networking support is also available:

dist/forge.all.js
dist/forge.all.min.js

Include the file via:

<script src="https://github.com/digitalbazaar/forge/raw/v1.4.0/YOUR_SCRIPT_PATH/forge.js"></script>

or

<script src="https://github.com/digitalbazaar/forge/raw/v1.4.0/YOUR_SCRIPT_PATH/forge.min.js"></script>

The above bundles will synchronously create a global 'forge' object.

Note: These bundles will not include any WebWorker scripts (eg: dist/prime.worker.js), so these will need to be accessible from the browser if any WebWorkers are used.

Building a custom browser bundle

The build process uses [webpack][] and the config file can be modified to generate a file or files that only contain the parts of forge you need.

[Browserify][] override support is also present in package.json.

Testing

Prepare to run tests

npm install

Running automated tests with Node.js

Forge natively runs in a [Node.js][] environment:

npm test

Running automated tests with Headless Chrome

Automated testing is done via [Karma][]. By default it will run the tests with Headless Chrome.

npm run test-karma

Is 'mocha' reporter output too verbose? Other reporters are available. Try 'dots', 'progress', or 'tap'.

npm run test-karma -- --reporters progress

By default [webpack][] is used. [Browserify][] can also be used.

BUNDLER=browserify npm run test-karma

Running automated tests with one or more browsers

You can also specify one or more browsers to use.

npm run test-karma -- --browsers Chrome,Firefox,Safari,ChromeHeadless

The reporter option and BUNDLER environment variable can also be used.

Running manual tests in a browser

Testing in a browser uses [webpack][] to combine forge and all tests and then loading the result in a browser. A simple web server is provided that will output the HTTP or HTTPS URLs to load. It also will start a simple Flash Policy Server. Unit tests and older legacy tests are provided. Custom ports can be used by running node tests/server.js manually.

To run the unit tests in a browser a special forge build is required:

npm run test-build

To run legacy browser based tests the main forge build is required:

npm run build

The tests are run with a custom server that prints out the URLs to use:

npm run test-server

Running other tests

There are some other random tests and benchmarks available in the tests directory.

Coverage testing

To perform coverage testing of the unit tests, run the following. The results will be put in the coverage/ directory. Note that coverage testing can slow down some tests considerably.

npm install
npm run coverage

Contributing

Any contributions (eg: PRs) that are accepted will be brought under the same license used by the rest of the Forge project. This license allows Forge to be used under the terms of either the BSD License or the GNU General Public License (GPL) Version 2.

See: LICENSE

If a contribution contains 3rd party source code with its own license, it may retain it, so long as that license is compatible with the Forge license.

API

Options

If at any time you wish to disable the use of native code, where available, for particular forge features like its secure random number generator, you may set the forge.options.usePureJavaScript flag to true. It is not recommended that you set this flag as native code is typically more performant and may have stronger security properties. It may be useful to set this flag to test certain features that you plan to run in environments that are different from your testing environment.

To disable native code when including forge in the browser:

// run this *after* including the forge script
forge.options.usePureJavaScript = true;

To disable native code when using Node.js:

var forge = require('node-forge');
forge.options.usePureJavaScript = true;

Transports

TLS

Provides a native javascript client and server-side [TLS][] implementation.

Examples

// create TLS client
var client = forge.tls.createConnection({
  server: false,
  caStore: /* Array of PEM-formatted certs or a CA store object */,
  sessionCache: {},
  // supported cipher suites in order of preference
  cipherSuites: [
    forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
    forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
  virtualHost: 'example.com',
  verify: function(connection, verified, depth, certs) {
    if(depth === 0) {
      var cn = certs[0].subject.getField('CN').value;
      if(cn !== 'example.com') {
        verified = {
          alert: forge.tls.Alert.Description.bad_certificate,
          message: 'Certificate common name does not match hostname.'
        };
      }
    }
    return verified;
  },
  connected: function(connection) {
    console.log('connected');
    // send message to server
    connection.prepare(forge.util.encodeUtf8('Hi server!'));
    /* NOTE: experimental, start heartbeat retransmission timer
    myHeartbeatTimer = setInterval(function() {
      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
    }, 5*60*1000);*/
  },
  /* provide a client-side cert if you want
  getCertificate: function(connection, hint) {
    return myClientCertificate;
  },
  /* the private key for the client-side cert if provided */
  getPrivateKey: function(connection, cert) {
    return myClientPrivateKey;
  },
  tlsDataReady: function(connection) {
    // TLS data (encrypted) is ready to be sent to the server
    sendToServerSomehow(connection.tlsData.getBytes());
    // if you were communicating with the server below, you'd do:
    // server.process(connection.tlsData.getBytes());
  },
  dataReady: function(connection) {
    // clear data from the server is ready
    console.log('the server sent: ' +
      forge.util.decodeUtf8(connection.data.getBytes()));
    // close connection
    connection.close();
  },
  /* NOTE: experimental
  heartbeatReceived: function(connection, payload) {
    // restart retransmission timer, look at payload
    clearInterval(myHeartbeatTimer);
    myHeartbeatTimer = setInterval(function() {
      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
    }, 5*60*1000);
    payload.getBytes();
  },*/
  closed: function(connection) {
    console.log('disconnected');
  },
  error: function(connection, error) {
    console.log('uh oh', error);
  }
});

// start the handshake process
client.handshake();

// when encrypted TLS data is received from the server, process it
client.process(encryptedBytesFromServer);

// create TLS server
var server = forge.tls.createConnection({
  server: true,
  caStore: /* Array of PEM-formatted certs or a CA store object */,
  sessionCache: {},
  // supported cipher suites in order of preference
  cipherSuites: [
    forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
    forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
  // require a client-side certificate if you want
  verifyClient: true,
  verify: function(connection, verified, depth, certs) {
    if(depth === 0) {
      var cn = certs[0].subject.getField('CN').value;
      if(cn !== 'the-client') {
        verified = {
          alert: forge.tls.Alert.Description.bad_certificate,
          message: 'Certificate common name does not match expected client.'
        };
      }
    }
    return verified;
  },
  connected: function(connection) {
    console.log('connected');
    // send message to client
    connection.prepare(forge.util.encodeUtf8('Hi client!'));
    /* NOTE: experimental, start heartbeat retransmission timer
    myHeartbeatTimer = setInterval(function() {
      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
    }, 5*60*1000);*/
  },
  getCertificate: function(connection, hint) {
    return myServerCertificate;
  },
  getPrivateKey: function(connection, cert) {
    return myServerPrivateKey;
  },
  tlsDataReady: function(connection) {
    // TLS data (encrypted) is ready to be sent to the client
    sendToClientSomehow(connection.tlsData.getBytes());
    // if you were communicating with the client above you'd do:
    // client.process(connection.tlsData.getBytes());
  },
  dataReady: function(connection) {
    // clear data from the client is ready
    console.log('the client sent: ' +
      forge.util.decodeUtf8(connection.data.getBytes()));
    // close connection
    connection.close();
  },
  /* NOTE: experimental
  heartbeatReceived: function(connection, payload) {
    // restart retransmission timer, look at payload
    clearInterval(myHeartbeatTimer);
    myHeartbeatTimer = setInterval(function() {
      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
    }, 5*60*1000);
    payload.getBytes();
  },*/
  closed: function(connection) {
    console.log('disconnected');
  },
  error: function(connection, error) {
    console.log('uh oh', error);
  }
});

// when encrypted TLS data is received from the client, process it
server.process(encryptedBytesFromClient);

Connect to a TLS server using node's net.Socket:

```js var socket = new net.Socket();

var client = forge.tls.createConnection({ server: false, verify: function(connection, verified, depth, certs) { // skip verification for testing console.log('[tls] server certificate verified'); return true; }, connected: function(connection) { console.log('[tls] connected'); // prepare some data to send (note that the string is interpreted as // 'binary' encoded, which works for HTTP which only uses ASCII, use // forge.util.encodeUtf8(str) otherwise client.prepare('GET / HTTP/1.0\r\n\r\n'); }, tlsDataReady: function(connection) { // encrypted data is ready to be sent to the server var data = connection.tlsData.getBytes(); socket.write(data, 'binary'); // encoding should be 'binary' }, dataReady: function(connection) { // clear data from the server is ready var data = connection.data.getBytes(); console.log('[tls] data received from the server: ' + data); }, closed: function() { console.log('[tls] disconnected'); }, error: function(connection,

Core symbols most depended-on inside this repo

_add
called by 102
tests/unit/asn1.js
_IN
called by 99
lib/oids.js
addTest
called by 61
tests/legacy/common.js
gf
called by 50
lib/ed25519.js
callback
called by 44
lib/tls.js
_h2b
called by 38
tests/unit/asn1.js
nbi
called by 34
lib/jsbn.js
_I_
called by 30
lib/oids.js

Shape

Function 423
Class 2
Method 2

Languages

TypeScript99%
Python1%

Modules by API surface

lib/jsbn.js107 symbols
lib/ed25519.js30 symbols
lib/rsa.js18 symbols
lib/http.js18 symbols
lib/util.js14 symbols
lib/tls.js14 symbols
lib/pkcs7.js14 symbols
lib/x509.js13 symbols
tests/websockets/server-webid.js11 symbols
tests/unit/rsa.js11 symbols
tests/unit/pkcs1.js9 symbols
tests/benchmarks/so-44303784.js9 symbols

Dependencies from manifests, versioned

browserify16.5.2 · 1×
commander2.20.0 · 1×
cross-env5.2.1 · 1×
eslint7.27.0 · 1×
eslint-config-digitalbazaar2.8.0 · 1×
express4.16.2 · 1×
flex-sdk
karma4.4.1 · 1×
karma-browserify7.0.0 · 1×
karma-chrome-launcher3.1.0 · 1×
karma-edge-launcher0.4.2 · 1×
karma-firefox-launcher1.3.0 · 1×

For agents

$ claude mcp add forge \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact