@sphereon/ssi-sdk-ext.key-utils 0.24.0 → 0.24.1-next.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/functions.d.ts +14 -1
- package/dist/functions.d.ts.map +1 -1
- package/dist/functions.js +181 -18
- package/dist/functions.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/jwk-jcs.d.ts +28 -1
- package/dist/jwk-jcs.d.ts.map +1 -1
- package/dist/jwk-jcs.js +2 -1
- package/dist/jwk-jcs.js.map +1 -1
- package/dist/types/key-util-types.d.ts +33 -9
- package/dist/types/key-util-types.d.ts.map +1 -1
- package/dist/types/key-util-types.js +16 -6
- package/dist/types/key-util-types.js.map +1 -1
- package/package.json +6 -3
- package/src/functions.ts +207 -13
- package/src/index.ts +0 -2
- package/src/jwk-jcs.ts +1 -2
- package/src/types/key-util-types.ts +40 -9
- package/dist/x509/index.d.ts +0 -4
- package/dist/x509/index.d.ts.map +0 -1
- package/dist/x509/index.js +0 -20
- package/dist/x509/index.js.map +0 -1
- package/dist/x509/rsa-key.d.ts +0 -11
- package/dist/x509/rsa-key.d.ts.map +0 -1
- package/dist/x509/rsa-key.js +0 -101
- package/dist/x509/rsa-key.js.map +0 -1
- package/dist/x509/rsa-signer.d.ts +0 -25
- package/dist/x509/rsa-signer.d.ts.map +0 -1
- package/dist/x509/rsa-signer.js +0 -105
- package/dist/x509/rsa-signer.js.map +0 -1
- package/dist/x509/x509-utils.d.ts +0 -25
- package/dist/x509/x509-utils.d.ts.map +0 -1
- package/dist/x509/x509-utils.js +0 -176
- package/dist/x509/x509-utils.js.map +0 -1
- package/src/x509/index.ts +0 -3
- package/src/x509/rsa-key.ts +0 -81
- package/src/x509/rsa-signer.ts +0 -81
- package/src/x509/x509-utils.ts +0 -145
package/dist/x509/rsa-signer.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.RSASigner = void 0;
|
|
36
|
-
const u8a = __importStar(require("uint8arrays"));
|
|
37
|
-
const rsa_key_1 = require("./rsa-key");
|
|
38
|
-
const x509_utils_1 = require("./x509-utils");
|
|
39
|
-
class RSASigner {
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @param key Either in PEM or JWK format (no raw hex keys here!)
|
|
43
|
-
* @param opts The algorithm and signature/encryption schemes
|
|
44
|
-
*/
|
|
45
|
-
constructor(key, opts) {
|
|
46
|
-
var _a, _b;
|
|
47
|
-
if (typeof key === 'string') {
|
|
48
|
-
this.jwk = (0, x509_utils_1.PEMToJwk)(key, opts === null || opts === void 0 ? void 0 : opts.visibility);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
this.jwk = key;
|
|
52
|
-
}
|
|
53
|
-
this.hashAlgorithm = (_a = opts === null || opts === void 0 ? void 0 : opts.hashAlgorithm) !== null && _a !== void 0 ? _a : 'SHA-256';
|
|
54
|
-
this.scheme = (_b = opts === null || opts === void 0 ? void 0 : opts.scheme) !== null && _b !== void 0 ? _b : 'RSA-PSS';
|
|
55
|
-
}
|
|
56
|
-
getImportParams() {
|
|
57
|
-
if (this.scheme === 'RSA-PSS') {
|
|
58
|
-
return { name: this.scheme, saltLength: 32 };
|
|
59
|
-
}
|
|
60
|
-
// console.log({ name: this.scheme /*, hash: this.hashAlgorithm*/ })
|
|
61
|
-
return { name: this.scheme /*, hash: this.hashAlgorithm*/ };
|
|
62
|
-
}
|
|
63
|
-
getKey() {
|
|
64
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
-
if (!this.key) {
|
|
66
|
-
this.key = yield (0, rsa_key_1.cryptoSubtleImportRSAKey)(this.jwk, this.scheme, this.hashAlgorithm);
|
|
67
|
-
}
|
|
68
|
-
return this.key;
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
bufferToString(buf) {
|
|
72
|
-
const uint8Array = new Uint8Array(buf);
|
|
73
|
-
return u8a.toString(uint8Array, 'base64url'); // Needs to be base64url for JsonWebSignature2020. Don't change!
|
|
74
|
-
}
|
|
75
|
-
sign(data) {
|
|
76
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
-
const input = data;
|
|
78
|
-
const key = yield this.getKey();
|
|
79
|
-
const signature = this.bufferToString(yield crypto.subtle.sign(this.getImportParams(), key, input));
|
|
80
|
-
if (!signature) {
|
|
81
|
-
throw Error('Could not sign input data');
|
|
82
|
-
}
|
|
83
|
-
// base64url signature
|
|
84
|
-
return signature;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
verify(data, signature) {
|
|
88
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
-
const jws = signature.includes('.') ? signature.split('.')[2] : signature;
|
|
90
|
-
const input = typeof data == 'string' ? u8a.fromString(data, 'utf-8') : data;
|
|
91
|
-
let key = yield this.getKey();
|
|
92
|
-
if (!key.usages.includes('verify')) {
|
|
93
|
-
const verifyJwk = Object.assign({}, this.jwk);
|
|
94
|
-
delete verifyJwk.d;
|
|
95
|
-
delete verifyJwk.use;
|
|
96
|
-
delete verifyJwk.key_ops;
|
|
97
|
-
key = yield (0, rsa_key_1.cryptoSubtleImportRSAKey)(verifyJwk, this.scheme, this.hashAlgorithm);
|
|
98
|
-
}
|
|
99
|
-
const verificationResult = yield crypto.subtle.verify(this.getImportParams(), key, u8a.fromString(jws, 'base64url'), input);
|
|
100
|
-
return verificationResult;
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
exports.RSASigner = RSASigner;
|
|
105
|
-
//# sourceMappingURL=rsa-signer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rsa-signer.js","sourceRoot":"","sources":["../../src/x509/rsa-signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { JWK, KeyVisibility } from '../types';
|
|
2
|
-
export declare function pemCertChainTox5c(cert: string, maxDepth?: number): string[];
|
|
3
|
-
export declare function x5cToPemCertChain(x5c: string[], maxDepth?: number): string;
|
|
4
|
-
export declare const toKeyObject: (PEM: string, visibility?: KeyVisibility) => {
|
|
5
|
-
pem: string;
|
|
6
|
-
jwk: JWK;
|
|
7
|
-
keyHex: string;
|
|
8
|
-
keyType: KeyVisibility;
|
|
9
|
-
};
|
|
10
|
-
export declare const jwkToPEM: (jwk: JWK, visibility?: KeyVisibility) => string;
|
|
11
|
-
export declare const PEMToJwk: (pem: string, visibility?: KeyVisibility) => JWK;
|
|
12
|
-
export declare const privateKeyHexFromPEM: (PEM: string) => string;
|
|
13
|
-
export declare const hexKeyFromPEMBasedJwk: (jwk: JWK, visibility?: KeyVisibility) => string;
|
|
14
|
-
export declare const publicKeyHexFromPEM: (PEM: string) => string;
|
|
15
|
-
export declare const PEMToHex: (PEM: string, headerKey?: string) => string;
|
|
16
|
-
/**
|
|
17
|
-
* Converts a base64 encoded string to hex string, removing any non-base64 characters, including newlines
|
|
18
|
-
* @param input The input in base64, with optional newlines
|
|
19
|
-
* @param inputEncoding
|
|
20
|
-
*/
|
|
21
|
-
export declare const base64ToHex: (input: string, inputEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad') => string;
|
|
22
|
-
export declare const hexToBase64: (input: number | object | string, targetEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad') => string;
|
|
23
|
-
export declare const hexToPEM: (hex: string, type: KeyVisibility) => string;
|
|
24
|
-
export declare function base64ToPEM(cert: string, headerKey?: 'PUBLIC KEY' | 'RSA PRIVATE KEY' | 'PRIVATE KEY' | 'CERTIFICATE'): string;
|
|
25
|
-
//# sourceMappingURL=x509-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"x509-utils.d.ts","sourceRoot":"","sources":["../../src/x509/x509-utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAI7C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAuB3E;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAU1E;AAED,eAAO,MAAM,WAAW,QAAS,MAAM,eAAc,aAAa;;;;;CAWjE,CAAA;AAED,eAAO,MAAM,QAAQ,QAAS,GAAG,eAAc,aAAa,KAAc,MAEzE,CAAA;AAED,eAAO,MAAM,QAAQ,QAAS,MAAM,eAAc,aAAa,KAAc,GAE5E,CAAA;AACD,eAAO,MAAM,oBAAoB,QAAS,MAAM,WAE/C,CAAA;AAED,eAAO,MAAM,qBAAqB,QAAS,GAAG,eAAc,aAAa,KAAc,MAMtF,CAAA;AAED,eAAO,MAAM,mBAAmB,QAAS,MAAM,WAU9C,CAAA;AAED,eAAO,MAAM,QAAQ,QAAS,MAAM,cAAc,MAAM,KAAG,MAc1D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,UAAW,MAAM,kBAAkB,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,WAG/G,CAAA;AAED,eAAO,MAAM,WAAW,UAAW,MAAM,GAAG,MAAM,GAAG,MAAM,mBAAmB,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,KAAG,MAMrI,CAAA;AAED,eAAO,MAAM,QAAQ,QAAS,MAAM,QAAQ,aAAa,KAAG,MAa3D,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,YAAY,GAAG,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,MAAM,CAO9H"}
|
package/dist/x509/x509-utils.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.base64ToPEM = exports.hexToPEM = exports.hexToBase64 = exports.base64ToHex = exports.PEMToHex = exports.publicKeyHexFromPEM = exports.hexKeyFromPEMBasedJwk = exports.privateKeyHexFromPEM = exports.PEMToJwk = exports.jwkToPEM = exports.toKeyObject = exports.x5cToPemCertChain = exports.pemCertChainTox5c = void 0;
|
|
30
|
-
const u8a = __importStar(require("uint8arrays"));
|
|
31
|
-
// @ts-ignore
|
|
32
|
-
const keyto_1 = __importDefault(require("@trust/keyto"));
|
|
33
|
-
// Based on (MIT licensed):
|
|
34
|
-
// https://github.com/hildjj/node-posh/blob/master/lib/index.js
|
|
35
|
-
function pemCertChainTox5c(cert, maxDepth) {
|
|
36
|
-
if (!maxDepth) {
|
|
37
|
-
maxDepth = 0;
|
|
38
|
-
}
|
|
39
|
-
/*
|
|
40
|
-
* Convert a PEM-encoded certificate to the version used in the x5c element
|
|
41
|
-
* of a [JSON Web Key](http://tools.ietf.org/html/draft-ietf-jose-json-web-key).
|
|
42
|
-
*
|
|
43
|
-
* `cert` PEM-encoded certificate chain
|
|
44
|
-
* `maxdepth` The maximum number of certificates to use from the chain.
|
|
45
|
-
*/
|
|
46
|
-
const intermediate = cert
|
|
47
|
-
.replace(/-----[^\n]+\n?/gm, ',')
|
|
48
|
-
.replace(/\n/g, '')
|
|
49
|
-
.replace(/\r/g, '');
|
|
50
|
-
let x5c = intermediate.split(',').filter(function (c) {
|
|
51
|
-
return c.length > 0;
|
|
52
|
-
});
|
|
53
|
-
if (maxDepth > 0) {
|
|
54
|
-
x5c = x5c.splice(0, maxDepth);
|
|
55
|
-
}
|
|
56
|
-
return x5c;
|
|
57
|
-
}
|
|
58
|
-
exports.pemCertChainTox5c = pemCertChainTox5c;
|
|
59
|
-
function x5cToPemCertChain(x5c, maxDepth) {
|
|
60
|
-
if (!maxDepth) {
|
|
61
|
-
maxDepth = 0;
|
|
62
|
-
}
|
|
63
|
-
const length = maxDepth === 0 ? x5c.length : Math.min(maxDepth, x5c.length);
|
|
64
|
-
let pem = '';
|
|
65
|
-
for (let i = 0; i < length; i++) {
|
|
66
|
-
pem += base64ToPEM(x5c[i], 'CERTIFICATE');
|
|
67
|
-
}
|
|
68
|
-
return pem;
|
|
69
|
-
}
|
|
70
|
-
exports.x5cToPemCertChain = x5cToPemCertChain;
|
|
71
|
-
const toKeyObject = (PEM, visibility = 'public') => {
|
|
72
|
-
const jwk = (0, exports.PEMToJwk)(PEM, visibility);
|
|
73
|
-
const keyVisibility = jwk.d ? 'private' : 'public';
|
|
74
|
-
const keyHex = keyVisibility === 'private' ? (0, exports.privateKeyHexFromPEM)(PEM) : (0, exports.publicKeyHexFromPEM)(PEM);
|
|
75
|
-
return {
|
|
76
|
-
pem: (0, exports.hexToPEM)(keyHex, visibility),
|
|
77
|
-
jwk,
|
|
78
|
-
keyHex,
|
|
79
|
-
keyType: keyVisibility,
|
|
80
|
-
};
|
|
81
|
-
};
|
|
82
|
-
exports.toKeyObject = toKeyObject;
|
|
83
|
-
const jwkToPEM = (jwk, visibility = 'public') => {
|
|
84
|
-
return keyto_1.default.from(jwk, 'jwk').toString('pem', visibility === 'public' ? 'public_pkcs8' : 'private_pkcs8');
|
|
85
|
-
};
|
|
86
|
-
exports.jwkToPEM = jwkToPEM;
|
|
87
|
-
const PEMToJwk = (pem, visibility = 'public') => {
|
|
88
|
-
return keyto_1.default.from(pem, 'pem').toJwk(visibility);
|
|
89
|
-
};
|
|
90
|
-
exports.PEMToJwk = PEMToJwk;
|
|
91
|
-
const privateKeyHexFromPEM = (PEM) => {
|
|
92
|
-
return (0, exports.PEMToHex)(PEM);
|
|
93
|
-
};
|
|
94
|
-
exports.privateKeyHexFromPEM = privateKeyHexFromPEM;
|
|
95
|
-
const hexKeyFromPEMBasedJwk = (jwk, visibility = 'public') => {
|
|
96
|
-
if (visibility === 'private') {
|
|
97
|
-
return (0, exports.privateKeyHexFromPEM)((0, exports.jwkToPEM)(jwk, 'private'));
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
return (0, exports.publicKeyHexFromPEM)((0, exports.jwkToPEM)(jwk, 'public'));
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
exports.hexKeyFromPEMBasedJwk = hexKeyFromPEMBasedJwk;
|
|
104
|
-
const publicKeyHexFromPEM = (PEM) => {
|
|
105
|
-
const hex = (0, exports.PEMToHex)(PEM);
|
|
106
|
-
if (PEM.includes('CERTIFICATE')) {
|
|
107
|
-
throw Error('Cannot directly deduce public Key from PEM Certificate yet');
|
|
108
|
-
}
|
|
109
|
-
else if (!PEM.includes('PRIVATE')) {
|
|
110
|
-
return hex;
|
|
111
|
-
}
|
|
112
|
-
const publicJwk = (0, exports.PEMToJwk)(PEM, 'public');
|
|
113
|
-
const publicPEM = (0, exports.jwkToPEM)(publicJwk, 'public');
|
|
114
|
-
return (0, exports.PEMToHex)(publicPEM);
|
|
115
|
-
};
|
|
116
|
-
exports.publicKeyHexFromPEM = publicKeyHexFromPEM;
|
|
117
|
-
const PEMToHex = (PEM, headerKey) => {
|
|
118
|
-
if (PEM.indexOf('-----BEGIN ') == -1) {
|
|
119
|
-
throw Error(`PEM header not found: ${headerKey}`);
|
|
120
|
-
}
|
|
121
|
-
let strippedPem;
|
|
122
|
-
if (headerKey) {
|
|
123
|
-
strippedPem = PEM.replace(new RegExp('^[^]*-----BEGIN ' + headerKey + '-----'), '');
|
|
124
|
-
strippedPem = strippedPem.replace(new RegExp('-----END ' + headerKey + '-----[^]*$'), '');
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
strippedPem = PEM.replace(/^[^]*-----BEGIN [^-]+-----/, '');
|
|
128
|
-
strippedPem = strippedPem.replace(/-----END [^-]+-----[^]*$/, '');
|
|
129
|
-
}
|
|
130
|
-
return (0, exports.base64ToHex)(strippedPem, 'base64pad');
|
|
131
|
-
};
|
|
132
|
-
exports.PEMToHex = PEMToHex;
|
|
133
|
-
/**
|
|
134
|
-
* Converts a base64 encoded string to hex string, removing any non-base64 characters, including newlines
|
|
135
|
-
* @param input The input in base64, with optional newlines
|
|
136
|
-
* @param inputEncoding
|
|
137
|
-
*/
|
|
138
|
-
const base64ToHex = (input, inputEncoding) => {
|
|
139
|
-
const base64NoNewlines = input.replace(/[^0-9A-Za-z_\-~\/+=]*/g, '');
|
|
140
|
-
return u8a.toString(u8a.fromString(base64NoNewlines, inputEncoding ? inputEncoding : 'base64pad'), 'base16');
|
|
141
|
-
};
|
|
142
|
-
exports.base64ToHex = base64ToHex;
|
|
143
|
-
const hexToBase64 = (input, targetEncoding) => {
|
|
144
|
-
let hex = typeof input === 'string' ? input : input.toString(16);
|
|
145
|
-
if (hex.length % 2 === 1) {
|
|
146
|
-
hex = `0${hex}`;
|
|
147
|
-
}
|
|
148
|
-
return u8a.toString(u8a.fromString(hex, 'base16'), targetEncoding ? targetEncoding : 'base64pad');
|
|
149
|
-
};
|
|
150
|
-
exports.hexToBase64 = hexToBase64;
|
|
151
|
-
const hexToPEM = (hex, type) => {
|
|
152
|
-
const base64 = (0, exports.hexToBase64)(hex, 'base64pad');
|
|
153
|
-
const headerKey = type === 'private' ? 'RSA PRIVATE KEY' : 'PUBLIC KEY';
|
|
154
|
-
if (type === 'private') {
|
|
155
|
-
const pem = base64ToPEM(base64, headerKey);
|
|
156
|
-
try {
|
|
157
|
-
(0, exports.PEMToJwk)(pem); // We only use it to test the private key
|
|
158
|
-
return pem;
|
|
159
|
-
}
|
|
160
|
-
catch (error) {
|
|
161
|
-
return base64ToPEM(base64, 'PRIVATE KEY');
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return base64ToPEM(base64, headerKey);
|
|
165
|
-
};
|
|
166
|
-
exports.hexToPEM = hexToPEM;
|
|
167
|
-
function base64ToPEM(cert, headerKey) {
|
|
168
|
-
const key = headerKey !== null && headerKey !== void 0 ? headerKey : 'CERTIFICATE';
|
|
169
|
-
const matches = cert.match(/.{1,64}/g);
|
|
170
|
-
if (!matches) {
|
|
171
|
-
throw Error('Invalid cert input value supplied');
|
|
172
|
-
}
|
|
173
|
-
return `-----BEGIN ${key}-----\n${matches.join('\n')}\n-----END ${key}-----\n`;
|
|
174
|
-
}
|
|
175
|
-
exports.base64ToPEM = base64ToPEM;
|
|
176
|
-
//# sourceMappingURL=x509-utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"x509-utils.js","sourceRoot":"","sources":["../../src/x509/x509-utils.ts"],"names":[],"mappings":"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"}
|
package/src/x509/index.ts
DELETED
package/src/x509/rsa-key.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import * as u8a from 'uint8arrays'
|
|
2
|
-
import { HashAlgorithm } from '../digest-methods'
|
|
3
|
-
import { JWK } from '../types'
|
|
4
|
-
import { base64ToPEM } from './x509-utils'
|
|
5
|
-
|
|
6
|
-
export type RSASignatureSchemes = 'RSASSA-PKCS1-V1_5' | 'RSA-PSS'
|
|
7
|
-
|
|
8
|
-
export type RSAEncryptionSchemes = 'RSAES-PKCS-v1_5 ' | 'RSAES-OAEP'
|
|
9
|
-
|
|
10
|
-
const usage = (jwk: JWK): KeyUsage[] => {
|
|
11
|
-
if (jwk.key_ops && jwk.key_ops.length > 0) {
|
|
12
|
-
return jwk.key_ops as KeyUsage[]
|
|
13
|
-
}
|
|
14
|
-
if (jwk.use) {
|
|
15
|
-
const usages: KeyUsage[] = []
|
|
16
|
-
if (jwk.use.includes('sig')) {
|
|
17
|
-
usages.push('sign', 'verify')
|
|
18
|
-
} else if (jwk.use.includes('enc')) {
|
|
19
|
-
usages.push('encrypt', 'decrypt')
|
|
20
|
-
}
|
|
21
|
-
if (usages.length > 0) {
|
|
22
|
-
return usages
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
if (jwk.kty === 'RSA') {
|
|
26
|
-
if (jwk.d) {
|
|
27
|
-
return jwk.alg?.toUpperCase()?.includes('QAEP') ? ['encrypt'] : ['sign']
|
|
28
|
-
}
|
|
29
|
-
return jwk.alg?.toUpperCase()?.includes('QAEP') ? ['decrypt'] : ['verify']
|
|
30
|
-
}
|
|
31
|
-
// "decrypt" | "deriveBits" | "deriveKey" | "encrypt" | "sign" | "unwrapKey" | "verify" | "wrapKey";
|
|
32
|
-
return jwk.d && jwk.kty !== 'RSA' ? ['sign', 'decrypt', 'verify', 'encrypt'] : ['verify']
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const signAlgorithmToSchemeAndHashAlg = (signingAlg: string) => {
|
|
36
|
-
const alg = signingAlg.toUpperCase()
|
|
37
|
-
let scheme: RSAEncryptionSchemes | RSASignatureSchemes
|
|
38
|
-
if (alg.startsWith('RS')) {
|
|
39
|
-
scheme = 'RSASSA-PKCS1-V1_5'
|
|
40
|
-
} else if (alg.startsWith('PS')) {
|
|
41
|
-
scheme = 'RSA-PSS'
|
|
42
|
-
} else {
|
|
43
|
-
throw Error(`Invalid signing algorithm supplied ${signingAlg}`)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const hashAlgorithm = `SHA-${alg.substring(2)}` as HashAlgorithm
|
|
47
|
-
return { scheme, hashAlgorithm }
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export const cryptoSubtleImportRSAKey = async (
|
|
51
|
-
jwk: JWK,
|
|
52
|
-
scheme: RSAEncryptionSchemes | RSASignatureSchemes,
|
|
53
|
-
hashAlgorithm?: HashAlgorithm
|
|
54
|
-
): Promise<CryptoKey> => {
|
|
55
|
-
const hashName = hashAlgorithm ? hashAlgorithm : jwk.alg ? `SHA-${jwk.alg.substring(2)}` : 'SHA-256'
|
|
56
|
-
|
|
57
|
-
const importParams: RsaHashedImportParams = { name: scheme, hash: hashName }
|
|
58
|
-
return await crypto.subtle.importKey('jwk', jwk as JsonWebKey, importParams, false, usage(jwk))
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export const generateRSAKeyAsPEM = async (
|
|
62
|
-
scheme: RSAEncryptionSchemes | RSASignatureSchemes,
|
|
63
|
-
hashAlgorithm?: HashAlgorithm,
|
|
64
|
-
modulusLength?: number
|
|
65
|
-
): Promise<string> => {
|
|
66
|
-
const hashName = hashAlgorithm ? hashAlgorithm : 'SHA-256'
|
|
67
|
-
|
|
68
|
-
const params: RsaHashedKeyGenParams = {
|
|
69
|
-
name: scheme,
|
|
70
|
-
hash: hashName,
|
|
71
|
-
modulusLength: modulusLength ? modulusLength : 2048,
|
|
72
|
-
publicExponent: new Uint8Array([1, 0, 1]),
|
|
73
|
-
}
|
|
74
|
-
const keyUsage: KeyUsage[] = scheme === 'RSA-PSS' || scheme === 'RSASSA-PKCS1-V1_5' ? ['sign', 'verify'] : ['encrypt', 'decrypt']
|
|
75
|
-
|
|
76
|
-
const keypair = await crypto.subtle.generateKey(params, true, keyUsage)
|
|
77
|
-
const pkcs8 = await crypto.subtle.exportKey('pkcs8', keypair.privateKey)
|
|
78
|
-
|
|
79
|
-
const uint8Array = new Uint8Array(pkcs8)
|
|
80
|
-
return base64ToPEM(u8a.toString(uint8Array, 'base64pad'), 'RSA PRIVATE KEY')
|
|
81
|
-
}
|
package/src/x509/rsa-signer.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import * as u8a from 'uint8arrays'
|
|
2
|
-
import { HashAlgorithm } from '../digest-methods'
|
|
3
|
-
import { JWK, KeyVisibility } from '../types'
|
|
4
|
-
import { cryptoSubtleImportRSAKey, RSAEncryptionSchemes, RSASignatureSchemes } from './rsa-key'
|
|
5
|
-
import { PEMToJwk } from './x509-utils'
|
|
6
|
-
|
|
7
|
-
export class RSASigner {
|
|
8
|
-
private readonly hashAlgorithm: HashAlgorithm
|
|
9
|
-
private readonly jwk: JWK
|
|
10
|
-
|
|
11
|
-
private key: CryptoKey | undefined
|
|
12
|
-
private readonly scheme: RSAEncryptionSchemes | RSASignatureSchemes
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
* @param key Either in PEM or JWK format (no raw hex keys here!)
|
|
17
|
-
* @param opts The algorithm and signature/encryption schemes
|
|
18
|
-
*/
|
|
19
|
-
constructor(
|
|
20
|
-
key: string | JWK,
|
|
21
|
-
opts?: { hashAlgorithm?: HashAlgorithm; scheme?: RSAEncryptionSchemes | RSASignatureSchemes; visibility?: KeyVisibility }
|
|
22
|
-
) {
|
|
23
|
-
if (typeof key === 'string') {
|
|
24
|
-
this.jwk = PEMToJwk(key, opts?.visibility)
|
|
25
|
-
} else {
|
|
26
|
-
this.jwk = key
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
this.hashAlgorithm = opts?.hashAlgorithm ?? 'SHA-256'
|
|
30
|
-
this.scheme = opts?.scheme ?? 'RSA-PSS'
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private getImportParams(): AlgorithmIdentifier | RsaPssParams {
|
|
34
|
-
if (this.scheme === 'RSA-PSS') {
|
|
35
|
-
return { name: this.scheme, saltLength: 32 }
|
|
36
|
-
}
|
|
37
|
-
// console.log({ name: this.scheme /*, hash: this.hashAlgorithm*/ })
|
|
38
|
-
return { name: this.scheme /*, hash: this.hashAlgorithm*/ }
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
private async getKey(): Promise<CryptoKey> {
|
|
42
|
-
if (!this.key) {
|
|
43
|
-
this.key = await cryptoSubtleImportRSAKey(this.jwk, this.scheme, this.hashAlgorithm)
|
|
44
|
-
}
|
|
45
|
-
return this.key
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private bufferToString(buf: ArrayBuffer) {
|
|
49
|
-
const uint8Array = new Uint8Array(buf)
|
|
50
|
-
return u8a.toString(uint8Array, 'base64url') // Needs to be base64url for JsonWebSignature2020. Don't change!
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public async sign(data: Uint8Array): Promise<string> {
|
|
54
|
-
const input = data
|
|
55
|
-
const key = await this.getKey()
|
|
56
|
-
const signature = this.bufferToString(await crypto.subtle.sign(this.getImportParams(), key, input))
|
|
57
|
-
if (!signature) {
|
|
58
|
-
throw Error('Could not sign input data')
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// base64url signature
|
|
62
|
-
return signature
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
public async verify(data: string | Uint8Array, signature: string): Promise<boolean> {
|
|
66
|
-
const jws = signature.includes('.') ? signature.split('.')[2] : signature
|
|
67
|
-
|
|
68
|
-
const input = typeof data == 'string' ? u8a.fromString(data, 'utf-8') : data
|
|
69
|
-
|
|
70
|
-
let key = await this.getKey()
|
|
71
|
-
if (!key.usages.includes('verify')) {
|
|
72
|
-
const verifyJwk = { ...this.jwk }
|
|
73
|
-
delete verifyJwk.d
|
|
74
|
-
delete verifyJwk.use
|
|
75
|
-
delete verifyJwk.key_ops
|
|
76
|
-
key = await cryptoSubtleImportRSAKey(verifyJwk, this.scheme, this.hashAlgorithm)
|
|
77
|
-
}
|
|
78
|
-
const verificationResult = await crypto.subtle.verify(this.getImportParams(), key, u8a.fromString(jws, 'base64url'), input)
|
|
79
|
-
return verificationResult
|
|
80
|
-
}
|
|
81
|
-
}
|
package/src/x509/x509-utils.ts
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import * as u8a from 'uint8arrays'
|
|
2
|
-
// @ts-ignore
|
|
3
|
-
import keyto from '@trust/keyto'
|
|
4
|
-
import { JWK, KeyVisibility } from '../types'
|
|
5
|
-
|
|
6
|
-
// Based on (MIT licensed):
|
|
7
|
-
// https://github.com/hildjj/node-posh/blob/master/lib/index.js
|
|
8
|
-
export function pemCertChainTox5c(cert: string, maxDepth?: number): string[] {
|
|
9
|
-
if (!maxDepth) {
|
|
10
|
-
maxDepth = 0
|
|
11
|
-
}
|
|
12
|
-
/*
|
|
13
|
-
* Convert a PEM-encoded certificate to the version used in the x5c element
|
|
14
|
-
* of a [JSON Web Key](http://tools.ietf.org/html/draft-ietf-jose-json-web-key).
|
|
15
|
-
*
|
|
16
|
-
* `cert` PEM-encoded certificate chain
|
|
17
|
-
* `maxdepth` The maximum number of certificates to use from the chain.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const intermediate = cert
|
|
21
|
-
.replace(/-----[^\n]+\n?/gm, ',')
|
|
22
|
-
.replace(/\n/g, '')
|
|
23
|
-
.replace(/\r/g, '')
|
|
24
|
-
let x5c = intermediate.split(',').filter(function (c) {
|
|
25
|
-
return c.length > 0
|
|
26
|
-
})
|
|
27
|
-
if (maxDepth > 0) {
|
|
28
|
-
x5c = x5c.splice(0, maxDepth)
|
|
29
|
-
}
|
|
30
|
-
return x5c
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function x5cToPemCertChain(x5c: string[], maxDepth?: number): string {
|
|
34
|
-
if (!maxDepth) {
|
|
35
|
-
maxDepth = 0
|
|
36
|
-
}
|
|
37
|
-
const length = maxDepth === 0 ? x5c.length : Math.min(maxDepth, x5c.length)
|
|
38
|
-
let pem = ''
|
|
39
|
-
for (let i = 0; i < length; i++) {
|
|
40
|
-
pem += base64ToPEM(x5c[i], 'CERTIFICATE')
|
|
41
|
-
}
|
|
42
|
-
return pem
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const toKeyObject = (PEM: string, visibility: KeyVisibility = 'public') => {
|
|
46
|
-
const jwk = PEMToJwk(PEM, visibility)
|
|
47
|
-
const keyVisibility: KeyVisibility = jwk.d ? 'private' : 'public'
|
|
48
|
-
const keyHex = keyVisibility === 'private' ? privateKeyHexFromPEM(PEM) : publicKeyHexFromPEM(PEM)
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
pem: hexToPEM(keyHex, visibility),
|
|
52
|
-
jwk,
|
|
53
|
-
keyHex,
|
|
54
|
-
keyType: keyVisibility,
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export const jwkToPEM = (jwk: JWK, visibility: KeyVisibility = 'public'): string => {
|
|
59
|
-
return keyto.from(jwk, 'jwk').toString('pem', visibility === 'public' ? 'public_pkcs8' : 'private_pkcs8')
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export const PEMToJwk = (pem: string, visibility: KeyVisibility = 'public'): JWK => {
|
|
63
|
-
return keyto.from(pem, 'pem').toJwk(visibility)
|
|
64
|
-
}
|
|
65
|
-
export const privateKeyHexFromPEM = (PEM: string) => {
|
|
66
|
-
return PEMToHex(PEM)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export const hexKeyFromPEMBasedJwk = (jwk: JWK, visibility: KeyVisibility = 'public'): string => {
|
|
70
|
-
if (visibility === 'private') {
|
|
71
|
-
return privateKeyHexFromPEM(jwkToPEM(jwk, 'private'))
|
|
72
|
-
} else {
|
|
73
|
-
return publicKeyHexFromPEM(jwkToPEM(jwk, 'public'))
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export const publicKeyHexFromPEM = (PEM: string) => {
|
|
78
|
-
const hex = PEMToHex(PEM)
|
|
79
|
-
if (PEM.includes('CERTIFICATE')) {
|
|
80
|
-
throw Error('Cannot directly deduce public Key from PEM Certificate yet')
|
|
81
|
-
} else if (!PEM.includes('PRIVATE')) {
|
|
82
|
-
return hex
|
|
83
|
-
}
|
|
84
|
-
const publicJwk = PEMToJwk(PEM, 'public')
|
|
85
|
-
const publicPEM = jwkToPEM(publicJwk, 'public')
|
|
86
|
-
return PEMToHex(publicPEM)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export const PEMToHex = (PEM: string, headerKey?: string): string => {
|
|
90
|
-
if (PEM.indexOf('-----BEGIN ') == -1) {
|
|
91
|
-
throw Error(`PEM header not found: ${headerKey}`)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
let strippedPem: string
|
|
95
|
-
if (headerKey) {
|
|
96
|
-
strippedPem = PEM.replace(new RegExp('^[^]*-----BEGIN ' + headerKey + '-----'), '')
|
|
97
|
-
strippedPem = strippedPem.replace(new RegExp('-----END ' + headerKey + '-----[^]*$'), '')
|
|
98
|
-
} else {
|
|
99
|
-
strippedPem = PEM.replace(/^[^]*-----BEGIN [^-]+-----/, '')
|
|
100
|
-
strippedPem = strippedPem.replace(/-----END [^-]+-----[^]*$/, '')
|
|
101
|
-
}
|
|
102
|
-
return base64ToHex(strippedPem, 'base64pad')
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Converts a base64 encoded string to hex string, removing any non-base64 characters, including newlines
|
|
107
|
-
* @param input The input in base64, with optional newlines
|
|
108
|
-
* @param inputEncoding
|
|
109
|
-
*/
|
|
110
|
-
export const base64ToHex = (input: string, inputEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad') => {
|
|
111
|
-
const base64NoNewlines = input.replace(/[^0-9A-Za-z_\-~\/+=]*/g, '')
|
|
112
|
-
return u8a.toString(u8a.fromString(base64NoNewlines, inputEncoding ? inputEncoding : 'base64pad'), 'base16')
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export const hexToBase64 = (input: number | object | string, targetEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad'): string => {
|
|
116
|
-
let hex = typeof input === 'string' ? input : input.toString(16)
|
|
117
|
-
if (hex.length % 2 === 1) {
|
|
118
|
-
hex = `0${hex}`
|
|
119
|
-
}
|
|
120
|
-
return u8a.toString(u8a.fromString(hex, 'base16'), targetEncoding ? targetEncoding : 'base64pad')
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export const hexToPEM = (hex: string, type: KeyVisibility): string => {
|
|
124
|
-
const base64 = hexToBase64(hex, 'base64pad')
|
|
125
|
-
const headerKey = type === 'private' ? 'RSA PRIVATE KEY' : 'PUBLIC KEY'
|
|
126
|
-
if (type === 'private') {
|
|
127
|
-
const pem = base64ToPEM(base64, headerKey)
|
|
128
|
-
try {
|
|
129
|
-
PEMToJwk(pem) // We only use it to test the private key
|
|
130
|
-
return pem
|
|
131
|
-
} catch (error) {
|
|
132
|
-
return base64ToPEM(base64, 'PRIVATE KEY')
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return base64ToPEM(base64, headerKey)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export function base64ToPEM(cert: string, headerKey?: 'PUBLIC KEY' | 'RSA PRIVATE KEY' | 'PRIVATE KEY' | 'CERTIFICATE'): string {
|
|
139
|
-
const key = headerKey ?? 'CERTIFICATE'
|
|
140
|
-
const matches = cert.match(/.{1,64}/g)
|
|
141
|
-
if (!matches) {
|
|
142
|
-
throw Error('Invalid cert input value supplied')
|
|
143
|
-
}
|
|
144
|
-
return `-----BEGIN ${key}-----\n${matches.join('\n')}\n-----END ${key}-----\n`
|
|
145
|
-
}
|