react-native-quick-crypto
Version:
A fast implementation of Node's `crypto` module written in C/C++ JSI
189 lines (187 loc) • 6.18 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.X509Certificate = void 0;
var _reactNativeNitroModules = require("react-native-nitro-modules");
var _reactNativeBuffer = require("@craftzdog/react-native-buffer");
var _keys = require("./keys");
var _utils = require("./utils");
const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT = 0x1;
const X509_CHECK_FLAG_NO_WILDCARDS = 0x2;
const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS = 0x4;
const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = 0x8;
const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS = 0x10;
const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = 0x20;
function getFlags(options) {
if (!options) return 0;
let flags = 0;
if (options.subject === 'always') {
flags |= X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT;
} else if (options.subject === 'never') {
flags |= X509_CHECK_FLAG_NEVER_CHECK_SUBJECT;
}
if (options.wildcards === false) {
flags |= X509_CHECK_FLAG_NO_WILDCARDS;
}
if (options.partialWildcards === false) {
flags |= X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
}
if (options.multiLabelWildcards === true) {
flags |= X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS;
}
if (options.singleLabelSubdomains === true) {
flags |= X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS;
}
return flags;
}
class X509Certificate {
cache = new Map();
constructor(buffer) {
this.handle = _reactNativeNitroModules.NitroModules.createHybridObject('X509CertificateHandle');
// For string input, route through binaryLikeToArrayBuffer so the result
// is a tight ArrayBuffer of just the encoded bytes. `Buffer.from(str).buffer`
// can return a pool-backed ArrayBuffer with byteOffset > 0, exposing
// unrelated bytes (and giving the wrong byteLength) to native.
const ab = (0, _utils.binaryLikeToArrayBuffer)(buffer);
this.handle.init(ab);
}
cached(key, compute) {
if (this.cache.has(key)) {
return this.cache.get(key);
}
const value = compute();
this.cache.set(key, value);
return value;
}
get subject() {
return this.cached('subject', () => this.handle.subject());
}
get subjectAltName() {
return this.cached('subjectAltName', () => this.handle.subjectAltName());
}
get issuer() {
return this.cached('issuer', () => this.handle.issuer());
}
get infoAccess() {
return this.cached('infoAccess', () => this.handle.infoAccess());
}
get validFrom() {
return this.cached('validFrom', () => this.handle.validFrom());
}
get validTo() {
return this.cached('validTo', () => this.handle.validTo());
}
get validFromDate() {
return this.cached('validFromDate', () => new Date(this.handle.validFromDate()));
}
get validToDate() {
return this.cached('validToDate', () => new Date(this.handle.validToDate()));
}
get fingerprint() {
return this.cached('fingerprint', () => this.handle.fingerprint());
}
get fingerprint256() {
return this.cached('fingerprint256', () => this.handle.fingerprint256());
}
get fingerprint512() {
return this.cached('fingerprint512', () => this.handle.fingerprint512());
}
get extKeyUsage() {
return this.cached('extKeyUsage', () => this.handle.keyUsage());
}
get keyUsage() {
return this.extKeyUsage;
}
get serialNumber() {
return this.cached('serialNumber', () => this.handle.serialNumber());
}
get signatureAlgorithm() {
return this.cached('signatureAlgorithm', () => this.handle.signatureAlgorithm());
}
get signatureAlgorithmOid() {
return this.cached('signatureAlgorithmOid', () => this.handle.signatureAlgorithmOid());
}
get ca() {
return this.cached('ca', () => this.handle.ca());
}
get raw() {
return this.cached('raw', () => _reactNativeBuffer.Buffer.from(this.handle.raw()));
}
get publicKey() {
return this.cached('publicKey', () => new _keys.PublicKeyObject(this.handle.publicKey()));
}
get issuerCertificate() {
return undefined;
}
checkHost(name, options) {
if (typeof name !== 'string') {
throw new TypeError('The "name" argument must be a string');
}
return this.handle.checkHost(name, getFlags(options));
}
checkEmail(email, options) {
if (typeof email !== 'string') {
throw new TypeError('The "email" argument must be a string');
}
return this.handle.checkEmail(email, getFlags(options));
}
checkIP(ip) {
if (typeof ip !== 'string') {
throw new TypeError('The "ip" argument must be a string');
}
return this.handle.checkIP(ip);
}
checkIssued(otherCert) {
if (!(otherCert instanceof X509Certificate)) {
throw new TypeError('The "otherCert" argument must be an instance of X509Certificate');
}
return this.handle.checkIssued(otherCert.handle);
}
checkPrivateKey(pkey) {
if (!(pkey instanceof _keys.KeyObject)) {
throw new TypeError('The "pkey" argument must be an instance of KeyObject');
}
if (pkey.type !== 'private') {
throw new TypeError('The "pkey" argument must be a private key');
}
return this.handle.checkPrivateKey(pkey.handle);
}
verify(pkey) {
if (!(pkey instanceof _keys.KeyObject)) {
throw new TypeError('The "pkey" argument must be an instance of KeyObject');
}
if (pkey.type !== 'public') {
throw new TypeError(`The "pkey" argument must be a public key, got '${pkey.type}'`);
}
return this.handle.verify(pkey.handle);
}
toString() {
return this.cached('pem', () => this.handle.pem());
}
toJSON() {
return this.toString();
}
toLegacyObject() {
return {
subject: this.subject,
issuer: this.issuer,
subjectaltname: this.subjectAltName,
infoAccess: this.infoAccess,
ca: this.ca,
modulus: undefined,
bits: undefined,
exponent: undefined,
valid_from: this.validFrom,
valid_to: this.validTo,
fingerprint: this.fingerprint,
fingerprint256: this.fingerprint256,
fingerprint512: this.fingerprint512,
ext_key_usage: this.keyUsage,
serialNumber: this.serialNumber,
raw: this.raw
};
}
}
exports.X509Certificate = X509Certificate;
//# sourceMappingURL=x509certificate.js.map