Skip to content

Commit

Permalink
crypto: introduce X509Certificate API
Browse files Browse the repository at this point in the history
Introduces the `crypto.X509Certificate` object.

```js
const { X509Certificate } = require('crypto');

const x509 = new X509Certificate('{pem encoded cert}');
console.log(x509.subject);
```

Fixes: nodejs#29181
Signed-off-by: James M Snell <[email protected]>

PR-URL: nodejs#36804
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
  • Loading branch information
jasnell committed Jan 9, 2021
1 parent 324a6c2 commit f5287a4
Show file tree
Hide file tree
Showing 16 changed files with 1,695 additions and 146 deletions.
254 changes: 254 additions & 0 deletions doc/api/crypto.md
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,259 @@ thrown.
Because public keys can be derived from private keys, a private key may
be passed instead of a public key.

## Class: `X509Certificate`
<!-- YAML
added: REPLACEME
-->

Encapsulates an X509 certificate and provides read-only access to
it's information.

```js
const { X509Certificate } = require('crypto');

const x509 = new X509Certificate('{... pem encoded cert ...}');

console.log(x509.subject);
```

### `new X509Certificate(buffer)`
<!-- YAML
added: REPLACEME
-->

* `buffer` {string|TypedArray|Buffer|DataView} A PEM or DER encoded
X509 Certificate.

### `x509.ca`
<!-- YAML
added: REPLACEME
-->

* Type: {boolean} Will be `true` if this is a Certificate Authority (ca)
certificate.

### `x509.checkEmail(email[, options])`
<!-- YAML
added: REPLACEME
-->

* `email` {string}
* `options` {Object}
* `subject` {string} `'always'` or `'never'`. **Defaults**: `'always'`.
* `wildcards` {boolean} **Defaults**: `true`.
* `partialWildcards` {boolean} **Defaults**: `true`.
* `multiLabelWildcards` {boolean} **Defaults**: `false`.
* `singleLabelSubdomains` {boolean} **Defaults**: `false`.
* Returns: {string|undefined} Returns `email` if the certificate matches,
`undefined` if it does not.

Checks whether the certificate matches the given email address.

### `x509.checkHost(name[, options])`
<!-- YAML
added: REPLACEME
-->

* `name` {string}
* `options` {Object}
* `subject` {string} `'always'` or `'never'`. **Defaults**: `'always'`.
* `wildcards` {boolean} **Defaults**: `true`.
* `partialWildcards` {boolean} **Defaults**: `true`.
* `multiLabelWildcards` {boolean} **Defaults**: `false`.
* `singleLabelSubdomains` {boolean} **Defaults**: `false`.
* Returns: {string|undefined} Returns `name` if the certificate matches,
`undefined` if it does not.

Checks whether the certificate matches the given host name.

### `x509.checkIP(ip[, options])`
<!-- YAML
added: REPLACEME
-->

* `ip` {string}
* `options` {Object}
* `subject` {string} `'always'` or `'never'`. **Defaults**: `'always'`.
* `wildcards` {boolean} **Defaults**: `true`.
* `partialWildcards` {boolean} **Defaults**: `true`.
* `multiLabelWildcards` {boolean} **Defaults**: `false`.
* `singleLabelSubdomains` {boolean} **Defaults**: `false`.
* Returns: {string|undefined} Returns `ip` if the certificate matches,
`undefined` if it does not.

Checks whether the certificate matches the given IP address (IPv4 or IPv6).

### `x509.checkIssued(otherCert)`
<!-- YAML
added: REPLACEME
-->

* `otherCert` {X509Certificate}
* Returns: {boolean}

Checks whether this certificate was issued by the given `otherCert`.

### `x509.checkPrivateKey(privateKey)`
<!-- YAML
added: REPLACEME
-->

* `privateKey` {KeyObject} A private key.
* Returns: {boolean}

Checks whether the public key for this certificate is consistent with
the given private key.

### `x509.fingerprint`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The SHA-1 fingerprint of this certificate.

### `x509.fingerprint256`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The SHA-256 fingerprint of this certificate.

### `x509.infoAccess`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The information access content of this certificate.

### `x509.issuer`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The issuer identification included in this certificate.

### `x509.keyUsage`
<!-- YAML
added: REPLACEME
-->

* Type: {string[]}

An array detailing the key usages for this certificate.

### `x509.publicKey`
<!-- YAML
added: REPLACEME
-->

* Type: {KeyObject}

The public key {KeyObject} for this certificate.

### `x509.raw`
<!-- YAML
added: REPLACEME
-->

* Type: {Buffer}

A `Buffer` containing the DER encoding of this certificate.

### `x509.serialNumber`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The serial number of this certificate.

### `x509.subject`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The complete subject of this certificate.

### `x509.subjectAltName`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The subject alternative name specified for this certificate.

### `x509.toJSON()`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

There is no standard JSON encoding for X509 certificates. The
`toJSON()` method returns a string containing the PEM encoded
certificate.

### `x509.toLegacyObject()`
<!-- YAML
added: REPLACEME
-->

* Type: {Object}

Returns information about this certificate using the legacy
[certificate object][] encoding.

### `x509.toString()`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

Returns the PEM-encoded certificate.

### `x509.validFrom`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The date/time from which this certificate is considered valid.

### `x509.validTo`
<!-- YAML
added: REPLACEME
-->

* Type: {string}

The date/time until which this certificate is considered valid.

### `x509.verify(publicKey)`
<!-- YAML
added: REPLACEME
-->

* `publicKey` {KeyObject} A public key.
* Returns: {boolean}

Verifies that this certificate was signed by the given public key.
Does not perform any other validation checks on the certificate.

## `crypto` module methods and properties

### `crypto.constants`
Expand Down Expand Up @@ -3997,6 +4250,7 @@ See the [list of SSL OP Flags][] for details.
[`util.promisify()`]: util.md#util_util_promisify_original
[`verify.update()`]: #crypto_verify_update_data_inputencoding
[`verify.verify()`]: #crypto_verify_verify_object_signature_signatureencoding
[certificate object]: tls.md#tls_certificate_object
[encoding]: buffer.md#buffer_buffers_and_character_encodings
[initialization vector]: https://en.wikipedia.org/wiki/Initialization_vector
[list of SSL OP Flags]: https://wiki.openssl.org/index.php/List_of_SSL_OP_Flags#Table_of_Options
Expand Down
8 changes: 5 additions & 3 deletions doc/api/worker_threads.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,9 @@ are part of the channel.
<!-- YAML
added: v10.5.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/36804
description: Added `X509Certificate` tot he list of cloneable types.
- version:
- v14.5.0
- v12.19.0
Expand Down Expand Up @@ -501,8 +504,8 @@ In particular, the significant differences to `JSON` are:
* `value` may contain typed arrays, both using `ArrayBuffer`s
and `SharedArrayBuffer`s.
* `value` may contain [`WebAssembly.Module`][] instances.
* `value` may not contain native (C++-backed) objects other than `MessagePort`s,
[`FileHandle`][]s, and [`KeyObject`][]s.
* `value` may not contain native (C++-backed) objects other than {MessagePort}s,
{FileHandle}s, {KeyObject}s, and {X509Certificate}s.

```js
const { MessageChannel } = require('worker_threads');
Expand Down Expand Up @@ -1129,7 +1132,6 @@ active handle in the event system. If the worker is already `unref()`ed calling
[`ERR_WORKER_NOT_RUNNING`]: errors.md#ERR_WORKER_NOT_RUNNING
[`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
[`FileHandle`]: fs.md#fs_class_filehandle
[`KeyObject`]: crypto.md#crypto_class_keyobject
[`MessagePort`]: #worker_threads_class_messageport
[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
Expand Down
6 changes: 5 additions & 1 deletion lib/crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ const {
Hash,
Hmac
} = require('internal/crypto/hash');
const {
X509Certificate
} = require('internal/crypto/x509');
const {
getCiphers,
getCurves,
Expand Down Expand Up @@ -225,7 +228,8 @@ module.exports = {
Hmac,
KeyObject,
Sign,
Verify
Verify,
X509Certificate,
};

function setFipsDisabled() {
Expand Down
Loading

0 comments on commit f5287a4

Please sign in to comment.