"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.appendLeadingZeros = exports.pruneLeadingZeros = exports.getJwkType = exports.getSec1KeyType = exports.getAsn1KeyType = exports.isAsn1Public = exports.isAsn1Encrypted = void 0; var _jsEncodingUtils = _interopRequireDefault(require("js-encoding-utils")); var _params = _interopRequireDefault(require("./params.js")); var _asn1def = require("./asn1def.js"); /** * util.js */ /** * Check if the given key is encrypted. * @param {DER|PEM} key - Private key object in ASN.1 encoding. * @param {AsnFormat} [format='pem'] - pem or der * @return {boolean} - True if encrypted. */ var isAsn1Encrypted = function isAsn1Encrypted(key) { var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'pem'; var keyType; try { keyType = getAsn1KeyType(key, format); } catch (e) { return false; } return keyType === 'encryptedPrivate'; }; /** * Check if the given key is public. * @param {DER|PEM} key - Public key object in ASN.1 encoding. * @param {AsnFormat} format - pem or der * @return {boolean} - True if public. */ exports.isAsn1Encrypted = isAsn1Encrypted; var isAsn1Public = function isAsn1Public(key) { var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'pem'; var keyType; try { keyType = getAsn1KeyType(key, format); } catch (e) { return false; } return keyType === 'public'; }; /** * Retrieve the key type of public or private in ASN.1 format * @param {DER|PEM} key - Key object in ASN.1 encoding. * @param {AsnFormat} format - pem or der * @return {'public'|'private'|'encryptedPrivate'} - The key type of the given key. * @throws {Error} - Throws if NotSpkiNorPkcs8Key. */ exports.isAsn1Public = isAsn1Public; var getAsn1KeyType = function getAsn1KeyType(key) { var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'pem'; // Peel the pem strings var binKey = format === 'pem' ? _jsEncodingUtils.default.formatter.pemToBin(key, 'private') : key; var decoded = _asn1def.KeyStructure.decode(Buffer.from(binKey), 'der'); if (decoded.type === 'encryptedPrivateKeyInfo') return 'encryptedPrivate';else if (decoded.type === 'oneAsymmetricKey') return 'private';else if (decoded.type === 'subjectPublicKeyInfo') return 'public';else throw new Error('NotSpkiNorPkcs8Key'); }; /** * Retrieve the type of SEC1 octet key. * @param {OctetEC} sec1key - Key object in OctetEC encoding in String (hex string) or Uint8Array. * @param {String} namedCurve - Name of elliptic curve like 'P-256'. * @return {PublicOrPrivate} - public or private * @throws {Error} - Throws if UnsupportedKeyStructure. */ exports.getAsn1KeyType = getAsn1KeyType; var getSec1KeyType = function getSec1KeyType(sec1key, namedCurve) { var format; if (sec1key instanceof Uint8Array) format = 'binary';else if (typeof sec1key === 'string') format = 'string';else throw new Error('InvalidObjectType'); var binKey = format === 'string' ? _jsEncodingUtils.default.encoder.hexStringToArrayBuffer(sec1key) : sec1key; var len = _params.default.namedCurves[namedCurve].payloadSize; // original key type if (binKey.length <= len) return 'private';else if (binKey.length === 2 * len + 1 && binKey[0] === 0x04 || binKey.length === len + 1 && (binKey[0] === 0x02 || binKey[0] === 0x03)) return 'public';else throw new Error('UnsupportedKeyStructure'); }; /** * Check key type of JWK. * @param {JsonWebKey} jwkey - Key object in JWK format. * @return {PublicOrPrivate} - public or private * @throws {Error} - Throws if InvalidECKey, InvalidRSAKey or UnsupportedJWKType. */ exports.getSec1KeyType = getSec1KeyType; var getJwkType = function getJwkType(jwkey) { if (jwkey.kty === 'EC') { if (jwkey.x && jwkey.y && jwkey.d) return 'private';else if (jwkey.x && jwkey.y) return 'public';else throw new Error('InvalidECKey'); } else if (jwkey.kty === 'RSA') { if (jwkey.n && jwkey.e && jwkey.d && jwkey.p && jwkey.q && jwkey.dp && jwkey.dq && jwkey.qi) return 'private';else if (jwkey.n && jwkey.e) return 'public';else throw new Error('InvalidRSAKey'); } else throw new Error('UnsupportedJWKType'); }; /** * Prune leading zeros of an octet sequence in Uint8Array for jwk formatting of RSA. * https://tools.ietf.org/html/rfc7518#section-6.3 * @param {Uint8Array} array - The octet sequence. * @return {Uint8Array} - An octet sequence pruned leading zeros of length equal to or shorter than the input array. * @throws {Error} - Throws if NonUint8Array. */ exports.getJwkType = getJwkType; var pruneLeadingZeros = function pruneLeadingZeros(array) { if (!(array instanceof Uint8Array)) throw new Error('NonUint8Array'); var offset = 0; for (var i = 0; i < array.length; i++) { if (array[i] !== 0x00) break; offset++; } var returnArray = new Uint8Array(array.length - offset); returnArray.set(array.slice(offset, array.length)); return returnArray; }; // for pem/oct/der formatting from jwk of RSA /** * Append leading zeros and generate an octet sequence of fixed length. * @param {Uint8Array} array - An octet sequence. * @param {Number} len - Intended length of output sequence. * @returns {Uint8Array} - An octet sequence with leading zeros. * @throws {Error} - Throws if NonUint8Array or InvalidLength. */ exports.pruneLeadingZeros = pruneLeadingZeros; var appendLeadingZeros = function appendLeadingZeros(array, len) { if (!(array instanceof Uint8Array)) throw new Error('NonUint8Array'); if (array.length > len) throw new Error('InvalidLength'); var returnArray = new Uint8Array(len); // initialized with zeros returnArray.set(array, len - array.length); return returnArray; }; exports.appendLeadingZeros = appendLeadingZeros;