@peculiar/certificates-viewer 4.7.0 → 4.7.1-alpha.4
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/components/attribute-certificate-viewer.js +4 -2
- package/components/attribute-certificate-viewer.js.map +1 -1
- package/components/attribute.js +1 -1
- package/components/certificate-viewer.js +3 -2
- package/components/certificate-viewer.js.map +1 -1
- package/components/crl-viewer.js +4 -2
- package/components/crl-viewer.js.map +1 -1
- package/components/csr-viewer.js +1 -1
- package/components/download.js +1674 -45
- package/components/download.js.map +1 -1
- package/components/index2.js +3 -2
- package/components/index2.js.map +1 -1
- package/components/issuer_name.js +1 -1
- package/components/miscellaneous.js +4 -79
- package/components/miscellaneous.js.map +1 -1
- package/components/peculiar-certificate-decoder.js +32 -16
- package/components/peculiar-certificate-decoder.js.map +1 -1
- package/components/peculiar-certificates-viewer.js +1 -1
- package/components/peculiar-ssh-certificate-viewer.d.ts +11 -0
- package/components/peculiar-ssh-certificate-viewer.js +12 -0
- package/components/peculiar-ssh-certificate-viewer.js.map +1 -0
- package/components/peculiar-text-hider.js +1 -32
- package/components/peculiar-text-hider.js.map +1 -1
- package/components/pkcs10_certificate_request.js +2 -1
- package/components/pkcs10_certificate_request.js.map +1 -1
- package/components/row.js +87 -0
- package/components/row.js.map +1 -0
- package/components/ssh-certificate-viewer.js +210 -0
- package/components/ssh-certificate-viewer.js.map +1 -0
- package/components/subject_name.js +2 -2
- package/components/text-hider.js +40 -0
- package/components/text-hider.js.map +1 -0
- package/components/utils.js +39 -0
- package/components/utils.js.map +1 -0
- package/dist/cjs/extension-DTtJlxk8.js +110 -0
- package/dist/cjs/{extension-CGZpfI3W.js.map → extension-DTtJlxk8.js.map} +1 -1
- package/dist/cjs/index.cjs.js +4 -4
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{miscellaneous-D_RAtkZz.js → miscellaneous-DCeacaAw.js} +147 -147
- package/dist/cjs/{miscellaneous-D_RAtkZz.js.map → miscellaneous-DCeacaAw.js.map} +1 -1
- package/dist/cjs/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.peculiar-ssh-certificate-viewer.entry.cjs.js.map +1 -0
- package/dist/cjs/{peculiar-attribute-certificate-viewer_4.cjs.entry.js → peculiar-attribute-certificate-viewer_5.cjs.entry.js} +215 -45
- package/dist/cjs/peculiar-attribute-certificate-viewer_5.cjs.entry.js.map +1 -0
- package/dist/cjs/peculiar-certificate-decoder.cjs.entry.js +25 -21
- package/dist/cjs/peculiar-certificate-decoder.cjs.entry.js.map +1 -1
- package/dist/cjs/peculiar-certificate-decoder.entry.cjs.js.map +1 -1
- package/dist/cjs/peculiar-certificate-viewer.cjs.entry.js +4 -4
- package/dist/cjs/peculiar-certificates-viewer.cjs.entry.js +23 -23
- package/dist/cjs/peculiar-certificates-viewer.cjs.entry.js.map +1 -1
- package/dist/cjs/peculiar-certificates-viewer.entry.cjs.js.map +1 -1
- package/dist/cjs/peculiar.cjs.js +1 -1
- package/dist/cjs/pkcs10_certificate_request-DE-0eDXE.js +146 -0
- package/dist/cjs/{pkcs10_certificate_request-BQkkkT42.js.map → pkcs10_certificate_request-DE-0eDXE.js.map} +1 -1
- package/dist/cjs/{certification_request-DISQwgjn.js → ssh_certificate-D2q_p49O.js} +1676 -16
- package/dist/cjs/ssh_certificate-D2q_p49O.js.map +1 -0
- package/dist/cjs/{x509_certificate-DGRpZGA2.js → x509_certificate-Cto1q-eu.js} +29 -29
- package/dist/cjs/{x509_certificate-DGRpZGA2.js.map → x509_certificate-Cto1q-eu.js.map} +1 -1
- package/dist/cjs/{x509_crl-DMvJk_81.js → x509_crl-CgixMZrh.js} +32 -32
- package/dist/cjs/{x509_crl-DMvJk_81.js.map → x509_crl-CgixMZrh.js.map} +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/certificate-decoder/certificate-decoder.js +10 -6
- package/dist/collection/components/certificate-decoder/certificate-decoder.js.map +1 -1
- package/dist/collection/components/ssh-certificate-viewer/-components/basic_information.js +29 -0
- package/dist/collection/components/ssh-certificate-viewer/-components/basic_information.js.map +1 -0
- package/dist/collection/components/ssh-certificate-viewer/-components/miscellaneous.js +23 -0
- package/dist/collection/components/ssh-certificate-viewer/-components/miscellaneous.js.map +1 -0
- package/dist/collection/components/ssh-certificate-viewer/-components/public_key.js +26 -0
- package/dist/collection/components/ssh-certificate-viewer/-components/public_key.js.map +1 -0
- package/dist/collection/components/ssh-certificate-viewer/-components/signature_key.js +26 -0
- package/dist/collection/components/ssh-certificate-viewer/-components/signature_key.js.map +1 -0
- package/dist/collection/components/ssh-certificate-viewer/ssh-certificate-viewer.js +194 -0
- package/dist/collection/components/ssh-certificate-viewer/ssh-certificate-viewer.js.map +1 -0
- package/dist/collection/crypto/index.js +1 -0
- package/dist/collection/crypto/index.js.map +1 -1
- package/dist/collection/crypto/ssh_certificate.js +74 -0
- package/dist/collection/crypto/ssh_certificate.js.map +1 -0
- package/dist/collection/locales/en.json +6 -1
- package/dist/collection/utils/download.js +5 -0
- package/dist/collection/utils/download.js.map +1 -1
- package/dist/esm/{extension-CUOKUt7o.js → extension-DmlhftES.js} +3 -3
- package/dist/{esm-es5/extension-CUOKUt7o.js.map → esm/extension-DmlhftES.js.map} +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{miscellaneous-DVlekgVM.js → miscellaneous-BTlqwN5_.js} +4 -4
- package/dist/esm/{miscellaneous-DVlekgVM.js.map → miscellaneous-BTlqwN5_.js.map} +1 -1
- package/dist/esm/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.peculiar-ssh-certificate-viewer.entry.js.map +1 -0
- package/dist/esm/{peculiar-attribute-certificate-viewer_4.entry.js → peculiar-attribute-certificate-viewer_5.entry.js} +185 -16
- package/dist/esm/peculiar-attribute-certificate-viewer_5.entry.js.map +1 -0
- package/dist/esm/peculiar-certificate-decoder.entry.js +14 -10
- package/dist/esm/peculiar-certificate-decoder.entry.js.map +1 -1
- package/dist/esm/peculiar-certificate-viewer.entry.js +4 -4
- package/dist/esm/peculiar-certificates-viewer.entry.js +3 -3
- package/dist/esm/peculiar.js +1 -1
- package/dist/esm/{pkcs10_certificate_request-B9Q42jiE.js → pkcs10_certificate_request-B5C1NYFc.js} +3 -3
- package/dist/esm/{pkcs10_certificate_request-B9Q42jiE.js.map → pkcs10_certificate_request-B5C1NYFc.js.map} +1 -1
- package/dist/esm/{certification_request-CSS3OhZq.js → ssh_certificate-PCn0WXhQ.js} +1676 -17
- package/dist/esm/ssh_certificate-PCn0WXhQ.js.map +1 -0
- package/dist/esm/{x509_certificate-fWXLCtc8.js → x509_certificate-BiAmXJ4S.js} +4 -4
- package/dist/esm/{x509_certificate-fWXLCtc8.js.map → x509_certificate-BiAmXJ4S.js.map} +1 -1
- package/dist/esm/{x509_crl-Dq33Vv-q.js → x509_crl-CCeoLLUZ.js} +5 -5
- package/dist/esm/{x509_crl-Dq33Vv-q.js.map → x509_crl-CCeoLLUZ.js.map} +1 -1
- package/dist/esm-es5/{extension-CUOKUt7o.js → extension-DmlhftES.js} +2 -2
- package/dist/{esm/extension-CUOKUt7o.js.map → esm-es5/extension-DmlhftES.js.map} +1 -1
- package/dist/esm-es5/index.js +1 -1
- package/dist/esm-es5/loader.js +2 -2
- package/dist/esm-es5/{miscellaneous-DVlekgVM.js → miscellaneous-BTlqwN5_.js} +2 -2
- package/dist/esm-es5/{miscellaneous-DVlekgVM.js.map → miscellaneous-BTlqwN5_.js.map} +1 -1
- package/dist/esm-es5/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.peculiar-ssh-certificate-viewer.entry.js.map +1 -0
- package/dist/esm-es5/{peculiar-attribute-certificate-viewer_4.entry.js → peculiar-attribute-certificate-viewer_5.entry.js} +31 -3
- package/dist/esm-es5/peculiar-attribute-certificate-viewer_5.entry.js.map +1 -0
- package/dist/esm-es5/peculiar-certificate-decoder.entry.js +1 -1
- package/dist/esm-es5/peculiar-certificate-decoder.entry.js.map +1 -1
- package/dist/esm-es5/peculiar-certificate-viewer.entry.js +1 -1
- package/dist/esm-es5/peculiar-certificates-viewer.entry.js +1 -1
- package/dist/esm-es5/peculiar.js +1 -1
- package/dist/esm-es5/{pkcs10_certificate_request-B9Q42jiE.js → pkcs10_certificate_request-B5C1NYFc.js} +2 -2
- package/dist/esm-es5/{pkcs10_certificate_request-B9Q42jiE.js.map → pkcs10_certificate_request-B5C1NYFc.js.map} +1 -1
- package/dist/esm-es5/{certification_request-CSS3OhZq.js → ssh_certificate-PCn0WXhQ.js} +8 -8
- package/dist/esm-es5/ssh_certificate-PCn0WXhQ.js.map +1 -0
- package/dist/esm-es5/{x509_certificate-fWXLCtc8.js → x509_certificate-BiAmXJ4S.js} +4 -4
- package/dist/esm-es5/{x509_certificate-fWXLCtc8.js.map → x509_certificate-BiAmXJ4S.js.map} +1 -1
- package/dist/esm-es5/{x509_crl-Dq33Vv-q.js → x509_crl-CCeoLLUZ.js} +2 -2
- package/dist/esm-es5/{x509_crl-Dq33Vv-q.js.map → x509_crl-CCeoLLUZ.js.map} +1 -1
- package/dist/peculiar/index.esm.js +1 -1
- package/dist/peculiar/locales/en.json +6 -1
- package/dist/peculiar/{p-17ebc78c.system.entry.js → p-24861cf6.system.entry.js} +2 -2
- package/dist/peculiar/{p-a193f8fd.system.entry.js → p-46c17c8d.system.entry.js} +2 -2
- package/dist/peculiar/{p-a4e74904.entry.js → p-71cb31c6.entry.js} +47 -19
- package/dist/peculiar/p-71cb31c6.entry.js.map +1 -0
- package/dist/peculiar/{p-4cc72a56.entry.js → p-71eab586.entry.js} +2 -2
- package/dist/peculiar/p-7273601a.entry.js +5 -0
- package/dist/peculiar/p-7273601a.entry.js.map +1 -0
- package/dist/peculiar/p-83bfd8e5.system.entry.js +5 -0
- package/dist/peculiar/p-83bfd8e5.system.entry.js.map +1 -0
- package/dist/peculiar/{p-e3967e76.entry.js → p-98219569.entry.js} +2 -2
- package/dist/peculiar/p-9MJeDspO.system.js.map +1 -0
- package/dist/peculiar/p-AjXipXSl.system.js +12 -0
- package/dist/peculiar/{p-CgCUixvk.system.js.map → p-AjXipXSl.system.js.map} +1 -1
- package/dist/peculiar/{p-CEzxVCEh.system.js → p-B2FH4Pv2.system.js} +2 -2
- package/dist/peculiar/{p-CEzxVCEh.system.js.map → p-B2FH4Pv2.system.js.map} +1 -1
- package/dist/peculiar/{p-DcTXA-2R.system.js → p-B5GO6_Ut.system.js} +18 -18
- package/dist/peculiar/{p-DcTXA-2R.system.js.map → p-B5GO6_Ut.system.js.map} +1 -1
- package/dist/peculiar/{p-Bsy7Sqzl.system.js.map → p-B82-c-xr.system.js.map} +1 -1
- package/dist/peculiar/p-BGASC3UX.system.js +1 -1
- package/dist/peculiar/p-BHpSDBz_.system.js.map +1 -0
- package/dist/peculiar/p-BwlcJAh0.js +12 -0
- package/dist/peculiar/{p-CZuaTO2G.js.map → p-BwlcJAh0.js.map} +1 -1
- package/dist/peculiar/{p-D8TC0Na9.system.js.map → p-CSz5liuX.system.js.map} +1 -1
- package/dist/peculiar/{p-tl0v45Y7.js → p-CstRxc9v.js} +2 -2
- package/dist/peculiar/{p-tl0v45Y7.js.map → p-CstRxc9v.js.map} +1 -1
- package/dist/peculiar/p-DMDALRLP.system.js +135 -0
- package/dist/peculiar/p-DMDALRLP.system.js.map +1 -0
- package/dist/peculiar/{p-DTz3NA_M.system.js → p-DPbpwYQ8.system.js} +3 -3
- package/dist/peculiar/{p-DTz3NA_M.system.js.map → p-DPbpwYQ8.system.js.map} +1 -1
- package/dist/peculiar/{p-CoPYW15U.js → p-Db41gPxb.js} +4 -4
- package/dist/peculiar/{p-CoPYW15U.js.map → p-Db41gPxb.js.map} +1 -1
- package/dist/peculiar/{p-DKooqn40.js → p-DnOLjFJP.js} +39 -39
- package/dist/peculiar/{p-DKooqn40.js.map → p-DnOLjFJP.js.map} +1 -1
- package/dist/peculiar/{p-CSS3OhZq.js → p-PCn0WXhQ.js} +13 -13
- package/dist/peculiar/p-PCn0WXhQ.js.map +1 -0
- package/dist/peculiar/{p-7fTYvx_V.system.js → p-SjVQtfgD.system.js} +5 -5
- package/dist/peculiar/{p-7fTYvx_V.system.js.map → p-SjVQtfgD.system.js.map} +1 -1
- package/dist/peculiar/{p-e7c60082.system.entry.js → p-cc01a2da.system.entry.js} +47 -19
- package/dist/peculiar/p-cc01a2da.system.entry.js.map +1 -0
- package/dist/peculiar/{p-BTn-wukS.system.js → p-dOkqMp-O.system.js} +2 -2
- package/dist/peculiar/p-dOkqMp-O.system.js.map +1 -0
- package/dist/peculiar/{p-BG_D4qzJ.js → p-h7XP7otl.js} +3 -3
- package/dist/peculiar/{p-BG_D4qzJ.js.map → p-h7XP7otl.js.map} +1 -1
- package/dist/peculiar/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.peculiar-ssh-certificate-viewer.entry.esm.js.map +1 -0
- package/dist/peculiar/peculiar-certificate-decoder.entry.esm.js.map +1 -1
- package/dist/peculiar/peculiar.esm.js +1 -1
- package/dist/types/components/certificate-decoder/certificate-decoder.d.ts +4 -4
- package/dist/types/components/ssh-certificate-viewer/-components/basic_information.d.ts +21 -0
- package/dist/types/components/ssh-certificate-viewer/-components/miscellaneous.d.ts +14 -0
- package/dist/types/components/ssh-certificate-viewer/-components/public_key.d.ts +14 -0
- package/dist/types/components/ssh-certificate-viewer/-components/signature_key.d.ts +14 -0
- package/dist/types/components/ssh-certificate-viewer/ssh-certificate-viewer.d.ts +43 -0
- package/dist/types/components.d.ts +43 -0
- package/dist/types/crypto/index.d.ts +1 -0
- package/dist/types/crypto/ssh_certificate.d.ts +30 -0
- package/dist/types/utils/download.d.ts +3 -0
- package/dist/types/utils/l10n.d.ts +5 -0
- package/hydrate/index.js +1869 -27
- package/hydrate/index.mjs +1869 -27
- package/package.json +3 -2
- package/dist/cjs/certification_request-DISQwgjn.js.map +0 -1
- package/dist/cjs/extension-CGZpfI3W.js +0 -110
- package/dist/cjs/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.entry.cjs.js.map +0 -1
- package/dist/cjs/peculiar-attribute-certificate-viewer_4.cjs.entry.js.map +0 -1
- package/dist/cjs/pkcs10_certificate_request-BQkkkT42.js +0 -146
- package/dist/esm/certification_request-CSS3OhZq.js.map +0 -1
- package/dist/esm/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.entry.js.map +0 -1
- package/dist/esm/peculiar-attribute-certificate-viewer_4.entry.js.map +0 -1
- package/dist/esm-es5/certification_request-CSS3OhZq.js.map +0 -1
- package/dist/esm-es5/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.entry.js.map +0 -1
- package/dist/esm-es5/peculiar-attribute-certificate-viewer_4.entry.js.map +0 -1
- package/dist/peculiar/p-BTn-wukS.system.js.map +0 -1
- package/dist/peculiar/p-CSS3OhZq.js.map +0 -1
- package/dist/peculiar/p-CZuaTO2G.js +0 -12
- package/dist/peculiar/p-CgCUixvk.system.js +0 -12
- package/dist/peculiar/p-DLsQGkmT.system.js.map +0 -1
- package/dist/peculiar/p-D_WeukQa.system.js +0 -135
- package/dist/peculiar/p-D_WeukQa.system.js.map +0 -1
- package/dist/peculiar/p-a4e74904.entry.js.map +0 -1
- package/dist/peculiar/p-ce006f1c.system.entry.js +0 -5
- package/dist/peculiar/p-ce006f1c.system.entry.js.map +0 -1
- package/dist/peculiar/p-e7c60082.system.entry.js.map +0 -1
- package/dist/peculiar/p-f465afe6.entry.js +0 -5
- package/dist/peculiar/p-f465afe6.entry.js.map +0 -1
- package/dist/peculiar/p-tBL0ekYY.system.js.map +0 -1
- package/dist/peculiar/peculiar-attribute-certificate-viewer.peculiar-certificate-chain-viewer.peculiar-crl-viewer.peculiar-csr-viewer.entry.esm.js.map +0 -1
- /package/dist/peculiar/{p-17ebc78c.system.entry.js.map → p-24861cf6.system.entry.js.map} +0 -0
- /package/dist/peculiar/{p-a193f8fd.system.entry.js.map → p-46c17c8d.system.entry.js.map} +0 -0
- /package/dist/peculiar/{p-4cc72a56.entry.js.map → p-71eab586.entry.js.map} +0 -0
- /package/dist/peculiar/{p-e3967e76.entry.js.map → p-98219569.entry.js.map} +0 -0
package/components/download.js
CHANGED
|
@@ -508,6 +508,11 @@ Download.crl = {
|
|
|
508
508
|
downloadFromBuffer(raw, name, 'crl', 'application/pkix-crl');
|
|
509
509
|
},
|
|
510
510
|
};
|
|
511
|
+
Download.certSSH = {
|
|
512
|
+
asSSH: (value, name) => {
|
|
513
|
+
downloadFromBuffer(buildExports.Convert.FromString(value), name, 'cert', 'application/ssh-cert');
|
|
514
|
+
},
|
|
515
|
+
};
|
|
511
516
|
|
|
512
517
|
/*!
|
|
513
518
|
Copyright (c) Peculiar Ventures, LLC
|
|
@@ -6768,6 +6773,10 @@ const crlEntryExtensions = "CRL Entry Extensions";
|
|
|
6768
6773
|
const previewCertificate = "Preview certificate";
|
|
6769
6774
|
const viewDetails = "View details";
|
|
6770
6775
|
const downloadOptions = "Download options";
|
|
6776
|
+
const keyId = "Key ID";
|
|
6777
|
+
const principals = "Principals";
|
|
6778
|
+
const criticalOptions = "Critical Options";
|
|
6779
|
+
const signingCA = "Signing CA";
|
|
6771
6780
|
var en = {
|
|
6772
6781
|
basicInformation: basicInformation,
|
|
6773
6782
|
subjectName: subjectName,
|
|
@@ -6779,6 +6788,7 @@ var en = {
|
|
|
6779
6788
|
download: download,
|
|
6780
6789
|
"download.pem": "Download PEM",
|
|
6781
6790
|
"download.der": "Download DER",
|
|
6791
|
+
"download.ssh": "Download SSH",
|
|
6782
6792
|
serialNumber: serialNumber,
|
|
6783
6793
|
version: version,
|
|
6784
6794
|
validity: validity,
|
|
@@ -6815,7 +6825,11 @@ var en = {
|
|
|
6815
6825
|
crlEntryExtensions: crlEntryExtensions,
|
|
6816
6826
|
previewCertificate: previewCertificate,
|
|
6817
6827
|
viewDetails: viewDetails,
|
|
6818
|
-
downloadOptions: downloadOptions
|
|
6828
|
+
downloadOptions: downloadOptions,
|
|
6829
|
+
keyId: keyId,
|
|
6830
|
+
principals: principals,
|
|
6831
|
+
criticalOptions: criticalOptions,
|
|
6832
|
+
signingCA: signingCA
|
|
6819
6833
|
};
|
|
6820
6834
|
|
|
6821
6835
|
/**
|
|
@@ -9235,13 +9249,13 @@ const OIDs = {
|
|
|
9235
9249
|
* This source code is licensed under the MIT license found in the
|
|
9236
9250
|
* LICENSE file in the root directory of this source tree.
|
|
9237
9251
|
*/
|
|
9238
|
-
var __classPrivateFieldSet$
|
|
9252
|
+
var __classPrivateFieldSet$2 = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
9239
9253
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9240
9254
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9241
9255
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
9242
9256
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
9243
9257
|
};
|
|
9244
|
-
var __classPrivateFieldGet$
|
|
9258
|
+
var __classPrivateFieldGet$2 = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9245
9259
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9246
9260
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
9247
9261
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
@@ -9251,15 +9265,15 @@ class Name {
|
|
|
9251
9265
|
constructor(data) {
|
|
9252
9266
|
_Name_asn.set(this, new Name$1());
|
|
9253
9267
|
if (buildExports.BufferSourceConverter.isBufferSource(data)) {
|
|
9254
|
-
__classPrivateFieldSet$
|
|
9268
|
+
__classPrivateFieldSet$2(this, _Name_asn, AsnParser.parse(data, Name$1), "f");
|
|
9255
9269
|
}
|
|
9256
9270
|
else {
|
|
9257
|
-
__classPrivateFieldSet$
|
|
9271
|
+
__classPrivateFieldSet$2(this, _Name_asn, data, "f");
|
|
9258
9272
|
}
|
|
9259
9273
|
}
|
|
9260
9274
|
toJSON() {
|
|
9261
9275
|
const res = [];
|
|
9262
|
-
__classPrivateFieldGet$
|
|
9276
|
+
__classPrivateFieldGet$2(this, _Name_asn, "f").forEach((o) => (o.forEach((a) => {
|
|
9263
9277
|
res.push({
|
|
9264
9278
|
type: a.type,
|
|
9265
9279
|
name: OIDs[a.type],
|
|
@@ -10800,13 +10814,13 @@ __decorate([
|
|
|
10800
10814
|
* This source code is licensed under the MIT license found in the
|
|
10801
10815
|
* LICENSE file in the root directory of this source tree.
|
|
10802
10816
|
*/
|
|
10803
|
-
var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
10817
|
+
var __classPrivateFieldSet$1 = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
10804
10818
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
10805
10819
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10806
10820
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10807
10821
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
10808
10822
|
};
|
|
10809
|
-
var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
10823
|
+
var __classPrivateFieldGet$1 = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
10810
10824
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10811
10825
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10812
10826
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
@@ -10819,20 +10833,20 @@ class AsnData {
|
|
|
10819
10833
|
_AsnData_raw.set(this, void 0);
|
|
10820
10834
|
if (args.length === 1) {
|
|
10821
10835
|
// asn
|
|
10822
|
-
__classPrivateFieldSet(this, _AsnData_asn, args[0], "f");
|
|
10823
|
-
__classPrivateFieldSet(this, _AsnData_raw, AsnConvert.serialize(__classPrivateFieldGet(this, _AsnData_asn, "f")), "f");
|
|
10836
|
+
__classPrivateFieldSet$1(this, _AsnData_asn, args[0], "f");
|
|
10837
|
+
__classPrivateFieldSet$1(this, _AsnData_raw, AsnConvert.serialize(__classPrivateFieldGet$1(this, _AsnData_asn, "f")), "f");
|
|
10824
10838
|
}
|
|
10825
10839
|
else {
|
|
10826
10840
|
// raw, type
|
|
10827
|
-
__classPrivateFieldSet(this, _AsnData_asn, AsnConvert.parse(args[0], args[1]), "f");
|
|
10828
|
-
__classPrivateFieldSet(this, _AsnData_raw, buildExports.BufferSourceConverter.toArrayBuffer(args[0]), "f");
|
|
10841
|
+
__classPrivateFieldSet$1(this, _AsnData_asn, AsnConvert.parse(args[0], args[1]), "f");
|
|
10842
|
+
__classPrivateFieldSet$1(this, _AsnData_raw, buildExports.BufferSourceConverter.toArrayBuffer(args[0]), "f");
|
|
10829
10843
|
}
|
|
10830
10844
|
}
|
|
10831
10845
|
get asn() {
|
|
10832
|
-
return __classPrivateFieldGet(this, _AsnData_asn, "f");
|
|
10846
|
+
return __classPrivateFieldGet$1(this, _AsnData_asn, "f");
|
|
10833
10847
|
}
|
|
10834
10848
|
get raw() {
|
|
10835
|
-
return __classPrivateFieldGet(this, _AsnData_raw, "f");
|
|
10849
|
+
return __classPrivateFieldGet$1(this, _AsnData_raw, "f");
|
|
10836
10850
|
}
|
|
10837
10851
|
}
|
|
10838
10852
|
_AsnData_asn = new WeakMap(), _AsnData_raw = new WeakMap();
|
|
@@ -11053,36 +11067,6 @@ class CryptoProvider {
|
|
|
11053
11067
|
CryptoProvider.DEFAULT = 'default';
|
|
11054
11068
|
const cryptoProvider = new CryptoProvider();
|
|
11055
11069
|
|
|
11056
|
-
/**
|
|
11057
|
-
* @license
|
|
11058
|
-
* Copyright (c) Peculiar Ventures, LLC.
|
|
11059
|
-
*
|
|
11060
|
-
* This source code is licensed under the MIT license found in the
|
|
11061
|
-
* LICENSE file in the root directory of this source tree.
|
|
11062
|
-
*/
|
|
11063
|
-
const certificateRawToBuffer = (raw) => {
|
|
11064
|
-
if (PemConverter.isPem(raw)) {
|
|
11065
|
-
return PemConverter.decode(raw)[0];
|
|
11066
|
-
}
|
|
11067
|
-
if (buildExports.Convert.isHex(raw)) {
|
|
11068
|
-
return buildExports.Convert.FromHex(raw);
|
|
11069
|
-
}
|
|
11070
|
-
if (buildExports.Convert.isBase64(raw)) {
|
|
11071
|
-
return buildExports.Convert.FromBase64(raw);
|
|
11072
|
-
}
|
|
11073
|
-
if (buildExports.Convert.isBase64Url(raw)) {
|
|
11074
|
-
return buildExports.Convert.FromBase64Url(raw);
|
|
11075
|
-
}
|
|
11076
|
-
return buildExports.Convert.FromBinary(raw);
|
|
11077
|
-
};
|
|
11078
|
-
const getCertificateThumbprint = async (algorithm, data) => {
|
|
11079
|
-
const crypto = cryptoProvider.get();
|
|
11080
|
-
if (crypto.subtle) {
|
|
11081
|
-
return crypto.subtle.digest(algorithm, data);
|
|
11082
|
-
}
|
|
11083
|
-
return undefined;
|
|
11084
|
-
};
|
|
11085
|
-
|
|
11086
11070
|
class ACClearAttrs {
|
|
11087
11071
|
constructor(params = {}) {
|
|
11088
11072
|
this.acIssuer = new GeneralName();
|
|
@@ -12698,6 +12682,1651 @@ __decorate$1([
|
|
|
12698
12682
|
AsnProp({ type: AsnPropTypes.BitString })
|
|
12699
12683
|
], CertificationRequest.prototype, "signature", void 0);
|
|
12700
12684
|
|
|
12685
|
+
let globalCrypto = globalThis.crypto;
|
|
12686
|
+
function getCrypto() {
|
|
12687
|
+
return globalCrypto;
|
|
12688
|
+
}
|
|
12689
|
+
|
|
12690
|
+
class SshError extends Error {
|
|
12691
|
+
code;
|
|
12692
|
+
constructor(message, code) {
|
|
12693
|
+
super(message);
|
|
12694
|
+
this.code = code;
|
|
12695
|
+
this.name = this.constructor.name;
|
|
12696
|
+
if (Error.captureStackTrace) {
|
|
12697
|
+
Error.captureStackTrace(this, this.constructor);
|
|
12698
|
+
}
|
|
12699
|
+
}
|
|
12700
|
+
}
|
|
12701
|
+
class UnsupportedAlgorithmError extends SshError {
|
|
12702
|
+
constructor(algorithm, supportedAlgorithms) {
|
|
12703
|
+
const supported = supportedAlgorithms ? ` Supported: ${supportedAlgorithms.join(', ')}` : '';
|
|
12704
|
+
super(`Unsupported algorithm: ${algorithm}.${supported}`, 'UNSUPPORTED_ALGORITHM');
|
|
12705
|
+
}
|
|
12706
|
+
}
|
|
12707
|
+
class InvalidFormatError extends SshError {
|
|
12708
|
+
constructor(format, expectedFormat) {
|
|
12709
|
+
const expected = expectedFormat ? ` Expected: ${expectedFormat}` : '';
|
|
12710
|
+
super(`Invalid format: ${format}.${expected}`, 'INVALID_FORMAT');
|
|
12711
|
+
}
|
|
12712
|
+
}
|
|
12713
|
+
class UnsupportedKeyTypeError extends SshError {
|
|
12714
|
+
constructor(keyType, supportedTypes) {
|
|
12715
|
+
const supported = supportedTypes ? ` Supported: ${supportedTypes.join(', ')}` : '';
|
|
12716
|
+
super(`Unsupported key type: ${keyType}.${supported}`, 'UNSUPPORTED_KEY_TYPE');
|
|
12717
|
+
}
|
|
12718
|
+
}
|
|
12719
|
+
class InvalidPrivateKeyFormatError extends SshError {
|
|
12720
|
+
constructor(details) {
|
|
12721
|
+
const message = details
|
|
12722
|
+
? `Invalid SSH private key format: ${details}`
|
|
12723
|
+
: 'Invalid SSH private key format';
|
|
12724
|
+
super(message, 'INVALID_PRIVATE_KEY_FORMAT');
|
|
12725
|
+
}
|
|
12726
|
+
}
|
|
12727
|
+
class EncryptedKeyNotSupportedError extends SshError {
|
|
12728
|
+
constructor(cipher) {
|
|
12729
|
+
const message = cipher
|
|
12730
|
+
? `Encrypted SSH private keys are not supported (cipher: ${cipher})`
|
|
12731
|
+
: 'Encrypted SSH private keys are not supported';
|
|
12732
|
+
super(message, 'ENCRYPTED_KEY_NOT_SUPPORTED');
|
|
12733
|
+
}
|
|
12734
|
+
}
|
|
12735
|
+
class InvalidKeyDataError extends SshError {
|
|
12736
|
+
constructor(details) {
|
|
12737
|
+
const message = details ? `Invalid key data: ${details}` : 'Invalid key data';
|
|
12738
|
+
super(message, 'INVALID_KEY_DATA');
|
|
12739
|
+
}
|
|
12740
|
+
}
|
|
12741
|
+
class UnexpectedEOFError extends SshError {
|
|
12742
|
+
constructor(expected, actual) {
|
|
12743
|
+
const details = expected !== undefined && actual !== undefined
|
|
12744
|
+
? ` Expected ${expected} bytes, got ${actual}`
|
|
12745
|
+
: '';
|
|
12746
|
+
super(`Unexpected end of data${details}`, 'UNEXPECTED_EOF');
|
|
12747
|
+
}
|
|
12748
|
+
}
|
|
12749
|
+
|
|
12750
|
+
const encoder = new TextEncoder();
|
|
12751
|
+
const decoder = new TextDecoder();
|
|
12752
|
+
|
|
12753
|
+
class SshReader {
|
|
12754
|
+
buffer;
|
|
12755
|
+
offset;
|
|
12756
|
+
constructor(data) {
|
|
12757
|
+
this.buffer = data;
|
|
12758
|
+
this.offset = 0;
|
|
12759
|
+
}
|
|
12760
|
+
readUint8() {
|
|
12761
|
+
if (this.offset >= this.buffer.length) {
|
|
12762
|
+
throw new UnexpectedEOFError(1, 0);
|
|
12763
|
+
}
|
|
12764
|
+
return this.buffer[this.offset++];
|
|
12765
|
+
}
|
|
12766
|
+
readUint32() {
|
|
12767
|
+
const value = (this.readUint8() << 24) |
|
|
12768
|
+
(this.readUint8() << 16) |
|
|
12769
|
+
(this.readUint8() << 8) |
|
|
12770
|
+
this.readUint8();
|
|
12771
|
+
return value >>> 0;
|
|
12772
|
+
}
|
|
12773
|
+
readUint64() {
|
|
12774
|
+
const high = this.readUint32();
|
|
12775
|
+
const low = this.readUint32();
|
|
12776
|
+
return (BigInt(high) << 32n) | BigInt(low);
|
|
12777
|
+
}
|
|
12778
|
+
readBytes(length) {
|
|
12779
|
+
if (length < 0) {
|
|
12780
|
+
throw new InvalidFormatError(`Invalid length: ${length}`);
|
|
12781
|
+
}
|
|
12782
|
+
if (this.offset + length > this.buffer.length) {
|
|
12783
|
+
throw new UnexpectedEOFError(length, this.buffer.length - this.offset);
|
|
12784
|
+
}
|
|
12785
|
+
const result = this.buffer.subarray(this.offset, this.offset + length);
|
|
12786
|
+
this.offset += length;
|
|
12787
|
+
return result;
|
|
12788
|
+
}
|
|
12789
|
+
readString() {
|
|
12790
|
+
const length = this.readUint32();
|
|
12791
|
+
const bytes = this.readBytes(length);
|
|
12792
|
+
return decoder.decode(bytes);
|
|
12793
|
+
}
|
|
12794
|
+
peekString(length) {
|
|
12795
|
+
if (this.offset + length > this.buffer.length) {
|
|
12796
|
+
throw new UnexpectedEOFError(length, this.buffer.length - this.offset);
|
|
12797
|
+
}
|
|
12798
|
+
const bytes = this.buffer.subarray(this.offset, this.offset + length);
|
|
12799
|
+
return decoder.decode(bytes);
|
|
12800
|
+
}
|
|
12801
|
+
readMpInt(sshEncoding = false) {
|
|
12802
|
+
const length = this.readUint32();
|
|
12803
|
+
const bytes = this.readBytes(length);
|
|
12804
|
+
if (sshEncoding && bytes.length > 1 && bytes[0] === 0x00) {
|
|
12805
|
+
return bytes.subarray(1);
|
|
12806
|
+
}
|
|
12807
|
+
return bytes;
|
|
12808
|
+
}
|
|
12809
|
+
readMpIntSsh() {
|
|
12810
|
+
return this.readMpInt(true);
|
|
12811
|
+
}
|
|
12812
|
+
remaining() {
|
|
12813
|
+
return this.buffer.length - this.offset;
|
|
12814
|
+
}
|
|
12815
|
+
getOffset() {
|
|
12816
|
+
return this.offset;
|
|
12817
|
+
}
|
|
12818
|
+
seek(offset) {
|
|
12819
|
+
if (offset < 0 || offset > this.buffer.length) {
|
|
12820
|
+
throw new InvalidFormatError(`Invalid offset: ${offset}. Buffer length: ${this.buffer.length}`);
|
|
12821
|
+
}
|
|
12822
|
+
this.offset = offset;
|
|
12823
|
+
}
|
|
12824
|
+
}
|
|
12825
|
+
|
|
12826
|
+
class SshWriter {
|
|
12827
|
+
buffer;
|
|
12828
|
+
offset;
|
|
12829
|
+
constructor(initialSize = 1024) {
|
|
12830
|
+
this.buffer = new Uint8Array(initialSize);
|
|
12831
|
+
this.offset = 0;
|
|
12832
|
+
}
|
|
12833
|
+
ensureCapacity(additional) {
|
|
12834
|
+
const required = this.offset + additional;
|
|
12835
|
+
if (required > this.buffer.length) {
|
|
12836
|
+
const newSize = Math.max(required, this.buffer.length * 2);
|
|
12837
|
+
const newBuffer = new Uint8Array(newSize);
|
|
12838
|
+
newBuffer.set(this.buffer.subarray(0, this.offset));
|
|
12839
|
+
this.buffer = newBuffer;
|
|
12840
|
+
}
|
|
12841
|
+
}
|
|
12842
|
+
reserve(minCapacity) {
|
|
12843
|
+
if (minCapacity > this.buffer.length) {
|
|
12844
|
+
const newBuffer = new Uint8Array(minCapacity);
|
|
12845
|
+
newBuffer.set(this.buffer.subarray(0, this.offset));
|
|
12846
|
+
this.buffer = newBuffer;
|
|
12847
|
+
}
|
|
12848
|
+
}
|
|
12849
|
+
writeUint8(value) {
|
|
12850
|
+
this.ensureCapacity(1);
|
|
12851
|
+
this.buffer[this.offset++] = value & 0xff;
|
|
12852
|
+
}
|
|
12853
|
+
writeUint32(value) {
|
|
12854
|
+
this.ensureCapacity(4);
|
|
12855
|
+
this.buffer[this.offset++] = (value >>> 24) & 0xff;
|
|
12856
|
+
this.buffer[this.offset++] = (value >>> 16) & 0xff;
|
|
12857
|
+
this.buffer[this.offset++] = (value >>> 8) & 0xff;
|
|
12858
|
+
this.buffer[this.offset++] = value & 0xff;
|
|
12859
|
+
}
|
|
12860
|
+
writeUint64(value) {
|
|
12861
|
+
this.ensureCapacity(8);
|
|
12862
|
+
const high = Number(value >> 32n);
|
|
12863
|
+
const low = Number(value & 0xffffffffn);
|
|
12864
|
+
this.writeUint32(high);
|
|
12865
|
+
this.writeUint32(low);
|
|
12866
|
+
}
|
|
12867
|
+
writeBytes(data) {
|
|
12868
|
+
this.ensureCapacity(data.length);
|
|
12869
|
+
this.buffer.set(data, this.offset);
|
|
12870
|
+
this.offset += data.length;
|
|
12871
|
+
}
|
|
12872
|
+
writeString(value) {
|
|
12873
|
+
const bytes = encoder.encode(value);
|
|
12874
|
+
this.writeUint32(bytes.length);
|
|
12875
|
+
this.writeBytes(bytes);
|
|
12876
|
+
}
|
|
12877
|
+
writeMpInt(value, sshEncoding = false) {
|
|
12878
|
+
if (sshEncoding && value.length > 0 && (value[0] & 0x80) !== 0) {
|
|
12879
|
+
const paddedBytes = new Uint8Array(value.length + 1);
|
|
12880
|
+
paddedBytes[0] = 0x00;
|
|
12881
|
+
paddedBytes.set(value, 1);
|
|
12882
|
+
this.writeUint32(paddedBytes.length);
|
|
12883
|
+
this.writeBytes(paddedBytes);
|
|
12884
|
+
}
|
|
12885
|
+
else {
|
|
12886
|
+
this.writeUint32(value.length);
|
|
12887
|
+
this.writeBytes(value);
|
|
12888
|
+
}
|
|
12889
|
+
}
|
|
12890
|
+
writeMpIntSsh(value) {
|
|
12891
|
+
this.writeMpInt(value, true);
|
|
12892
|
+
}
|
|
12893
|
+
toUint8Array() {
|
|
12894
|
+
return this.buffer.subarray(0, this.offset);
|
|
12895
|
+
}
|
|
12896
|
+
getOffset() {
|
|
12897
|
+
return this.offset;
|
|
12898
|
+
}
|
|
12899
|
+
seek(offset) {
|
|
12900
|
+
if (offset < 0 || offset > this.buffer.length) {
|
|
12901
|
+
throw new InvalidFormatError('Invalid offset');
|
|
12902
|
+
}
|
|
12903
|
+
this.offset = offset;
|
|
12904
|
+
}
|
|
12905
|
+
}
|
|
12906
|
+
|
|
12907
|
+
class RsaBinding {
|
|
12908
|
+
hash = 'SHA-256';
|
|
12909
|
+
constructor(hash = 'SHA-256') {
|
|
12910
|
+
this.hash = hash;
|
|
12911
|
+
}
|
|
12912
|
+
async importPublicSsh(params) {
|
|
12913
|
+
const { blob, crypto } = params;
|
|
12914
|
+
const reader = new SshReader(blob);
|
|
12915
|
+
reader.readString();
|
|
12916
|
+
const e = reader.readMpInt(true);
|
|
12917
|
+
const n = reader.readMpInt(true);
|
|
12918
|
+
const jwk = {
|
|
12919
|
+
kty: 'RSA',
|
|
12920
|
+
n: buildExports.Convert.ToBase64Url(n),
|
|
12921
|
+
e: buildExports.Convert.ToBase64Url(e),
|
|
12922
|
+
};
|
|
12923
|
+
return crypto.subtle.importKey('jwk', jwk, {
|
|
12924
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
12925
|
+
hash: this.hash,
|
|
12926
|
+
}, true, ['verify']);
|
|
12927
|
+
}
|
|
12928
|
+
async exportPublicSsh(params) {
|
|
12929
|
+
const { publicKey, crypto } = params;
|
|
12930
|
+
const jwk = await crypto.subtle.exportKey('jwk', publicKey);
|
|
12931
|
+
if (!jwk.n || !jwk.e) {
|
|
12932
|
+
throw new InvalidKeyDataError('RSA JWK missing required parameters (n, e)');
|
|
12933
|
+
}
|
|
12934
|
+
const n = buildExports.BufferSourceConverter.toUint8Array(buildExports.Convert.FromBase64Url(jwk.n));
|
|
12935
|
+
const e = buildExports.BufferSourceConverter.toUint8Array(buildExports.Convert.FromBase64Url(jwk.e));
|
|
12936
|
+
const writer = new SshWriter();
|
|
12937
|
+
writer.writeString('ssh-rsa');
|
|
12938
|
+
writer.writeMpInt(e, true);
|
|
12939
|
+
writer.writeMpInt(n, true);
|
|
12940
|
+
return writer.toUint8Array();
|
|
12941
|
+
}
|
|
12942
|
+
async importPublicSpki(params) {
|
|
12943
|
+
const { spki, crypto } = params;
|
|
12944
|
+
return crypto.subtle.importKey('spki', spki, {
|
|
12945
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
12946
|
+
hash: this.hash,
|
|
12947
|
+
}, true, ['verify']);
|
|
12948
|
+
}
|
|
12949
|
+
async exportPublicSpki(params) {
|
|
12950
|
+
const { publicKey, crypto } = params;
|
|
12951
|
+
const spki = await crypto.subtle.exportKey('spki', publicKey);
|
|
12952
|
+
return buildExports.BufferSourceConverter.toUint8Array(spki);
|
|
12953
|
+
}
|
|
12954
|
+
async importPrivatePkcs8(params) {
|
|
12955
|
+
const { pkcs8, crypto } = params;
|
|
12956
|
+
return crypto.subtle.importKey('pkcs8', pkcs8, {
|
|
12957
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
12958
|
+
hash: this.hash,
|
|
12959
|
+
}, true, ['sign']);
|
|
12960
|
+
}
|
|
12961
|
+
async exportPrivatePkcs8(params) {
|
|
12962
|
+
const { privateKey, crypto } = params;
|
|
12963
|
+
const pkcs8 = await crypto.subtle.exportKey('pkcs8', privateKey);
|
|
12964
|
+
return buildExports.BufferSourceConverter.toUint8Array(pkcs8);
|
|
12965
|
+
}
|
|
12966
|
+
async importPrivateSsh(params) {
|
|
12967
|
+
const { sshKey, crypto } = params;
|
|
12968
|
+
const base64Data = sshKey
|
|
12969
|
+
.replace(/-----BEGIN OPENSSH PRIVATE KEY-----/, '')
|
|
12970
|
+
.replace(/-----END OPENSSH PRIVATE KEY-----/, '')
|
|
12971
|
+
.replace(/\s/g, '');
|
|
12972
|
+
const binaryData = buildExports.Convert.FromBase64(base64Data);
|
|
12973
|
+
const reader = new SshReader(buildExports.BufferSourceConverter.toUint8Array(binaryData));
|
|
12974
|
+
const magic = reader.readBytes(15);
|
|
12975
|
+
if (buildExports.Convert.ToHex(magic) !== '6f70656e7373682d6b65792d763100') {
|
|
12976
|
+
throw new InvalidPrivateKeyFormatError('invalid magic string');
|
|
12977
|
+
}
|
|
12978
|
+
const _cipherName = reader.readString();
|
|
12979
|
+
reader.readString();
|
|
12980
|
+
reader.readString();
|
|
12981
|
+
if (_cipherName !== 'none') {
|
|
12982
|
+
throw new EncryptedKeyNotSupportedError(_cipherName);
|
|
12983
|
+
}
|
|
12984
|
+
const numKeys = reader.readUint32();
|
|
12985
|
+
if (numKeys !== 1) {
|
|
12986
|
+
throw new InvalidPrivateKeyFormatError('multiple keys not supported');
|
|
12987
|
+
}
|
|
12988
|
+
const publicKeyLength = reader.readUint32();
|
|
12989
|
+
reader.readBytes(publicKeyLength);
|
|
12990
|
+
const privateKeyLength = reader.readUint32();
|
|
12991
|
+
const privateKeyData = reader.readBytes(privateKeyLength);
|
|
12992
|
+
const privateReader = new SshReader(privateKeyData);
|
|
12993
|
+
const checkint1 = privateReader.readUint32();
|
|
12994
|
+
const checkint2 = privateReader.readUint32();
|
|
12995
|
+
if (checkint1 !== checkint2) {
|
|
12996
|
+
throw new InvalidPrivateKeyFormatError('invalid checkints');
|
|
12997
|
+
}
|
|
12998
|
+
privateReader.readString();
|
|
12999
|
+
const n = privateReader.readMpInt(true);
|
|
13000
|
+
const e = privateReader.readMpInt(true);
|
|
13001
|
+
const d = privateReader.readMpInt(true);
|
|
13002
|
+
const iqmp = privateReader.readMpInt(true);
|
|
13003
|
+
const p = privateReader.readMpInt(true);
|
|
13004
|
+
const q = privateReader.readMpInt(true);
|
|
13005
|
+
privateReader.readString();
|
|
13006
|
+
const dBig = BigInt('0x' + buildExports.Convert.ToHex(d));
|
|
13007
|
+
const pBig = BigInt('0x' + buildExports.Convert.ToHex(p));
|
|
13008
|
+
const qBig = BigInt('0x' + buildExports.Convert.ToHex(q));
|
|
13009
|
+
const dpBig = dBig % (pBig - 1n);
|
|
13010
|
+
const dqBig = dBig % (qBig - 1n);
|
|
13011
|
+
const dpBytes = buildExports.Convert.FromHex(dpBig.toString(16).padStart(p.length * 2, '0'));
|
|
13012
|
+
const dqBytes = buildExports.Convert.FromHex(dqBig.toString(16).padStart(q.length * 2, '0'));
|
|
13013
|
+
const jwk = {
|
|
13014
|
+
kty: 'RSA',
|
|
13015
|
+
n: buildExports.Convert.ToBase64Url(n),
|
|
13016
|
+
e: buildExports.Convert.ToBase64Url(e),
|
|
13017
|
+
d: buildExports.Convert.ToBase64Url(d),
|
|
13018
|
+
p: buildExports.Convert.ToBase64Url(p),
|
|
13019
|
+
q: buildExports.Convert.ToBase64Url(q),
|
|
13020
|
+
dp: buildExports.Convert.ToBase64Url(dpBytes),
|
|
13021
|
+
dq: buildExports.Convert.ToBase64Url(dqBytes),
|
|
13022
|
+
qi: buildExports.Convert.ToBase64Url(iqmp),
|
|
13023
|
+
};
|
|
13024
|
+
return crypto.subtle.importKey('jwk', jwk, {
|
|
13025
|
+
name: 'RSASSA-PKCS1-v1_5',
|
|
13026
|
+
hash: this.hash,
|
|
13027
|
+
}, true, ['sign']);
|
|
13028
|
+
}
|
|
13029
|
+
async exportPrivateSsh(params) {
|
|
13030
|
+
const { privateKey, crypto, jwk: providedJwk } = params;
|
|
13031
|
+
const jwk = providedJwk || (await crypto.subtle.exportKey('jwk', privateKey));
|
|
13032
|
+
if (!jwk.n || !jwk.e || !jwk.d || !jwk.p || !jwk.q) {
|
|
13033
|
+
throw new InvalidKeyDataError('RSA JWK missing required parameters');
|
|
13034
|
+
}
|
|
13035
|
+
const n = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.n));
|
|
13036
|
+
const e = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.e));
|
|
13037
|
+
const d = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.d));
|
|
13038
|
+
const p = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.p));
|
|
13039
|
+
const q = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.q));
|
|
13040
|
+
const qi = jwk.qi ? new Uint8Array(buildExports.Convert.FromBase64Url(jwk.qi)) : new Uint8Array();
|
|
13041
|
+
const writer = new SshWriter();
|
|
13042
|
+
writer.writeString('ssh-rsa');
|
|
13043
|
+
writer.writeMpInt(n, true);
|
|
13044
|
+
writer.writeMpInt(e, true);
|
|
13045
|
+
writer.writeMpInt(d, true);
|
|
13046
|
+
writer.writeMpInt(qi, true);
|
|
13047
|
+
writer.writeMpInt(p, true);
|
|
13048
|
+
writer.writeMpInt(q, true);
|
|
13049
|
+
return writer.toUint8Array();
|
|
13050
|
+
}
|
|
13051
|
+
async sign(params) {
|
|
13052
|
+
const { privateKey, data, crypto, hash } = params;
|
|
13053
|
+
if (hash && hash !== this.hash) {
|
|
13054
|
+
throw new InvalidKeyDataError(`Hash ${hash} not supported for this RSA algorithm`);
|
|
13055
|
+
}
|
|
13056
|
+
if (!privateKey.extractable) {
|
|
13057
|
+
throw new InvalidKeyDataError('Private key is not extractable');
|
|
13058
|
+
}
|
|
13059
|
+
const pkcs8 = await this.exportPrivatePkcs8({ privateKey, crypto });
|
|
13060
|
+
const keyToUse = await this.importPrivatePkcs8({ pkcs8: new Uint8Array(pkcs8), crypto });
|
|
13061
|
+
const signature = await crypto.subtle.sign('RSASSA-PKCS1-v1_5', keyToUse, data);
|
|
13062
|
+
return buildExports.BufferSourceConverter.toUint8Array(signature);
|
|
13063
|
+
}
|
|
13064
|
+
async verify(params) {
|
|
13065
|
+
const { publicKey, signature, data, crypto, hash } = params;
|
|
13066
|
+
if (hash && hash !== this.hash) {
|
|
13067
|
+
return false;
|
|
13068
|
+
}
|
|
13069
|
+
if (!publicKey.extractable) {
|
|
13070
|
+
throw new InvalidKeyDataError('Public key is not extractable');
|
|
13071
|
+
}
|
|
13072
|
+
const spki = await this.exportPublicSpki({ publicKey, crypto });
|
|
13073
|
+
const keyToUse = await this.importPublicSpki({ spki: new Uint8Array(spki), crypto });
|
|
13074
|
+
return crypto.subtle.verify('RSASSA-PKCS1-v1_5', keyToUse, signature, data);
|
|
13075
|
+
}
|
|
13076
|
+
encodeSignature(params) {
|
|
13077
|
+
const { signature, algo } = params;
|
|
13078
|
+
const writer = new SshWriter();
|
|
13079
|
+
writer.writeString(algo);
|
|
13080
|
+
writer.writeUint32(signature.byteLength);
|
|
13081
|
+
writer.writeBytes(signature);
|
|
13082
|
+
return writer.toUint8Array();
|
|
13083
|
+
}
|
|
13084
|
+
decodeSignature(params) {
|
|
13085
|
+
const { signature } = params;
|
|
13086
|
+
const reader = new SshReader(signature);
|
|
13087
|
+
const algo = reader.readString();
|
|
13088
|
+
const sigLength = reader.readUint32();
|
|
13089
|
+
const sig = reader.readBytes(sigLength);
|
|
13090
|
+
return { signature: sig, algo };
|
|
13091
|
+
}
|
|
13092
|
+
supportsCryptoKey(cryptoKey) {
|
|
13093
|
+
return cryptoKey.algorithm.name === 'RSASSA-PKCS1-v1_5';
|
|
13094
|
+
}
|
|
13095
|
+
parsePublicKey(reader) {
|
|
13096
|
+
const publicKeyExponent = reader.readBytes(reader.readUint32());
|
|
13097
|
+
const publicKeyModulus = reader.readBytes(reader.readUint32());
|
|
13098
|
+
const writer = new SshWriter();
|
|
13099
|
+
writer.writeString('ssh-rsa');
|
|
13100
|
+
writer.writeMpInt(publicKeyExponent);
|
|
13101
|
+
writer.writeMpInt(publicKeyModulus);
|
|
13102
|
+
return {
|
|
13103
|
+
type: 'ssh-rsa',
|
|
13104
|
+
keyData: writer.toUint8Array(),
|
|
13105
|
+
};
|
|
13106
|
+
}
|
|
13107
|
+
writePublicKey(writer, publicKey) {
|
|
13108
|
+
const publicKeyReader = new SshReader(publicKey.keyData);
|
|
13109
|
+
publicKeyReader.readString();
|
|
13110
|
+
const e = publicKeyReader.readMpInt();
|
|
13111
|
+
const n = publicKeyReader.readMpInt();
|
|
13112
|
+
writer.writeUint32(e.length);
|
|
13113
|
+
writer.writeBytes(e);
|
|
13114
|
+
writer.writeUint32(n.length);
|
|
13115
|
+
writer.writeBytes(n);
|
|
13116
|
+
}
|
|
13117
|
+
getCertificateType() {
|
|
13118
|
+
return 'ssh-rsa-cert-v01@openssh.com';
|
|
13119
|
+
}
|
|
13120
|
+
getSignatureAlgo() {
|
|
13121
|
+
return this.hash === 'SHA-256' ? 'rsa-sha2-256' : 'rsa-sha2-512';
|
|
13122
|
+
}
|
|
13123
|
+
}
|
|
13124
|
+
|
|
13125
|
+
class EcdsaBinding {
|
|
13126
|
+
curveName;
|
|
13127
|
+
sshType;
|
|
13128
|
+
namedCurve;
|
|
13129
|
+
constructor(curveName, sshType, namedCurve) {
|
|
13130
|
+
this.curveName = curveName;
|
|
13131
|
+
this.sshType = sshType;
|
|
13132
|
+
this.namedCurve = namedCurve;
|
|
13133
|
+
}
|
|
13134
|
+
getHashAlgorithm() {
|
|
13135
|
+
switch (this.namedCurve) {
|
|
13136
|
+
case 'P-256':
|
|
13137
|
+
return 'SHA-256';
|
|
13138
|
+
case 'P-384':
|
|
13139
|
+
return 'SHA-384';
|
|
13140
|
+
case 'P-521':
|
|
13141
|
+
return 'SHA-512';
|
|
13142
|
+
default:
|
|
13143
|
+
return 'SHA-256';
|
|
13144
|
+
}
|
|
13145
|
+
}
|
|
13146
|
+
getExpectedLength() {
|
|
13147
|
+
switch (this.namedCurve) {
|
|
13148
|
+
case 'P-256':
|
|
13149
|
+
return 32;
|
|
13150
|
+
case 'P-384':
|
|
13151
|
+
return 48;
|
|
13152
|
+
case 'P-521':
|
|
13153
|
+
return 66;
|
|
13154
|
+
default:
|
|
13155
|
+
return 32;
|
|
13156
|
+
}
|
|
13157
|
+
}
|
|
13158
|
+
getSignatureCoordLength() {
|
|
13159
|
+
return this.getExpectedLength();
|
|
13160
|
+
}
|
|
13161
|
+
async importPublicSsh(params) {
|
|
13162
|
+
const { blob, crypto } = params;
|
|
13163
|
+
const reader = new SshReader(blob);
|
|
13164
|
+
reader.readString();
|
|
13165
|
+
const curve = reader.readString();
|
|
13166
|
+
if (curve !== this.curveName) {
|
|
13167
|
+
throw new InvalidKeyDataError(`ECDSA curve name ${curve}, expected ${this.curveName}`);
|
|
13168
|
+
}
|
|
13169
|
+
const q = reader.readMpInt();
|
|
13170
|
+
const coordLength = Math.floor((q.length - 1) / 2);
|
|
13171
|
+
const jwk = {
|
|
13172
|
+
kty: 'EC',
|
|
13173
|
+
crv: this.namedCurve,
|
|
13174
|
+
x: buildExports.Convert.ToBase64Url(q.slice(1, 1 + coordLength)),
|
|
13175
|
+
y: buildExports.Convert.ToBase64Url(q.slice(1 + coordLength)),
|
|
13176
|
+
};
|
|
13177
|
+
return crypto.subtle.importKey('jwk', jwk, {
|
|
13178
|
+
name: 'ECDSA',
|
|
13179
|
+
namedCurve: this.namedCurve,
|
|
13180
|
+
}, true, ['verify']);
|
|
13181
|
+
}
|
|
13182
|
+
async exportPublicSsh(params) {
|
|
13183
|
+
const { publicKey, crypto } = params;
|
|
13184
|
+
const jwk = await crypto.subtle.exportKey('jwk', publicKey);
|
|
13185
|
+
if (!jwk.x || !jwk.y) {
|
|
13186
|
+
throw new InvalidKeyDataError('ECDSA JWK missing x or y parameters');
|
|
13187
|
+
}
|
|
13188
|
+
const x = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.x));
|
|
13189
|
+
const y = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.y));
|
|
13190
|
+
const q = new Uint8Array(1 + x.length + y.length);
|
|
13191
|
+
q[0] = 0x04;
|
|
13192
|
+
q.set(x, 1);
|
|
13193
|
+
q.set(y, 1 + x.length);
|
|
13194
|
+
const writer = new SshWriter();
|
|
13195
|
+
writer.writeString(this.sshType);
|
|
13196
|
+
writer.writeString(this.curveName);
|
|
13197
|
+
writer.writeMpInt(q);
|
|
13198
|
+
return writer.toUint8Array();
|
|
13199
|
+
}
|
|
13200
|
+
async importPublicSpki(params) {
|
|
13201
|
+
const { spki, crypto } = params;
|
|
13202
|
+
return crypto.subtle.importKey('spki', spki, {
|
|
13203
|
+
name: 'ECDSA',
|
|
13204
|
+
namedCurve: this.namedCurve,
|
|
13205
|
+
}, true, ['verify']);
|
|
13206
|
+
}
|
|
13207
|
+
async exportPublicSpki(params) {
|
|
13208
|
+
const { publicKey, crypto } = params;
|
|
13209
|
+
const spki = await crypto.subtle.exportKey('spki', publicKey);
|
|
13210
|
+
return buildExports.BufferSourceConverter.toUint8Array(spki);
|
|
13211
|
+
}
|
|
13212
|
+
async importPrivatePkcs8(params) {
|
|
13213
|
+
const { pkcs8, crypto } = params;
|
|
13214
|
+
return crypto.subtle.importKey('pkcs8', pkcs8, {
|
|
13215
|
+
name: 'ECDSA',
|
|
13216
|
+
namedCurve: this.namedCurve,
|
|
13217
|
+
}, true, ['sign']);
|
|
13218
|
+
}
|
|
13219
|
+
async exportPrivatePkcs8(params) {
|
|
13220
|
+
const { privateKey, crypto } = params;
|
|
13221
|
+
const pkcs8 = await crypto.subtle.exportKey('pkcs8', privateKey);
|
|
13222
|
+
return buildExports.BufferSourceConverter.toUint8Array(pkcs8);
|
|
13223
|
+
}
|
|
13224
|
+
async exportPrivateSsh(params) {
|
|
13225
|
+
const { privateKey, crypto, jwk: providedJwk } = params;
|
|
13226
|
+
const jwk = providedJwk || (await crypto.subtle.exportKey('jwk', privateKey));
|
|
13227
|
+
if (!jwk.d || !jwk.x || !jwk.y) {
|
|
13228
|
+
throw new InvalidKeyDataError('ECDSA private key JWK missing required parameters');
|
|
13229
|
+
}
|
|
13230
|
+
const x = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.x));
|
|
13231
|
+
const y = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.y));
|
|
13232
|
+
const d = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.d));
|
|
13233
|
+
const publicPoint = new Uint8Array(1 + x.length + y.length);
|
|
13234
|
+
publicPoint[0] = 0x04;
|
|
13235
|
+
publicPoint.set(x, 1);
|
|
13236
|
+
publicPoint.set(y, 1 + x.length);
|
|
13237
|
+
const writer = new SshWriter();
|
|
13238
|
+
writer.writeString(this.sshType);
|
|
13239
|
+
writer.writeString(this.curveName);
|
|
13240
|
+
writer.writeMpInt(publicPoint);
|
|
13241
|
+
writer.writeMpInt(d);
|
|
13242
|
+
return writer.toUint8Array();
|
|
13243
|
+
}
|
|
13244
|
+
async importPrivateSsh(params) {
|
|
13245
|
+
const { sshKey, crypto } = params;
|
|
13246
|
+
const base64Data = sshKey
|
|
13247
|
+
.replace(/-----BEGIN OPENSSH PRIVATE KEY-----/, '')
|
|
13248
|
+
.replace(/-----END OPENSSH PRIVATE KEY-----/, '')
|
|
13249
|
+
.replace(/\s/g, '');
|
|
13250
|
+
const binaryData = buildExports.Convert.FromBase64(base64Data);
|
|
13251
|
+
const reader = new SshReader(buildExports.BufferSourceConverter.toUint8Array(binaryData));
|
|
13252
|
+
const magic = reader.readBytes(15);
|
|
13253
|
+
if (buildExports.Convert.ToHex(magic) !== '6f70656e7373682d6b65792d763100') {
|
|
13254
|
+
throw new InvalidPrivateKeyFormatError('invalid magic string');
|
|
13255
|
+
}
|
|
13256
|
+
const _cipherName = reader.readString();
|
|
13257
|
+
reader.readString();
|
|
13258
|
+
reader.readString();
|
|
13259
|
+
if (_cipherName !== 'none') {
|
|
13260
|
+
throw new EncryptedKeyNotSupportedError(_cipherName);
|
|
13261
|
+
}
|
|
13262
|
+
const numKeys = reader.readUint32();
|
|
13263
|
+
if (numKeys !== 1) {
|
|
13264
|
+
throw new InvalidPrivateKeyFormatError('multiple keys not supported');
|
|
13265
|
+
}
|
|
13266
|
+
const publicKeyLength = reader.readUint32();
|
|
13267
|
+
reader.readBytes(publicKeyLength);
|
|
13268
|
+
const privateKeyLength = reader.readUint32();
|
|
13269
|
+
const privateKeyData = reader.readBytes(privateKeyLength);
|
|
13270
|
+
const privateReader = new SshReader(privateKeyData);
|
|
13271
|
+
const checkint1 = privateReader.readUint32();
|
|
13272
|
+
const checkint2 = privateReader.readUint32();
|
|
13273
|
+
if (checkint1 !== checkint2) {
|
|
13274
|
+
throw new InvalidPrivateKeyFormatError('invalid checkints');
|
|
13275
|
+
}
|
|
13276
|
+
privateReader.readString();
|
|
13277
|
+
privateReader.readString();
|
|
13278
|
+
const publicKeyPoint = privateReader.readMpInt();
|
|
13279
|
+
const privateKeyValue = privateReader.readMpInt();
|
|
13280
|
+
privateReader.readString();
|
|
13281
|
+
if (publicKeyPoint[0] !== 0x04) {
|
|
13282
|
+
throw new InvalidKeyDataError('invalid ECDSA public key point format');
|
|
13283
|
+
}
|
|
13284
|
+
const coordLength = Math.floor((publicKeyPoint.length - 1) / 2);
|
|
13285
|
+
const x = publicKeyPoint.slice(1, 1 + coordLength);
|
|
13286
|
+
const y = publicKeyPoint.slice(1 + coordLength);
|
|
13287
|
+
const jwk = {
|
|
13288
|
+
kty: 'EC',
|
|
13289
|
+
crv: this.namedCurve,
|
|
13290
|
+
x: buildExports.Convert.ToBase64Url(x),
|
|
13291
|
+
y: buildExports.Convert.ToBase64Url(y),
|
|
13292
|
+
d: buildExports.Convert.ToBase64Url(privateKeyValue),
|
|
13293
|
+
};
|
|
13294
|
+
return crypto.subtle.importKey('jwk', jwk, {
|
|
13295
|
+
name: 'ECDSA',
|
|
13296
|
+
namedCurve: this.namedCurve,
|
|
13297
|
+
}, true, ['sign']);
|
|
13298
|
+
}
|
|
13299
|
+
async sign(params) {
|
|
13300
|
+
const { privateKey, data, crypto, hash } = params;
|
|
13301
|
+
const expectedHash = this.getHashAlgorithm();
|
|
13302
|
+
if (hash && hash !== expectedHash) {
|
|
13303
|
+
throw new InvalidKeyDataError(`ECDSA ${this.namedCurve} requires ${expectedHash}, got ${hash}`);
|
|
13304
|
+
}
|
|
13305
|
+
const signature = await crypto.subtle.sign({
|
|
13306
|
+
name: 'ECDSA',
|
|
13307
|
+
hash: expectedHash,
|
|
13308
|
+
}, privateKey, data);
|
|
13309
|
+
return buildExports.BufferSourceConverter.toUint8Array(signature);
|
|
13310
|
+
}
|
|
13311
|
+
async verify(params) {
|
|
13312
|
+
const { publicKey, signature, data, crypto, hash } = params;
|
|
13313
|
+
const expectedHash = this.getHashAlgorithm();
|
|
13314
|
+
if (hash && hash !== expectedHash) {
|
|
13315
|
+
throw new InvalidKeyDataError(`ECDSA ${this.namedCurve} requires ${expectedHash}, got ${hash}`);
|
|
13316
|
+
}
|
|
13317
|
+
return crypto.subtle.verify({
|
|
13318
|
+
name: 'ECDSA',
|
|
13319
|
+
hash: expectedHash,
|
|
13320
|
+
}, publicKey, signature, data);
|
|
13321
|
+
}
|
|
13322
|
+
encodeSignature(params) {
|
|
13323
|
+
const { signature, algo } = params;
|
|
13324
|
+
if (algo.startsWith('ecdsa-sha2-')) {
|
|
13325
|
+
const coordLength = this.getSignatureCoordLength();
|
|
13326
|
+
const r = signature.subarray(0, coordLength);
|
|
13327
|
+
const s = signature.subarray(coordLength);
|
|
13328
|
+
const writer = new SshWriter();
|
|
13329
|
+
writer.writeString(algo);
|
|
13330
|
+
const sigWriter = new SshWriter();
|
|
13331
|
+
sigWriter.writeMpInt(r, true);
|
|
13332
|
+
sigWriter.writeMpInt(s, true);
|
|
13333
|
+
const sigData = sigWriter.toUint8Array();
|
|
13334
|
+
writer.writeUint32(sigData.length);
|
|
13335
|
+
writer.writeBytes(sigData);
|
|
13336
|
+
return writer.toUint8Array();
|
|
13337
|
+
}
|
|
13338
|
+
const writer = new SshWriter();
|
|
13339
|
+
writer.writeString(algo);
|
|
13340
|
+
writer.writeUint32(signature.byteLength);
|
|
13341
|
+
writer.writeBytes(signature);
|
|
13342
|
+
return writer.toUint8Array();
|
|
13343
|
+
}
|
|
13344
|
+
decodeSignature(params) {
|
|
13345
|
+
const { signature } = params;
|
|
13346
|
+
const reader = new SshReader(signature);
|
|
13347
|
+
const algo = reader.readString();
|
|
13348
|
+
const sigLength = reader.readUint32();
|
|
13349
|
+
const sig = reader.readBytes(sigLength);
|
|
13350
|
+
if (algo.startsWith('ecdsa-sha2-')) {
|
|
13351
|
+
const sigReader = new SshReader(sig);
|
|
13352
|
+
let r = sigReader.readMpInt();
|
|
13353
|
+
let s = sigReader.readMpInt();
|
|
13354
|
+
if (r[0] === 0x00 && r.length > 1 && (r[1] & 0x80) === 0) {
|
|
13355
|
+
r = r.slice(1);
|
|
13356
|
+
}
|
|
13357
|
+
if (s[0] === 0x00 && s.length > 1 && (s[1] & 0x80) === 0) {
|
|
13358
|
+
s = s.slice(1);
|
|
13359
|
+
}
|
|
13360
|
+
const expectedLength = this.getExpectedLength();
|
|
13361
|
+
const rPadded = new Uint8Array(expectedLength);
|
|
13362
|
+
const sPadded = new Uint8Array(expectedLength);
|
|
13363
|
+
if (r.length <= expectedLength) {
|
|
13364
|
+
rPadded.set(r, expectedLength - r.length);
|
|
13365
|
+
}
|
|
13366
|
+
else {
|
|
13367
|
+
rPadded.set(r.slice(r.length - expectedLength), 0);
|
|
13368
|
+
}
|
|
13369
|
+
if (s.length <= expectedLength) {
|
|
13370
|
+
sPadded.set(s, expectedLength - s.length);
|
|
13371
|
+
}
|
|
13372
|
+
else {
|
|
13373
|
+
sPadded.set(s.slice(s.length - expectedLength), 0);
|
|
13374
|
+
}
|
|
13375
|
+
const rawSignature = new Uint8Array([...rPadded, ...sPadded]);
|
|
13376
|
+
return { signature: rawSignature, algo };
|
|
13377
|
+
}
|
|
13378
|
+
return { signature: sig, algo };
|
|
13379
|
+
}
|
|
13380
|
+
supportsCryptoKey(cryptoKey) {
|
|
13381
|
+
return (cryptoKey.algorithm.name === 'ECDSA' &&
|
|
13382
|
+
cryptoKey.algorithm.namedCurve === this.namedCurve);
|
|
13383
|
+
}
|
|
13384
|
+
parsePublicKey(reader) {
|
|
13385
|
+
const curveName = reader.readString();
|
|
13386
|
+
if (curveName !== this.curveName) {
|
|
13387
|
+
throw new InvalidKeyDataError(`ECDSA certificate curve name ${curveName}, expected ${this.curveName}`);
|
|
13388
|
+
}
|
|
13389
|
+
const publicKeyPoint = reader.readBytes(reader.readUint32());
|
|
13390
|
+
const writer = new SshWriter();
|
|
13391
|
+
writer.writeString(this.sshType);
|
|
13392
|
+
writer.writeString(curveName);
|
|
13393
|
+
writer.writeMpInt(publicKeyPoint);
|
|
13394
|
+
return {
|
|
13395
|
+
type: this.sshType,
|
|
13396
|
+
keyData: writer.toUint8Array(),
|
|
13397
|
+
};
|
|
13398
|
+
}
|
|
13399
|
+
writePublicKey(writer, publicKey) {
|
|
13400
|
+
const publicKeyReader = new SshReader(publicKey.keyData);
|
|
13401
|
+
publicKeyReader.readString();
|
|
13402
|
+
const curveName = publicKeyReader.readString();
|
|
13403
|
+
const publicPoint = publicKeyReader.readMpInt();
|
|
13404
|
+
writer.writeString(curveName);
|
|
13405
|
+
writer.writeUint32(publicPoint.length);
|
|
13406
|
+
writer.writeBytes(publicPoint);
|
|
13407
|
+
}
|
|
13408
|
+
getCertificateType() {
|
|
13409
|
+
return `${this.sshType}-cert-v01@openssh.com`;
|
|
13410
|
+
}
|
|
13411
|
+
getSignatureAlgo() {
|
|
13412
|
+
return this.sshType;
|
|
13413
|
+
}
|
|
13414
|
+
}
|
|
13415
|
+
const EcdsaP256Binding = new EcdsaBinding('nistp256', 'ecdsa-sha2-nistp256', 'P-256');
|
|
13416
|
+
const EcdsaP384Binding = new EcdsaBinding('nistp384', 'ecdsa-sha2-nistp384', 'P-384');
|
|
13417
|
+
const EcdsaP521Binding = new EcdsaBinding('nistp521', 'ecdsa-sha2-nistp521', 'P-521');
|
|
13418
|
+
|
|
13419
|
+
class Ed25519Binding {
|
|
13420
|
+
async importPublicSsh(params) {
|
|
13421
|
+
const { blob, crypto } = params;
|
|
13422
|
+
const reader = new SshReader(blob);
|
|
13423
|
+
reader.readString();
|
|
13424
|
+
const keyLength = reader.readUint32();
|
|
13425
|
+
if (keyLength !== 32) {
|
|
13426
|
+
throw new InvalidKeyDataError(`Ed25519 key length ${keyLength}, expected 32`);
|
|
13427
|
+
}
|
|
13428
|
+
const publicKeyBytes = reader.readBytes(keyLength);
|
|
13429
|
+
return crypto.subtle.importKey('raw', publicKeyBytes, 'Ed25519', true, [
|
|
13430
|
+
'verify',
|
|
13431
|
+
]);
|
|
13432
|
+
}
|
|
13433
|
+
async exportPublicSsh(params) {
|
|
13434
|
+
const { publicKey, crypto } = params;
|
|
13435
|
+
const jwk = await crypto.subtle.exportKey('jwk', publicKey);
|
|
13436
|
+
if (!jwk.x) {
|
|
13437
|
+
throw new InvalidKeyDataError('Ed25519 JWK missing x parameter');
|
|
13438
|
+
}
|
|
13439
|
+
const keyBytes = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.x));
|
|
13440
|
+
const writer = new SshWriter();
|
|
13441
|
+
writer.writeString('ssh-ed25519');
|
|
13442
|
+
writer.writeUint32(keyBytes.length);
|
|
13443
|
+
writer.writeBytes(keyBytes);
|
|
13444
|
+
return writer.toUint8Array();
|
|
13445
|
+
}
|
|
13446
|
+
async importPublicSpki(params) {
|
|
13447
|
+
const { spki, crypto } = params;
|
|
13448
|
+
return crypto.subtle.importKey('spki', spki, 'Ed25519', true, ['verify']);
|
|
13449
|
+
}
|
|
13450
|
+
async exportPublicSpki(params) {
|
|
13451
|
+
const { publicKey, crypto } = params;
|
|
13452
|
+
const spki = await crypto.subtle.exportKey('spki', publicKey);
|
|
13453
|
+
return buildExports.BufferSourceConverter.toUint8Array(spki);
|
|
13454
|
+
}
|
|
13455
|
+
async importPrivatePkcs8(params) {
|
|
13456
|
+
const { pkcs8, crypto } = params;
|
|
13457
|
+
return crypto.subtle.importKey('pkcs8', pkcs8, 'Ed25519', true, ['sign']);
|
|
13458
|
+
}
|
|
13459
|
+
async exportPrivatePkcs8(params) {
|
|
13460
|
+
const { privateKey, crypto } = params;
|
|
13461
|
+
const pkcs8 = await crypto.subtle.exportKey('pkcs8', privateKey);
|
|
13462
|
+
return buildExports.BufferSourceConverter.toUint8Array(pkcs8);
|
|
13463
|
+
}
|
|
13464
|
+
async exportPrivateSsh(params) {
|
|
13465
|
+
const { privateKey, crypto, jwk: providedJwk } = params;
|
|
13466
|
+
const jwk = providedJwk || (await crypto.subtle.exportKey('jwk', privateKey));
|
|
13467
|
+
if (!jwk.d || !jwk.x) {
|
|
13468
|
+
throw new InvalidKeyDataError('Ed25519 private key JWK missing required parameters');
|
|
13469
|
+
}
|
|
13470
|
+
const privateBytes = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.d));
|
|
13471
|
+
const publicBytes = new Uint8Array(buildExports.Convert.FromBase64Url(jwk.x));
|
|
13472
|
+
const writer = new SshWriter();
|
|
13473
|
+
writer.writeString('ssh-ed25519');
|
|
13474
|
+
writer.writeUint32(publicBytes.length);
|
|
13475
|
+
writer.writeBytes(publicBytes);
|
|
13476
|
+
const privKeyPart = new Uint8Array(64);
|
|
13477
|
+
privKeyPart.set(privateBytes, 0);
|
|
13478
|
+
privKeyPart.set(publicBytes, 32);
|
|
13479
|
+
writer.writeUint32(privKeyPart.length);
|
|
13480
|
+
writer.writeBytes(privKeyPart);
|
|
13481
|
+
return writer.toUint8Array();
|
|
13482
|
+
}
|
|
13483
|
+
async importPrivateSsh(params) {
|
|
13484
|
+
const { sshKey, crypto } = params;
|
|
13485
|
+
const base64Data = sshKey
|
|
13486
|
+
.replace(/-----BEGIN OPENSSH PRIVATE KEY-----/, '')
|
|
13487
|
+
.replace(/-----END OPENSSH PRIVATE KEY-----/, '')
|
|
13488
|
+
.replace(/\s/g, '');
|
|
13489
|
+
const binaryData = buildExports.Convert.FromBase64(base64Data);
|
|
13490
|
+
const reader = new SshReader(buildExports.BufferSourceConverter.toUint8Array(binaryData));
|
|
13491
|
+
const magic = reader.readBytes(15);
|
|
13492
|
+
if (buildExports.Convert.ToHex(magic) !== '6f70656e7373682d6b65792d763100') {
|
|
13493
|
+
throw new InvalidPrivateKeyFormatError('invalid magic string');
|
|
13494
|
+
}
|
|
13495
|
+
const _cipherName = reader.readString();
|
|
13496
|
+
reader.readString();
|
|
13497
|
+
reader.readString();
|
|
13498
|
+
if (_cipherName !== 'none') {
|
|
13499
|
+
throw new EncryptedKeyNotSupportedError(_cipherName);
|
|
13500
|
+
}
|
|
13501
|
+
const numKeys = reader.readUint32();
|
|
13502
|
+
if (numKeys !== 1) {
|
|
13503
|
+
throw new InvalidPrivateKeyFormatError('multiple keys not supported');
|
|
13504
|
+
}
|
|
13505
|
+
const publicKeyLength = reader.readUint32();
|
|
13506
|
+
reader.readBytes(publicKeyLength);
|
|
13507
|
+
const privateKeyLength = reader.readUint32();
|
|
13508
|
+
const privateKeyData = reader.readBytes(privateKeyLength);
|
|
13509
|
+
const privateReader = new SshReader(privateKeyData);
|
|
13510
|
+
const checkint1 = privateReader.readUint32();
|
|
13511
|
+
const checkint2 = privateReader.readUint32();
|
|
13512
|
+
if (checkint1 !== checkint2) {
|
|
13513
|
+
throw new InvalidPrivateKeyFormatError('invalid checkints');
|
|
13514
|
+
}
|
|
13515
|
+
privateReader.readString();
|
|
13516
|
+
const pubKeyLength = privateReader.readUint32();
|
|
13517
|
+
const _publicKeyBytes = privateReader.readBytes(pubKeyLength);
|
|
13518
|
+
const privKeyLength = privateReader.readUint32();
|
|
13519
|
+
const privateKeyBytes = privateReader.readBytes(privKeyLength);
|
|
13520
|
+
privateReader.readString();
|
|
13521
|
+
const privateKey = privateKeyBytes.slice(0, 32);
|
|
13522
|
+
const jwk = {
|
|
13523
|
+
kty: 'OKP',
|
|
13524
|
+
crv: 'Ed25519',
|
|
13525
|
+
d: buildExports.Convert.ToBase64Url(privateKey),
|
|
13526
|
+
x: buildExports.Convert.ToBase64Url(_publicKeyBytes),
|
|
13527
|
+
};
|
|
13528
|
+
return crypto.subtle.importKey('jwk', jwk, 'Ed25519', true, ['sign']);
|
|
13529
|
+
}
|
|
13530
|
+
async sign(params) {
|
|
13531
|
+
const { privateKey, data, crypto } = params;
|
|
13532
|
+
const signature = await crypto.subtle.sign('Ed25519', privateKey, data);
|
|
13533
|
+
return buildExports.BufferSourceConverter.toUint8Array(signature);
|
|
13534
|
+
}
|
|
13535
|
+
async verify(params) {
|
|
13536
|
+
const { publicKey, signature, data, crypto } = params;
|
|
13537
|
+
return crypto.subtle.verify('Ed25519', publicKey, signature, data);
|
|
13538
|
+
}
|
|
13539
|
+
encodeSignature(params) {
|
|
13540
|
+
const { signature, algo } = params;
|
|
13541
|
+
const sigBytes = new Uint8Array(signature);
|
|
13542
|
+
const writer = new SshWriter();
|
|
13543
|
+
writer.writeString(algo);
|
|
13544
|
+
writer.writeUint32(sigBytes.length);
|
|
13545
|
+
writer.writeBytes(sigBytes);
|
|
13546
|
+
return writer.toUint8Array();
|
|
13547
|
+
}
|
|
13548
|
+
decodeSignature(params) {
|
|
13549
|
+
const { signature } = params;
|
|
13550
|
+
const reader = new SshReader(signature);
|
|
13551
|
+
const algo = reader.readString();
|
|
13552
|
+
const sigLength = reader.readUint32();
|
|
13553
|
+
const sigBytes = reader.readBytes(sigLength);
|
|
13554
|
+
return {
|
|
13555
|
+
signature: sigBytes,
|
|
13556
|
+
algo,
|
|
13557
|
+
};
|
|
13558
|
+
}
|
|
13559
|
+
supportsCryptoKey(cryptoKey) {
|
|
13560
|
+
return cryptoKey.algorithm.name === 'Ed25519';
|
|
13561
|
+
}
|
|
13562
|
+
parsePublicKey(reader) {
|
|
13563
|
+
const publicKeyData = reader.readBytes(reader.readUint32());
|
|
13564
|
+
const writer = new SshWriter();
|
|
13565
|
+
writer.writeString('ssh-ed25519');
|
|
13566
|
+
writer.writeUint32(publicKeyData.length);
|
|
13567
|
+
writer.writeBytes(publicKeyData);
|
|
13568
|
+
return {
|
|
13569
|
+
type: 'ssh-ed25519',
|
|
13570
|
+
keyData: writer.toUint8Array(),
|
|
13571
|
+
};
|
|
13572
|
+
}
|
|
13573
|
+
writePublicKey(writer, publicKey) {
|
|
13574
|
+
const publicKeyReader = new SshReader(publicKey.keyData);
|
|
13575
|
+
publicKeyReader.readString();
|
|
13576
|
+
const keyLength = publicKeyReader.readUint32();
|
|
13577
|
+
const rawKeyData = publicKeyReader.readBytes(keyLength);
|
|
13578
|
+
writer.writeUint32(rawKeyData.length);
|
|
13579
|
+
writer.writeBytes(rawKeyData);
|
|
13580
|
+
}
|
|
13581
|
+
getCertificateType() {
|
|
13582
|
+
return 'ssh-ed25519-cert-v01@openssh.com';
|
|
13583
|
+
}
|
|
13584
|
+
getSignatureAlgo() {
|
|
13585
|
+
return 'ssh-ed25519';
|
|
13586
|
+
}
|
|
13587
|
+
}
|
|
13588
|
+
|
|
13589
|
+
const registry = new Map();
|
|
13590
|
+
class AlgorithmRegistry {
|
|
13591
|
+
static get(name) {
|
|
13592
|
+
const binding = registry.get(name);
|
|
13593
|
+
if (!binding) {
|
|
13594
|
+
throw new UnsupportedKeyTypeError(name, Array.from(registry.keys()));
|
|
13595
|
+
}
|
|
13596
|
+
return binding;
|
|
13597
|
+
}
|
|
13598
|
+
static register(name, binding) {
|
|
13599
|
+
registry.set(name, binding);
|
|
13600
|
+
}
|
|
13601
|
+
static getSshTypeFromCryptoKey(cryptoKey) {
|
|
13602
|
+
for (const [sshType, binding] of registry.entries()) {
|
|
13603
|
+
if (binding.supportsCryptoKey(cryptoKey)) {
|
|
13604
|
+
return sshType;
|
|
13605
|
+
}
|
|
13606
|
+
}
|
|
13607
|
+
throw new UnsupportedKeyTypeError(cryptoKey.algorithm.name, Array.from(registry.keys()));
|
|
13608
|
+
}
|
|
13609
|
+
static certTypeToKeyType(certType) {
|
|
13610
|
+
const mapping = {
|
|
13611
|
+
'ssh-rsa-cert-v01@openssh.com': 'ssh-rsa',
|
|
13612
|
+
'ssh-ed25519-cert-v01@openssh.com': 'ssh-ed25519',
|
|
13613
|
+
'ecdsa-sha2-nistp256-cert-v01@openssh.com': 'ecdsa-sha2-nistp256',
|
|
13614
|
+
'ecdsa-sha2-nistp384-cert-v01@openssh.com': 'ecdsa-sha2-nistp384',
|
|
13615
|
+
'ecdsa-sha2-nistp521-cert-v01@openssh.com': 'ecdsa-sha2-nistp521',
|
|
13616
|
+
};
|
|
13617
|
+
return mapping[certType];
|
|
13618
|
+
}
|
|
13619
|
+
static getSupportedCertTypes() {
|
|
13620
|
+
return Object.keys({
|
|
13621
|
+
'ssh-rsa-cert-v01@openssh.com': 'ssh-rsa',
|
|
13622
|
+
'ssh-ed25519-cert-v01@openssh.com': 'ssh-ed25519',
|
|
13623
|
+
'ecdsa-sha2-nistp256-cert-v01@openssh.com': 'ecdsa-sha2-nistp256',
|
|
13624
|
+
'ecdsa-sha2-nistp384-cert-v01@openssh.com': 'ecdsa-sha2-nistp384',
|
|
13625
|
+
'ecdsa-sha2-nistp521-cert-v01@openssh.com': 'ecdsa-sha2-nistp521',
|
|
13626
|
+
});
|
|
13627
|
+
}
|
|
13628
|
+
}
|
|
13629
|
+
AlgorithmRegistry.register('ssh-ed25519', new Ed25519Binding());
|
|
13630
|
+
AlgorithmRegistry.register('ssh-rsa', new RsaBinding('SHA-256'));
|
|
13631
|
+
AlgorithmRegistry.register('rsa-sha2-256', new RsaBinding('SHA-256'));
|
|
13632
|
+
AlgorithmRegistry.register('rsa-sha2-512', new RsaBinding('SHA-512'));
|
|
13633
|
+
AlgorithmRegistry.register('ecdsa-sha2-nistp256', EcdsaP256Binding);
|
|
13634
|
+
AlgorithmRegistry.register('ecdsa-sha2-nistp384', EcdsaP384Binding);
|
|
13635
|
+
AlgorithmRegistry.register('ecdsa-sha2-nistp521', EcdsaP521Binding);
|
|
13636
|
+
|
|
13637
|
+
function parsePublicKey(input) {
|
|
13638
|
+
const parts = typeof input === 'string' ? input.trim().split(/\s+/) : null;
|
|
13639
|
+
if (!parts || parts.length < 2) {
|
|
13640
|
+
throw new InvalidFormatError('Invalid SSH public key format');
|
|
13641
|
+
}
|
|
13642
|
+
const type = parts[0];
|
|
13643
|
+
const blob = new Uint8Array(buildExports.Convert.FromBase64(parts[1]));
|
|
13644
|
+
const comment = parts.length > 2 ? parts.slice(2).join(' ') : undefined;
|
|
13645
|
+
const reader = new SshReader(blob);
|
|
13646
|
+
const blobType = reader.readString();
|
|
13647
|
+
if (blobType !== type) {
|
|
13648
|
+
throw new InvalidFormatError('Key type mismatch');
|
|
13649
|
+
}
|
|
13650
|
+
return {
|
|
13651
|
+
type,
|
|
13652
|
+
keyData: blob,
|
|
13653
|
+
comment,
|
|
13654
|
+
};
|
|
13655
|
+
}
|
|
13656
|
+
function serializePublicKey(blob) {
|
|
13657
|
+
const base64 = buildExports.Convert.ToBase64(blob.keyData);
|
|
13658
|
+
const parts = [blob.type, base64];
|
|
13659
|
+
if (blob.comment) {
|
|
13660
|
+
parts.push(blob.comment);
|
|
13661
|
+
}
|
|
13662
|
+
return parts.join(' ');
|
|
13663
|
+
}
|
|
13664
|
+
|
|
13665
|
+
function parse(input) {
|
|
13666
|
+
if (typeof input === 'string') {
|
|
13667
|
+
const parts = input.trim().split(/\s+/);
|
|
13668
|
+
if (parts.length < 2) {
|
|
13669
|
+
throw new InvalidFormatError('SSH certificate string', 'type base64 [comment]');
|
|
13670
|
+
}
|
|
13671
|
+
const type = parts[0];
|
|
13672
|
+
const blob = new Uint8Array(buildExports.Convert.FromBase64(parts[1]));
|
|
13673
|
+
const comment = parts.length > 2 ? parts.slice(2).join(' ') : undefined;
|
|
13674
|
+
const reader = new SshReader(blob);
|
|
13675
|
+
const blobType = reader.readString();
|
|
13676
|
+
if (blobType !== type) {
|
|
13677
|
+
throw new InvalidFormatError(`certificate blob type ${blobType}`, `expected ${type}`);
|
|
13678
|
+
}
|
|
13679
|
+
return {
|
|
13680
|
+
type,
|
|
13681
|
+
keyData: blob,
|
|
13682
|
+
comment,
|
|
13683
|
+
};
|
|
13684
|
+
}
|
|
13685
|
+
else {
|
|
13686
|
+
const reader = new SshReader(input);
|
|
13687
|
+
const type = reader.readString();
|
|
13688
|
+
const keyData = input.slice(reader.getOffset());
|
|
13689
|
+
return {
|
|
13690
|
+
type,
|
|
13691
|
+
keyData,
|
|
13692
|
+
};
|
|
13693
|
+
}
|
|
13694
|
+
}
|
|
13695
|
+
function parseCertificateData(keyData) {
|
|
13696
|
+
const reader = new SshReader(keyData);
|
|
13697
|
+
const certType = reader.readString();
|
|
13698
|
+
const nonce = reader.readBytes(reader.readUint32());
|
|
13699
|
+
const mappedKeyType = AlgorithmRegistry.certTypeToKeyType(certType);
|
|
13700
|
+
if (!mappedKeyType) {
|
|
13701
|
+
throw new UnsupportedAlgorithmError(certType, AlgorithmRegistry.getSupportedCertTypes());
|
|
13702
|
+
}
|
|
13703
|
+
const binding = AlgorithmRegistry.get(mappedKeyType);
|
|
13704
|
+
const publicKey = binding.parsePublicKey(reader);
|
|
13705
|
+
const keyType = mappedKeyType;
|
|
13706
|
+
const serial = reader.readUint64();
|
|
13707
|
+
const typeValue = reader.readUint32();
|
|
13708
|
+
const type = typeValue === 1 ? 'user' : 'host';
|
|
13709
|
+
const keyId = reader.readString();
|
|
13710
|
+
const principalsLength = reader.readUint32();
|
|
13711
|
+
const principalsData = reader.readBytes(principalsLength);
|
|
13712
|
+
const validPrincipals = [];
|
|
13713
|
+
if (principalsData.length > 0) {
|
|
13714
|
+
const principalsReader = new SshReader(principalsData);
|
|
13715
|
+
while (principalsReader.getOffset() < principalsData.length) {
|
|
13716
|
+
try {
|
|
13717
|
+
const principal = principalsReader.readString();
|
|
13718
|
+
validPrincipals.push(principal);
|
|
13719
|
+
}
|
|
13720
|
+
catch {
|
|
13721
|
+
break;
|
|
13722
|
+
}
|
|
13723
|
+
}
|
|
13724
|
+
}
|
|
13725
|
+
const validAfter = reader.readUint64();
|
|
13726
|
+
const validBefore = reader.readUint64();
|
|
13727
|
+
const criticalOptions = {};
|
|
13728
|
+
const criticalLength = reader.readUint32();
|
|
13729
|
+
const criticalData = reader.readBytes(criticalLength);
|
|
13730
|
+
if (criticalData.length > 0) {
|
|
13731
|
+
const optionsReader = new SshReader(criticalData);
|
|
13732
|
+
while (optionsReader.getOffset() < criticalData.length) {
|
|
13733
|
+
try {
|
|
13734
|
+
const name = optionsReader.readString();
|
|
13735
|
+
const valueData = optionsReader.readBytes(optionsReader.readUint32());
|
|
13736
|
+
const value = valueData.length === 0 ? '' : decoder.decode(valueData);
|
|
13737
|
+
criticalOptions[name] = value;
|
|
13738
|
+
}
|
|
13739
|
+
catch {
|
|
13740
|
+
break;
|
|
13741
|
+
}
|
|
13742
|
+
}
|
|
13743
|
+
}
|
|
13744
|
+
const extensions = {};
|
|
13745
|
+
const extensionsLength = reader.readUint32();
|
|
13746
|
+
const extensionsData = reader.readBytes(extensionsLength);
|
|
13747
|
+
if (extensionsData.length > 0) {
|
|
13748
|
+
const extReader = new SshReader(extensionsData);
|
|
13749
|
+
while (extReader.getOffset() < extensionsData.length) {
|
|
13750
|
+
try {
|
|
13751
|
+
const name = extReader.readString();
|
|
13752
|
+
const valueData = extReader.readBytes(extReader.readUint32());
|
|
13753
|
+
const value = valueData.length === 0 ? '' : decoder.decode(valueData);
|
|
13754
|
+
extensions[name] = value;
|
|
13755
|
+
}
|
|
13756
|
+
catch {
|
|
13757
|
+
break;
|
|
13758
|
+
}
|
|
13759
|
+
}
|
|
13760
|
+
}
|
|
13761
|
+
const reservedLength = reader.readUint32();
|
|
13762
|
+
const reserved = reader.readBytes(reservedLength);
|
|
13763
|
+
const signatureKeyLength = reader.readUint32();
|
|
13764
|
+
const signatureKeyData = reader.readBytes(signatureKeyLength);
|
|
13765
|
+
const signatureKeyReader = new SshReader(signatureKeyData);
|
|
13766
|
+
const signatureKeyType = signatureKeyReader.readString();
|
|
13767
|
+
const signatureKey = {
|
|
13768
|
+
type: signatureKeyType,
|
|
13769
|
+
keyData: signatureKeyData,
|
|
13770
|
+
};
|
|
13771
|
+
const signatureLength = reader.readUint32();
|
|
13772
|
+
const signature = reader.readBytes(signatureLength);
|
|
13773
|
+
return {
|
|
13774
|
+
nonce,
|
|
13775
|
+
keyType,
|
|
13776
|
+
publicKey,
|
|
13777
|
+
serial,
|
|
13778
|
+
type,
|
|
13779
|
+
keyId,
|
|
13780
|
+
validPrincipals,
|
|
13781
|
+
validAfter,
|
|
13782
|
+
validBefore,
|
|
13783
|
+
criticalOptions,
|
|
13784
|
+
extensions,
|
|
13785
|
+
reserved,
|
|
13786
|
+
signatureKey,
|
|
13787
|
+
signature,
|
|
13788
|
+
};
|
|
13789
|
+
}
|
|
13790
|
+
function serialize(cert) {
|
|
13791
|
+
const base64 = buildExports.Convert.ToBase64(cert.keyData);
|
|
13792
|
+
const parts = [cert.type, base64];
|
|
13793
|
+
if (cert.comment) {
|
|
13794
|
+
parts.push(cert.comment);
|
|
13795
|
+
}
|
|
13796
|
+
return parts.join(' ');
|
|
13797
|
+
}
|
|
13798
|
+
|
|
13799
|
+
function parseSignature(data) {
|
|
13800
|
+
const reader = new SshReader(data);
|
|
13801
|
+
if (data.length >= 6 && new TextDecoder().decode(data.subarray(0, 6)) === 'SSHSIG') {
|
|
13802
|
+
return parseSshSignatureFormat(reader);
|
|
13803
|
+
}
|
|
13804
|
+
else {
|
|
13805
|
+
return parseLegacyFormat(reader);
|
|
13806
|
+
}
|
|
13807
|
+
}
|
|
13808
|
+
function parseSshSignatureFormat(reader) {
|
|
13809
|
+
const magicBytes = reader.readBytes(6);
|
|
13810
|
+
const magic = new TextDecoder().decode(magicBytes);
|
|
13811
|
+
if (magic !== 'SSHSIG') {
|
|
13812
|
+
throw new InvalidFormatError(magic, 'SSHSIG');
|
|
13813
|
+
}
|
|
13814
|
+
const version = reader.readUint32();
|
|
13815
|
+
const publicKeyLength = reader.readUint32();
|
|
13816
|
+
const publicKey = reader.readBytes(publicKeyLength);
|
|
13817
|
+
const namespace = reader.readString();
|
|
13818
|
+
const reserved = reader.readString();
|
|
13819
|
+
const hashAlgorithm = reader.readString();
|
|
13820
|
+
const signatureLength = reader.readUint32();
|
|
13821
|
+
const signatureData = reader.readBytes(signatureLength);
|
|
13822
|
+
const sigReader = new SshReader(signatureData);
|
|
13823
|
+
const algorithm = sigReader.readString();
|
|
13824
|
+
const signatureLength2 = sigReader.readUint32();
|
|
13825
|
+
const signature = sigReader.readBytes(signatureLength2);
|
|
13826
|
+
return {
|
|
13827
|
+
format: 'ssh-signature',
|
|
13828
|
+
algorithm,
|
|
13829
|
+
signature,
|
|
13830
|
+
version,
|
|
13831
|
+
publicKey,
|
|
13832
|
+
namespace,
|
|
13833
|
+
reserved,
|
|
13834
|
+
hashAlgorithm,
|
|
13835
|
+
};
|
|
13836
|
+
}
|
|
13837
|
+
function parseLegacyFormat(reader) {
|
|
13838
|
+
const algorithm = reader.readString();
|
|
13839
|
+
const signatureLength = reader.readUint32();
|
|
13840
|
+
const signature = reader.readBytes(signatureLength);
|
|
13841
|
+
return {
|
|
13842
|
+
format: 'legacy',
|
|
13843
|
+
algorithm,
|
|
13844
|
+
signature,
|
|
13845
|
+
};
|
|
13846
|
+
}
|
|
13847
|
+
function serializeSignature(blob) {
|
|
13848
|
+
if (blob.format === 'ssh-signature') {
|
|
13849
|
+
return serializeSshSignatureFormat(blob);
|
|
13850
|
+
}
|
|
13851
|
+
else {
|
|
13852
|
+
return serializeLegacyFormat(blob);
|
|
13853
|
+
}
|
|
13854
|
+
}
|
|
13855
|
+
function serializeSshSignatureFormat(blob) {
|
|
13856
|
+
const writer = new SshWriter();
|
|
13857
|
+
writer.writeBytes(new TextEncoder().encode('SSHSIG'));
|
|
13858
|
+
writer.writeUint32(blob.version || 1);
|
|
13859
|
+
if (blob.publicKey) {
|
|
13860
|
+
writer.writeUint32(blob.publicKey.length);
|
|
13861
|
+
writer.writeBytes(blob.publicKey);
|
|
13862
|
+
}
|
|
13863
|
+
else {
|
|
13864
|
+
writer.writeUint32(0);
|
|
13865
|
+
}
|
|
13866
|
+
writer.writeString(blob.namespace || 'file');
|
|
13867
|
+
writer.writeString(blob.reserved || '');
|
|
13868
|
+
writer.writeString(blob.hashAlgorithm || 'sha512');
|
|
13869
|
+
const sigWriter = new SshWriter();
|
|
13870
|
+
sigWriter.writeString(blob.algorithm);
|
|
13871
|
+
sigWriter.writeUint32(blob.signature.length);
|
|
13872
|
+
sigWriter.writeBytes(blob.signature);
|
|
13873
|
+
const sigData = sigWriter.toUint8Array();
|
|
13874
|
+
writer.writeUint32(sigData.length);
|
|
13875
|
+
writer.writeBytes(sigData);
|
|
13876
|
+
return writer.toUint8Array();
|
|
13877
|
+
}
|
|
13878
|
+
function serializeLegacyFormat(blob) {
|
|
13879
|
+
const writer = new SshWriter();
|
|
13880
|
+
writer.writeString(blob.algorithm);
|
|
13881
|
+
writer.writeUint32(blob.signature.length);
|
|
13882
|
+
writer.writeBytes(blob.signature);
|
|
13883
|
+
return writer.toUint8Array();
|
|
13884
|
+
}
|
|
13885
|
+
|
|
13886
|
+
class SshObject {
|
|
13887
|
+
}
|
|
13888
|
+
|
|
13889
|
+
class SshPublicKey extends SshObject {
|
|
13890
|
+
static TYPE = 'public-key';
|
|
13891
|
+
type = SshPublicKey.TYPE;
|
|
13892
|
+
blob;
|
|
13893
|
+
cachedCryptoKey;
|
|
13894
|
+
constructor(blob) {
|
|
13895
|
+
super();
|
|
13896
|
+
this.blob = blob;
|
|
13897
|
+
}
|
|
13898
|
+
async getCryptoKey(crypto = getCrypto()) {
|
|
13899
|
+
if (!this.cachedCryptoKey) {
|
|
13900
|
+
const binding = AlgorithmRegistry.get(this.blob.type);
|
|
13901
|
+
this.cachedCryptoKey = await binding.importPublicSsh({ blob: this.blob.keyData, crypto });
|
|
13902
|
+
}
|
|
13903
|
+
return this.cachedCryptoKey;
|
|
13904
|
+
}
|
|
13905
|
+
static async fromSSH(sshKey, crypto = getCrypto()) {
|
|
13906
|
+
const blob = parsePublicKey(sshKey);
|
|
13907
|
+
const binding = AlgorithmRegistry.get(blob.type);
|
|
13908
|
+
await binding.importPublicSsh({ blob: blob.keyData, crypto });
|
|
13909
|
+
return new SshPublicKey(blob);
|
|
13910
|
+
}
|
|
13911
|
+
static async fromSPKI(spki, type, crypto = getCrypto()) {
|
|
13912
|
+
const binding = AlgorithmRegistry.get(type);
|
|
13913
|
+
const cryptoKey = await binding.importPublicSpki({ spki, crypto });
|
|
13914
|
+
const exported = await binding.exportPublicSsh({ publicKey: cryptoKey, crypto });
|
|
13915
|
+
const blob = {
|
|
13916
|
+
type,
|
|
13917
|
+
keyData: exported,
|
|
13918
|
+
};
|
|
13919
|
+
return new SshPublicKey(blob);
|
|
13920
|
+
}
|
|
13921
|
+
static async fromWebCrypto(cryptoKey, type, crypto = getCrypto()) {
|
|
13922
|
+
const sshType = type || AlgorithmRegistry.getSshTypeFromCryptoKey(cryptoKey);
|
|
13923
|
+
const binding = AlgorithmRegistry.get(sshType);
|
|
13924
|
+
const exported = await binding.exportPublicSsh({ publicKey: cryptoKey, crypto });
|
|
13925
|
+
const blob = {
|
|
13926
|
+
type: sshType,
|
|
13927
|
+
keyData: exported,
|
|
13928
|
+
};
|
|
13929
|
+
return new SshPublicKey(blob);
|
|
13930
|
+
}
|
|
13931
|
+
async export(format = 'ssh', crypto = getCrypto()) {
|
|
13932
|
+
if (format === 'ssh') {
|
|
13933
|
+
return serializePublicKey(this.blob);
|
|
13934
|
+
}
|
|
13935
|
+
else if (format === 'spki') {
|
|
13936
|
+
const cryptoKey = await this.getCryptoKey(crypto);
|
|
13937
|
+
const binding = AlgorithmRegistry.get(this.blob.type);
|
|
13938
|
+
const spki = await binding.exportPublicSpki({ publicKey: cryptoKey, crypto });
|
|
13939
|
+
return new Uint8Array(spki);
|
|
13940
|
+
}
|
|
13941
|
+
throw new UnsupportedKeyTypeError(`Unsupported export format: ${format}`);
|
|
13942
|
+
}
|
|
13943
|
+
async toSSH() {
|
|
13944
|
+
const result = await this.export('ssh');
|
|
13945
|
+
return result;
|
|
13946
|
+
}
|
|
13947
|
+
async toSPKI() {
|
|
13948
|
+
const result = await this.export('spki');
|
|
13949
|
+
return result;
|
|
13950
|
+
}
|
|
13951
|
+
async toWebCrypto(crypto = getCrypto()) {
|
|
13952
|
+
return this.getCryptoKey(crypto);
|
|
13953
|
+
}
|
|
13954
|
+
async verify(algorithm, signature, data, crypto = getCrypto()) {
|
|
13955
|
+
const binding = AlgorithmRegistry.get(algorithm);
|
|
13956
|
+
const cryptoKey = await this.toWebCrypto(crypto);
|
|
13957
|
+
return binding.verify({
|
|
13958
|
+
publicKey: cryptoKey,
|
|
13959
|
+
signature,
|
|
13960
|
+
data,
|
|
13961
|
+
crypto,
|
|
13962
|
+
});
|
|
13963
|
+
}
|
|
13964
|
+
get keyType() {
|
|
13965
|
+
return this.blob.type;
|
|
13966
|
+
}
|
|
13967
|
+
get comment() {
|
|
13968
|
+
return this.blob.comment;
|
|
13969
|
+
}
|
|
13970
|
+
getBlob() {
|
|
13971
|
+
return { ...this.blob };
|
|
13972
|
+
}
|
|
13973
|
+
async thumbprint(algorithm = 'sha256', crypto = getCrypto()) {
|
|
13974
|
+
const hashAlgorithm = algorithm === 'sha256' ? 'SHA-256' : 'SHA-512';
|
|
13975
|
+
const data = this.blob.keyData;
|
|
13976
|
+
const hash = await crypto.subtle.digest(hashAlgorithm, data);
|
|
13977
|
+
return new Uint8Array(hash);
|
|
13978
|
+
}
|
|
13979
|
+
}
|
|
13980
|
+
|
|
13981
|
+
class SshSignature extends SshObject {
|
|
13982
|
+
static TYPE = 'signature';
|
|
13983
|
+
type = SshSignature.TYPE;
|
|
13984
|
+
blob;
|
|
13985
|
+
format;
|
|
13986
|
+
algorithm;
|
|
13987
|
+
signature;
|
|
13988
|
+
version;
|
|
13989
|
+
publicKey;
|
|
13990
|
+
namespace;
|
|
13991
|
+
reserved;
|
|
13992
|
+
hashAlgorithm;
|
|
13993
|
+
constructor(blob) {
|
|
13994
|
+
super();
|
|
13995
|
+
this.blob = blob;
|
|
13996
|
+
this.format = blob.format;
|
|
13997
|
+
this.algorithm = blob.algorithm;
|
|
13998
|
+
this.signature = blob.signature;
|
|
13999
|
+
this.version = blob.version;
|
|
14000
|
+
this.namespace = blob.namespace;
|
|
14001
|
+
this.reserved = blob.reserved;
|
|
14002
|
+
this.hashAlgorithm = blob.hashAlgorithm;
|
|
14003
|
+
if (blob.publicKey) {
|
|
14004
|
+
const reader = new SshReader(blob.publicKey);
|
|
14005
|
+
const type = reader.readString();
|
|
14006
|
+
this.publicKey = new SshPublicKey({ type, keyData: blob.publicKey });
|
|
14007
|
+
}
|
|
14008
|
+
}
|
|
14009
|
+
static parse(data) {
|
|
14010
|
+
const blob = parseSignature(data);
|
|
14011
|
+
return new SshSignature(blob);
|
|
14012
|
+
}
|
|
14013
|
+
static fromBlob(blob) {
|
|
14014
|
+
return new SshSignature(blob);
|
|
14015
|
+
}
|
|
14016
|
+
static fromBase64(base64) {
|
|
14017
|
+
const data = new Uint8Array(buildExports.Convert.FromBase64(base64));
|
|
14018
|
+
return SshSignature.parse(data);
|
|
14019
|
+
}
|
|
14020
|
+
static fromText(text) {
|
|
14021
|
+
const base64 = text
|
|
14022
|
+
.replace(/-----BEGIN SSH SIGNATURE-----/, '')
|
|
14023
|
+
.replace(/-----END SSH SIGNATURE-----/, '')
|
|
14024
|
+
.replace(/[\r\n\s]/g, '');
|
|
14025
|
+
return SshSignature.fromBase64(base64);
|
|
14026
|
+
}
|
|
14027
|
+
serialize() {
|
|
14028
|
+
return serializeSignature(this.blob);
|
|
14029
|
+
}
|
|
14030
|
+
toBase64() {
|
|
14031
|
+
return buildExports.Convert.ToBase64(this.serialize());
|
|
14032
|
+
}
|
|
14033
|
+
toText() {
|
|
14034
|
+
const base64 = this.toBase64();
|
|
14035
|
+
const lines = [];
|
|
14036
|
+
for (let i = 0; i < base64.length; i += 70) {
|
|
14037
|
+
lines.push(base64.substring(i, i + 70));
|
|
14038
|
+
}
|
|
14039
|
+
return ['-----BEGIN SSH SIGNATURE-----', ...lines, '-----END SSH SIGNATURE-----'].join('\n');
|
|
14040
|
+
}
|
|
14041
|
+
async toSSH() {
|
|
14042
|
+
return this.toText();
|
|
14043
|
+
}
|
|
14044
|
+
async verify(data, publicKey) {
|
|
14045
|
+
const binding = AlgorithmRegistry.get(this.algorithm);
|
|
14046
|
+
const cryptoKey = await publicKey['getCryptoKey']();
|
|
14047
|
+
const crypto = getCrypto();
|
|
14048
|
+
let dataToVerify = data;
|
|
14049
|
+
if (this.format === 'ssh-signature') {
|
|
14050
|
+
const hashAlg = this.hashAlgorithm || 'sha512';
|
|
14051
|
+
const namespace = this.namespace || 'file';
|
|
14052
|
+
const reserved = this.reserved || '';
|
|
14053
|
+
const hashAlgorithm = hashAlg === 'sha256' ? 'SHA-256' : 'SHA-512';
|
|
14054
|
+
const messageHash = await crypto.subtle.digest(hashAlgorithm, data);
|
|
14055
|
+
const messageHashBytes = new Uint8Array(messageHash);
|
|
14056
|
+
const writer = new SshWriter();
|
|
14057
|
+
writer.writeBytes(new TextEncoder().encode('SSHSIG'));
|
|
14058
|
+
writer.writeString(namespace);
|
|
14059
|
+
writer.writeString(reserved);
|
|
14060
|
+
writer.writeString(hashAlg);
|
|
14061
|
+
writer.writeUint32(messageHashBytes.length);
|
|
14062
|
+
writer.writeBytes(messageHashBytes);
|
|
14063
|
+
dataToVerify = writer.toUint8Array();
|
|
14064
|
+
}
|
|
14065
|
+
let hashAlgorithm;
|
|
14066
|
+
if (this.algorithm === 'rsa-sha2-256') {
|
|
14067
|
+
hashAlgorithm = 'SHA-256';
|
|
14068
|
+
}
|
|
14069
|
+
else if (this.algorithm === 'rsa-sha2-512') {
|
|
14070
|
+
hashAlgorithm = 'SHA-512';
|
|
14071
|
+
}
|
|
14072
|
+
let signatureToVerify;
|
|
14073
|
+
if (this.format === 'legacy' || this.format === 'ssh-signature') {
|
|
14074
|
+
const sigWriter = new SshWriter();
|
|
14075
|
+
sigWriter.writeString(this.algorithm);
|
|
14076
|
+
sigWriter.writeUint32(this.signature.length);
|
|
14077
|
+
sigWriter.writeBytes(this.signature);
|
|
14078
|
+
const wireFormatSignature = sigWriter.toUint8Array();
|
|
14079
|
+
const decodedSig = binding.decodeSignature({
|
|
14080
|
+
signature: wireFormatSignature,
|
|
14081
|
+
});
|
|
14082
|
+
signatureToVerify = decodedSig.signature;
|
|
14083
|
+
}
|
|
14084
|
+
else {
|
|
14085
|
+
signatureToVerify = this.signature;
|
|
14086
|
+
}
|
|
14087
|
+
return binding.verify({
|
|
14088
|
+
publicKey: cryptoKey,
|
|
14089
|
+
signature: signatureToVerify,
|
|
14090
|
+
data: dataToVerify,
|
|
14091
|
+
crypto,
|
|
14092
|
+
hash: hashAlgorithm,
|
|
14093
|
+
});
|
|
14094
|
+
}
|
|
14095
|
+
static fromLegacy(algorithm, signature) {
|
|
14096
|
+
const binding = AlgorithmRegistry.get(algorithm);
|
|
14097
|
+
const encodedSignature = binding.encodeSignature({
|
|
14098
|
+
signature,
|
|
14099
|
+
algo: algorithm,
|
|
14100
|
+
});
|
|
14101
|
+
const sigReader = new SshReader(encodedSignature);
|
|
14102
|
+
sigReader.readString();
|
|
14103
|
+
const sigLength = sigReader.readUint32();
|
|
14104
|
+
const signatureData = sigReader.readBytes(sigLength);
|
|
14105
|
+
return new SshSignature({
|
|
14106
|
+
format: 'legacy',
|
|
14107
|
+
algorithm,
|
|
14108
|
+
signature: signatureData,
|
|
14109
|
+
});
|
|
14110
|
+
}
|
|
14111
|
+
static fromSshSignature(algorithm, signature, options = {}) {
|
|
14112
|
+
const blob = {
|
|
14113
|
+
format: 'ssh-signature',
|
|
14114
|
+
algorithm,
|
|
14115
|
+
signature,
|
|
14116
|
+
version: options.version || 1,
|
|
14117
|
+
publicKey: options.publicKey ? options.publicKey.getBlob().keyData : undefined,
|
|
14118
|
+
namespace: options.namespace || 'file',
|
|
14119
|
+
reserved: options.reserved || '',
|
|
14120
|
+
hashAlgorithm: options.hashAlgorithm || 'sha512',
|
|
14121
|
+
};
|
|
14122
|
+
return new SshSignature(blob);
|
|
14123
|
+
}
|
|
14124
|
+
static async sign(algorithm, privateKey, data, options = {}) {
|
|
14125
|
+
const { format = 'legacy', namespace = 'file' } = options;
|
|
14126
|
+
if (format === 'legacy') {
|
|
14127
|
+
const rawSignature = await privateKey.sign(algorithm, data);
|
|
14128
|
+
const algorithmUsed = algorithm || privateKey.keyType;
|
|
14129
|
+
return SshSignature.fromLegacy(algorithmUsed, rawSignature);
|
|
14130
|
+
}
|
|
14131
|
+
else {
|
|
14132
|
+
const signatureAlgorithm = algorithm;
|
|
14133
|
+
const binding = AlgorithmRegistry.get(signatureAlgorithm);
|
|
14134
|
+
const hashAlgorithm = algorithm === 'rsa-sha2-256' ? 'sha256' : 'sha512';
|
|
14135
|
+
const publicKey = await privateKey.getPublicKey();
|
|
14136
|
+
const crypto = getCrypto();
|
|
14137
|
+
const webCryptoHashAlg = hashAlgorithm === 'sha256' ? 'SHA-256' : 'SHA-512';
|
|
14138
|
+
const messageHash = await crypto.subtle.digest(webCryptoHashAlg, data);
|
|
14139
|
+
const messageHashBytes = new Uint8Array(messageHash);
|
|
14140
|
+
const writer = new SshWriter();
|
|
14141
|
+
writer.writeBytes(new TextEncoder().encode('SSHSIG'));
|
|
14142
|
+
writer.writeString(namespace);
|
|
14143
|
+
writer.writeString('');
|
|
14144
|
+
writer.writeString(hashAlgorithm);
|
|
14145
|
+
writer.writeUint32(messageHashBytes.length);
|
|
14146
|
+
writer.writeBytes(messageHashBytes);
|
|
14147
|
+
const dataToSign = writer.toUint8Array();
|
|
14148
|
+
const rawSignature = await privateKey.sign(signatureAlgorithm, dataToSign);
|
|
14149
|
+
const encodedSignature = binding.encodeSignature({
|
|
14150
|
+
signature: rawSignature,
|
|
14151
|
+
algo: signatureAlgorithm,
|
|
14152
|
+
});
|
|
14153
|
+
const sigReader = new SshReader(encodedSignature);
|
|
14154
|
+
sigReader.readString();
|
|
14155
|
+
const sigLength = sigReader.readUint32();
|
|
14156
|
+
const signatureData = sigReader.readBytes(sigLength);
|
|
14157
|
+
return SshSignature.fromSshSignature(signatureAlgorithm, signatureData, {
|
|
14158
|
+
namespace,
|
|
14159
|
+
hashAlgorithm,
|
|
14160
|
+
publicKey,
|
|
14161
|
+
});
|
|
14162
|
+
}
|
|
14163
|
+
}
|
|
14164
|
+
}
|
|
14165
|
+
|
|
14166
|
+
let SshCertificate$1 = class SshCertificate extends SshObject {
|
|
14167
|
+
static TYPE = 'certificate';
|
|
14168
|
+
type = SshCertificate.TYPE;
|
|
14169
|
+
_blob;
|
|
14170
|
+
data;
|
|
14171
|
+
_validAfter;
|
|
14172
|
+
_validBefore;
|
|
14173
|
+
keyId;
|
|
14174
|
+
principals;
|
|
14175
|
+
certType;
|
|
14176
|
+
serial;
|
|
14177
|
+
validAfter;
|
|
14178
|
+
validBefore;
|
|
14179
|
+
publicKey;
|
|
14180
|
+
signatureKey;
|
|
14181
|
+
criticalOptions;
|
|
14182
|
+
extensions;
|
|
14183
|
+
constructor(blob) {
|
|
14184
|
+
super();
|
|
14185
|
+
this._blob = blob;
|
|
14186
|
+
this.data = parseCertificateData(blob.keyData);
|
|
14187
|
+
this._validAfter = this.data.validAfter;
|
|
14188
|
+
this._validBefore = this.data.validBefore;
|
|
14189
|
+
this.keyId = this.data.keyId;
|
|
14190
|
+
this.principals = this.data.validPrincipals;
|
|
14191
|
+
this.certType = this.data.type;
|
|
14192
|
+
this.serial = this.data.serial;
|
|
14193
|
+
this.validAfter = new Date(Number(this.data.validAfter) * 1000);
|
|
14194
|
+
this.validBefore = new Date(Number(this.data.validBefore) * 1000);
|
|
14195
|
+
this.publicKey = new SshPublicKey(this.data.publicKey);
|
|
14196
|
+
this.signatureKey = new SshPublicKey(this.data.signatureKey);
|
|
14197
|
+
this.criticalOptions = { ...this.data.criticalOptions };
|
|
14198
|
+
this.extensions = { ...this.data.extensions };
|
|
14199
|
+
}
|
|
14200
|
+
static async fromSSH(text) {
|
|
14201
|
+
const blob = parse(text);
|
|
14202
|
+
return new SshCertificate(blob);
|
|
14203
|
+
}
|
|
14204
|
+
static async fromBlob(blob) {
|
|
14205
|
+
return new SshCertificate(blob);
|
|
14206
|
+
}
|
|
14207
|
+
async toSSH() {
|
|
14208
|
+
return serialize(this._blob);
|
|
14209
|
+
}
|
|
14210
|
+
toBlob() {
|
|
14211
|
+
return { ...this._blob };
|
|
14212
|
+
}
|
|
14213
|
+
get blob() {
|
|
14214
|
+
return this.toBlob();
|
|
14215
|
+
}
|
|
14216
|
+
validate(date = new Date()) {
|
|
14217
|
+
const ts = BigInt(Math.floor(date.getTime() / 1000));
|
|
14218
|
+
const after = this._validAfter;
|
|
14219
|
+
const before = this._validBefore;
|
|
14220
|
+
const INFINITY = 0xffffffffffffffffn;
|
|
14221
|
+
const upper = before === INFINITY ? ts : before;
|
|
14222
|
+
return ts >= after && ts <= upper;
|
|
14223
|
+
}
|
|
14224
|
+
async verify(caPublicKey, crypto = getCrypto()) {
|
|
14225
|
+
const verifyKey = caPublicKey || this.signatureKey;
|
|
14226
|
+
const signedData = this.getSignedData();
|
|
14227
|
+
const sshSignature = SshSignature.parse(this.data.signature);
|
|
14228
|
+
const binding = AlgorithmRegistry.get(sshSignature.algorithm);
|
|
14229
|
+
const cryptoKey = await verifyKey.toWebCrypto(crypto);
|
|
14230
|
+
return binding.verify({
|
|
14231
|
+
publicKey: cryptoKey,
|
|
14232
|
+
signature: sshSignature.signature,
|
|
14233
|
+
data: signedData,
|
|
14234
|
+
crypto,
|
|
14235
|
+
});
|
|
14236
|
+
}
|
|
14237
|
+
getSignedData() {
|
|
14238
|
+
const reader = new SshReader(this._blob.keyData);
|
|
14239
|
+
reader.readString();
|
|
14240
|
+
reader.readBytes(reader.readUint32());
|
|
14241
|
+
if (this.data.keyType === 'ssh-ed25519') {
|
|
14242
|
+
reader.readBytes(reader.readUint32());
|
|
14243
|
+
}
|
|
14244
|
+
else if (this.data.keyType === 'ssh-rsa') {
|
|
14245
|
+
reader.readBytes(reader.readUint32());
|
|
14246
|
+
reader.readBytes(reader.readUint32());
|
|
14247
|
+
}
|
|
14248
|
+
else if (this.data.keyType.startsWith('ecdsa-sha2-')) {
|
|
14249
|
+
reader.readString();
|
|
14250
|
+
reader.readBytes(reader.readUint32());
|
|
14251
|
+
}
|
|
14252
|
+
reader.readUint64();
|
|
14253
|
+
reader.readUint32();
|
|
14254
|
+
reader.readBytes(reader.readUint32());
|
|
14255
|
+
reader.readBytes(reader.readUint32());
|
|
14256
|
+
reader.readUint64();
|
|
14257
|
+
reader.readUint64();
|
|
14258
|
+
reader.readBytes(reader.readUint32());
|
|
14259
|
+
reader.readBytes(reader.readUint32());
|
|
14260
|
+
reader.readBytes(reader.readUint32());
|
|
14261
|
+
reader.readBytes(reader.readUint32());
|
|
14262
|
+
const signedDataEnd = reader.getOffset();
|
|
14263
|
+
return this._blob.keyData.slice(0, signedDataEnd);
|
|
14264
|
+
}
|
|
14265
|
+
};
|
|
14266
|
+
|
|
14267
|
+
var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
14268
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
14269
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
14270
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
14271
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
14272
|
+
};
|
|
14273
|
+
var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
14274
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
14275
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14276
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
14277
|
+
};
|
|
14278
|
+
var _SshCertificate_cert;
|
|
14279
|
+
class SshCertificate {
|
|
14280
|
+
constructor(raw) {
|
|
14281
|
+
_SshCertificate_cert.set(this, void 0);
|
|
14282
|
+
const blob = parse(raw.trim());
|
|
14283
|
+
// @ts-expect-error - SshCertificateType is not a constructor
|
|
14284
|
+
__classPrivateFieldSet(this, _SshCertificate_cert, new SshCertificate$1(blob), "f");
|
|
14285
|
+
this.notBefore = __classPrivateFieldGet(this, _SshCertificate_cert, "f").validAfter;
|
|
14286
|
+
this.notAfter = __classPrivateFieldGet(this, _SshCertificate_cert, "f").validBefore;
|
|
14287
|
+
this.validity = dateDiff(this.notBefore, this.notAfter);
|
|
14288
|
+
this.type = [__classPrivateFieldGet(this, _SshCertificate_cert, "f").blob.type, __classPrivateFieldGet(this, _SshCertificate_cert, "f").certType, __classPrivateFieldGet(this, _SshCertificate_cert, "f").type].join(' ');
|
|
14289
|
+
this.serialNumber = __classPrivateFieldGet(this, _SshCertificate_cert, "f").serial.toString();
|
|
14290
|
+
this.keyId = __classPrivateFieldGet(this, _SshCertificate_cert, "f").keyId;
|
|
14291
|
+
this.principals = __classPrivateFieldGet(this, _SshCertificate_cert, "f").principals;
|
|
14292
|
+
this.extensions = __classPrivateFieldGet(this, _SshCertificate_cert, "f").extensions;
|
|
14293
|
+
this.criticalOptions = __classPrivateFieldGet(this, _SshCertificate_cert, "f").criticalOptions;
|
|
14294
|
+
}
|
|
14295
|
+
async parseSignatureKey() {
|
|
14296
|
+
const key = await __classPrivateFieldGet(this, _SshCertificate_cert, "f").signatureKey.toWebCrypto();
|
|
14297
|
+
const blob = __classPrivateFieldGet(this, _SshCertificate_cert, "f").signatureKey.getBlob();
|
|
14298
|
+
const thumbprint = await __classPrivateFieldGet(this, _SshCertificate_cert, "f").signatureKey.thumbprint('sha256');
|
|
14299
|
+
this.signatureKey = {
|
|
14300
|
+
algorithm: key.algorithm.name,
|
|
14301
|
+
type: blob.type,
|
|
14302
|
+
value: await __classPrivateFieldGet(this, _SshCertificate_cert, "f").signatureKey.toSSH(),
|
|
14303
|
+
thumbprint: buildExports.Convert.ToBase64(thumbprint),
|
|
14304
|
+
};
|
|
14305
|
+
}
|
|
14306
|
+
async parsePublicKey() {
|
|
14307
|
+
const key = await __classPrivateFieldGet(this, _SshCertificate_cert, "f").publicKey.toWebCrypto();
|
|
14308
|
+
const blob = __classPrivateFieldGet(this, _SshCertificate_cert, "f").publicKey.getBlob();
|
|
14309
|
+
const thumbprint = await __classPrivateFieldGet(this, _SshCertificate_cert, "f").publicKey.thumbprint('sha256');
|
|
14310
|
+
this.publicKey = {
|
|
14311
|
+
algorithm: key.algorithm.name,
|
|
14312
|
+
type: blob.type,
|
|
14313
|
+
value: await __classPrivateFieldGet(this, _SshCertificate_cert, "f").publicKey.toSSH(),
|
|
14314
|
+
thumbprint: buildExports.Convert.ToBase64(thumbprint),
|
|
14315
|
+
};
|
|
14316
|
+
}
|
|
14317
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14318
|
+
async toString(_format = 'pem') {
|
|
14319
|
+
return __classPrivateFieldGet(this, _SshCertificate_cert, "f").toSSH();
|
|
14320
|
+
}
|
|
14321
|
+
get commonName() {
|
|
14322
|
+
return __classPrivateFieldGet(this, _SshCertificate_cert, "f").principals.join('_') || __classPrivateFieldGet(this, _SshCertificate_cert, "f").keyId || __classPrivateFieldGet(this, _SshCertificate_cert, "f").certType;
|
|
14323
|
+
}
|
|
14324
|
+
async downloadAsSSH(name) {
|
|
14325
|
+
Download.certSSH.asSSH(await this.toString(), name || this.commonName);
|
|
14326
|
+
}
|
|
14327
|
+
}
|
|
14328
|
+
_SshCertificate_cert = new WeakMap();
|
|
14329
|
+
|
|
12701
14330
|
/**
|
|
12702
14331
|
* @license
|
|
12703
14332
|
* Copyright (c) Peculiar Ventures, LLC.
|
|
@@ -12725,7 +14354,7 @@ const DownloadIcon = (props) => {
|
|
|
12725
14354
|
h("path", { fill: `var(--pv-color-${color})`, d: "M21 12h-2c-.6 0-1 .4-1 1s.4 1 1 1h2c.6 0 1 .4 1 1v7c0 .6-.4 1-1 1H9c-.6 0-1-.4-1-1v-7c0-.6.4-1 1-1h2c.6 0 1-.4 1-1s-.4-1-1-1H9c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h12c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3Zm-9.7 5.7 3 3c.2.2.4.3.7.3.3 0 .5-.1.7-.3l3-3c.4-.4.4-1 0-1.4-.4-.4-1-.4-1.4 0L16 17.6V6c0-.6-.4-1-1-1s-1 .4-1 1v11.6l-1.3-1.3c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4Z" })));
|
|
12726
14355
|
};
|
|
12727
14356
|
|
|
12728
|
-
export {
|
|
14357
|
+
export { CertificateList as $, AsnData as A, id_DomainNameTechnicalOperator as B, CertificationRequest as C, Download as D, ECParameters as E, id_DomainNameOwner as F, id_DomainNameLegalRepresentative as G, id_DomainNameBeneficiary as H, InsuranceValue as I, cryptoProvider as J, Certificate as K, Link as L, dateDiff as M, Name as N, id_composite_key as O, PemConverter as P, CompositePublicKey as Q, RSAPublicKey as R, id_alg_composite as S, TypeRelationship as T, UnstructuredName as U, ValuationRanking as V, WebGDPR as W, CompositeSignatureValue as X, CompositeParams as Y, OIDs as Z, dateShort as _, DownloadIcon as a, id_lei as a$, CRLReason as a0, InvalidityDate as a1, CertificateIssuer as a2, SignedData as a3, EncapsulatedContent as a4, OctetString as a5, CertificateSet as a6, CertificateChoices as a7, ContentInfo as a8, SshCertificate as a9, SubjectDirectoryAttributes as aA, SubjectAlternativeName as aB, PolicyMappings as aC, PolicyConstraints as aD, NameConstraints as aE, KeyUsage as aF, IssueAlternativeName as aG, InhibitAnyPolicy as aH, ExtendedKeyUsage as aI, IssuingDistributionPoint as aJ, CRLDistributionPoints as aK, CertificatePolicies as aL, BasicConstraints as aM, AuthorityKeyIdentifier as aN, AuthorityInfoAccessSyntax as aO, id_cabforganizationIdentifier as aP, id_ce_keyDescription as aQ, id_ce_deltaCRLIndicator as aR, id_ce_cRLNumber as aS, id_pe_subjectInfoAccess as aT, id_pe_TNAuthList as aU, id_pe_biometricInfo as aV, id_entrust_entrustVersInfo as aW, id_ce_privateKeyUsagePeriod as aX, id_adbe_archiveRevInfo as aY, id_adbe_timestamp as aZ, id_role as a_, AttributeCertificate as aa, Name$1 as ab, ByteStream as ac, SignedCertificateTimestamp as ad, Extension$1 as ae, CabforganizationIdentifier as af, NonStandardKeyDescription as ag, BaseCRLNumber as ah, CRLNumber as ai, SubjectInfoAccessSyntax as aj, TNAuthorizationList as ak, LogotypeExtn as al, BiometricSyntax as am, EntrustVersionInfo as an, PrivateKeyUsagePeriod as ao, ArchiveRevInfo as ap, Timestamp as aq, LeiRole as ar, LeiChoice as as, CaVersion as at, NetscapeCertType as au, NetscapeComment as av, EnrollCertTypeChoice as aw, CertificateTemplate as ax, QCStatements as ay, SubjectKeyIdentifier as az, AsnConvert as b, id_caVersion as b0, id_netscapeCertType as b1, id_netscapeComment as b2, id_enrollCertType as b3, id_certificateTemplate as b4, id_pe_qcStatements as b5, id_ce_subjectKeyIdentifier as b6, id_ce_subjectDirectoryAttributes as b7, id_ce_subjectAltName as b8, id_ce_policyMappings as b9, SemanticsInformation as bA, AsnIntegerArrayBufferConverter as bB, AttestationApplicationId as bC, RootOfTrust as bD, IntegerSet as bE, id_ce_policyConstraints as ba, id_ce_nameConstraints as bb, id_ce_keyUsage as bc, id_ce_issuerAltName as bd, id_ce_invalidityDate as be, id_ce_inhibitAnyPolicy as bf, id_ce_extKeyUsage as bg, id_ce_cRLReasons as bh, id_ce_issuingDistributionPoint as bi, id_ce_cRLDistributionPoints as bj, id_ce_certificatePolicies as bk, id_ce_certificateIssuer as bl, id_ce_basicConstraints as bm, id_ce_authorityKeyIdentifier as bn, id_pe_authorityInfoAccess as bo, OtherName as bp, DisplayText as bq, UserNotice as br, EDIPartyName as bs, __decorate$1 as bt, AsnProp as bu, AsnPropTypes as bv, AsnType as bw, AsnTypeTypes as bx, AsnArray as by, id_qcs_pkixQCSyntax_v2 as bz, id_rsaEncryption as c, downloadFromBuffer as d, buildExports as e, Attribute$1 as f, AsnParser as g, PrivateKeyPossessionStatement as h, id_ecPublicKey as i, ExtensionRequest as j, ChallengePassword as k, l10n as l, ActivityDescription as m, DomainNameTechnicalOperator as n, DomainNameOwner as o, DomainNameLegalRepresentative as p, DomainNameBeneficiary as q, id_at_statementOfPossession as r, id_pkcs9_at_extensionRequest as s, id_pkcs9_at_unstructuredName as t, id_pkcs9_at_challengePassword as u, id_ValuationRanking as v, id_InsuranceValue as w, id_WebGDPR as x, id_ActivityDescription as y, id_TypeRelationship as z };
|
|
12729
14358
|
//# sourceMappingURL=download.js.map
|
|
12730
14359
|
|
|
12731
14360
|
//# sourceMappingURL=download.js.map
|