core-3nweb-client-lib 0.40.1 → 0.41.1

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.
Files changed (32) hide show
  1. package/build/api-defs/files.d.ts +1 -0
  2. package/build/api-defs/mailerid.d.ts +51 -1
  3. package/build/core/asmail/key-verification.d.ts +5 -0
  4. package/build/core/asmail/key-verification.js +6 -4
  5. package/build/core/id-manager/index.d.ts +2 -2
  6. package/build/core/id-manager/index.js +30 -0
  7. package/build/core/id-manager/mailerid-cap-ipc.js +6 -2
  8. package/build/core-ipc/json-ipc-wrapping/json-n-binary.js +1 -1
  9. package/build/lib-client/asmail/sender.d.ts +2 -2
  10. package/build/lib-client/asmail/sender.js +1 -1
  11. package/build/lib-client/mailer-id/login.d.ts +2 -2
  12. package/build/lib-client/mailer-id/login.js +1 -1
  13. package/build/lib-client/mailer-id/provisioner.d.ts +2 -2
  14. package/build/lib-client/mailer-id/provisioner.js +6 -6
  15. package/build/lib-client/user-with-mid-session.d.ts +3 -3
  16. package/build/lib-client/user-with-mid-session.js +1 -1
  17. package/build/lib-client/xsp-fs/folder-node.js +3 -0
  18. package/build/lib-common/mailerid-sigs/id-provider.d.ts +64 -0
  19. package/build/lib-common/mailerid-sigs/id-provider.js +174 -0
  20. package/build/lib-common/mailerid-sigs/index.d.ts +44 -0
  21. package/build/lib-common/mailerid-sigs/index.js +50 -0
  22. package/build/lib-common/mailerid-sigs/relying-party.d.ts +59 -0
  23. package/build/lib-common/mailerid-sigs/relying-party.js +237 -0
  24. package/build/lib-common/mailerid-sigs/user.d.ts +60 -0
  25. package/build/lib-common/mailerid-sigs/user.js +149 -0
  26. package/build/lib-common/mailerid-sigs/utils-NaCl-Ed.d.ts +8 -0
  27. package/build/lib-common/mailerid-sigs/utils-NaCl-Ed.js +61 -0
  28. package/build/raw-3nweb-clients.d.ts +2 -2
  29. package/build/raw-3nweb-clients.js +1 -1
  30. package/package.json +1 -1
  31. package/build/lib-common/mid-sigs-NaCl-Ed.d.ts +0 -220
  32. package/build/lib-common/mid-sigs-NaCl-Ed.js +0 -560
@@ -48,6 +48,7 @@ declare namespace web3n.files {
48
48
  remoteNotSet?: true;
49
49
  notLinkableFile?: true;
50
50
  notLinkableFolder?: true;
51
+ badFnCallArguments?: true;
51
52
  }
52
53
 
53
54
  interface exceptionCode {
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright (C) 2020 3NSoft Inc.
2
+ Copyright (C) 2020, 2025 3NSoft Inc.
3
3
 
4
4
  This program is free software: you can redistribute it and/or modify it under
5
5
  the terms of the GNU General Public License as published by the Free Software
@@ -20,10 +20,36 @@ declare namespace web3n.mailerid {
20
20
 
21
21
  interface Service {
22
22
 
23
+ /**
24
+ * Returns MailerId/address of a current user.
25
+ */
23
26
  getUserId(): Promise<string>;
24
27
 
28
+ /**
29
+ * Performs a MailerId-based login at a given url, returning session id.
30
+ * @param serviceUrl
31
+ */
25
32
  login(serviceUrl: string): Promise<string>;
26
33
 
34
+ /**
35
+ * Signs given payload with current identity, returning object with
36
+ * signature and a complete MailerId certificates' chain of a used key.
37
+ * @param payload
38
+ */
39
+ sign(payload: Uint8Array): Promise<MailerIdSignature>;
40
+
41
+ /**
42
+ * Verifies given signature, returning true if it is ok.
43
+ * Since this is a check of MailerId signature, root certificate of a
44
+ * respective identity provider would have to be retrieved with a chance
45
+ * of related exceptions being thrown.
46
+ * @param midSignature
47
+ */
48
+ verifySignature(midSignature: MailerIdSignature): Promise<{
49
+ cryptoCheck: boolean;
50
+ midProviderCheck?: MailerIdProviderCheckResult;
51
+ }>;
52
+
27
53
  }
28
54
 
29
55
  interface MailerIdAssertionLoad {
@@ -34,4 +60,28 @@ declare namespace web3n.mailerid {
34
60
  expiresAt: number;
35
61
  }
36
62
 
63
+ interface MailerIdSignature {
64
+ rootMidCert: keys.SignedLoad;
65
+ provCert: keys.SignedLoad;
66
+ signeeCert: keys.SignedLoad;
67
+ signature: keys.SignedLoad;
68
+ }
69
+
70
+ type MailerIdProviderCheckResult =
71
+ 'all-ok'
72
+ | 'unknown-root-cert'
73
+ | 'not-current-provider'
74
+ |'dns-not-set'
75
+ | 'offline-no-check'
76
+ | 'other-fail';
77
+
78
+ interface MailerIdException extends RuntimeException {
79
+ type: 'mailerid';
80
+ algMismatch?: true;
81
+ timeMismatch?: true;
82
+ certsMismatch?: true;
83
+ certMalformed?: true;
84
+ sigVerificationFails?: true;
85
+ }
86
+
37
87
  }
@@ -1,6 +1,7 @@
1
1
  import { ServiceLocator } from '../../lib-client/service-locator';
2
2
  import { NetClient } from '../../lib-client/request-utils';
3
3
  type JsonKey = web3n.keys.JsonKey;
4
+ type SignedLoad = web3n.keys.SignedLoad;
4
5
  type PKeyCertChain = web3n.keys.PKeyCertChain;
5
6
  /**
6
7
  * This returns a promise, resolvable to public key, when certificates'
@@ -12,6 +13,10 @@ type PKeyCertChain = web3n.keys.PKeyCertChain;
12
13
  * @param certs is an object with a MailerId certificates chain for a public key
13
14
  */
14
15
  export declare function checkAndExtractPKey(client: NetClient, resolver: ServiceLocator, address: string, certs: PKeyCertChain): Promise<JsonKey>;
16
+ export declare function getRootCertForKey(kid: string, resolver: ServiceLocator, client: NetClient, address: string): Promise<{
17
+ domain: string;
18
+ rootCert: SignedLoad;
19
+ }>;
15
20
  /**
16
21
  * This returns a promise, resolvable to public key and related address, when
17
22
  * certificates' verification is successful, and rejectable in all other cases.
@@ -17,11 +17,13 @@
17
17
  */
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.checkAndExtractPKey = checkAndExtractPKey;
20
+ exports.getRootCertForKey = getRootCertForKey;
20
21
  exports.checkAndExtractPKeyWithAddress = checkAndExtractPKeyWithAddress;
21
22
  const canonical_address_1 = require("../../lib-common/canonical-address");
22
- const mid_sigs_NaCl_Ed_1 = require("../../lib-common/mid-sigs-NaCl-Ed");
23
23
  const jwkeys_1 = require("../../lib-common/jwkeys");
24
24
  const service_locator_1 = require("../../lib-client/service-locator");
25
+ const relying_party_1 = require("../../lib-common/mailerid-sigs/relying-party");
26
+ const mailerid_sigs_1 = require("../../lib-common/mailerid-sigs");
25
27
  /**
26
28
  * This returns a promise, resolvable to public key, when certificates'
27
29
  * verification is successful, and rejectable in all other cases.
@@ -36,7 +38,7 @@ async function checkAndExtractPKey(client, resolver, address, certs) {
36
38
  const validAt = Math.round(Date.now() / 1000);
37
39
  // get MailerId provider's info with a root certificate(s)
38
40
  const { domain: rootAddr, rootCert } = await getRootCertForKey(certs.provCert.kid, resolver, client, address);
39
- const pkey = mid_sigs_NaCl_Ed_1.relyingParty.verifyPubKey(certs.pkeyCert, address, { user: certs.userCert, prov: certs.provCert, root: rootCert }, rootAddr, validAt);
41
+ const pkey = (0, relying_party_1.verifyPubKey)(certs.pkeyCert, address, { user: certs.userCert, prov: certs.provCert, root: rootCert }, rootAddr, validAt);
40
42
  return pkey;
41
43
  }
42
44
  async function getRootCertForKey(kid, resolver, client, address) {
@@ -72,11 +74,11 @@ async function checkAndExtractPKeyWithAddress(client, resolver, certs, validAt)
72
74
  address = (0, jwkeys_1.getKeyCert)(certs.pkeyCert).cert.principal.address;
73
75
  }
74
76
  catch (err) {
75
- throw (0, mid_sigs_NaCl_Ed_1.makeMalformedCertsException)(`Cannot read public key certificate`, err);
77
+ throw (0, mailerid_sigs_1.makeMalformedCertsException)(`Cannot read public key certificate`, err);
76
78
  }
77
79
  // get MailerId provider's info with a root certificate(s)
78
80
  const { domain: rootAddr, rootCert } = await getRootCertForKey(certs.provCert.kid, resolver, client, address);
79
- const pkey = mid_sigs_NaCl_Ed_1.relyingParty.verifyPubKey(certs.pkeyCert, address, { user: certs.userCert, prov: certs.provCert, root: rootCert }, rootAddr, validAt);
81
+ const pkey = (0, relying_party_1.verifyPubKey)(certs.pkeyCert, address, { user: certs.userCert, prov: certs.provCert, root: rootCert }, rootAddr, validAt);
80
82
  return { address, pkey };
81
83
  }
82
84
  Object.freeze(exports);
@@ -1,8 +1,8 @@
1
- import { user as mid } from '../../lib-common/mid-sigs-NaCl-Ed';
2
1
  import { GenerateKey } from '../startup/sign-in';
3
2
  import { LogError, LogWarning } from '../../lib-client/logging/log-to-file';
4
3
  import { NetClient } from '../../lib-client/request-utils';
5
4
  import { ServiceLocator } from '../../lib-client/service-locator';
5
+ import { MailerIdSigner } from '../../lib-common/mailerid-sigs/user';
6
6
  type JsonKey = web3n.keys.JsonKey;
7
7
  type WritableFS = web3n.files.WritableFS;
8
8
  /**
@@ -17,7 +17,7 @@ export interface CompleteProvisioning {
17
17
  /**
18
18
  * This returns a promise, resolvable to mailerId signer.
19
19
  */
20
- export type GetSigner = () => Promise<mid.MailerIdSigner>;
20
+ export type GetSigner = () => Promise<MailerIdSigner>;
21
21
  export type SetupManagerStorage = (fs: WritableFS, keysToSave?: JsonKey[]) => Promise<void>;
22
22
  export declare class IdManager {
23
23
  private readonly store;
@@ -23,6 +23,9 @@ const jwkeys_1 = require("../../lib-common/jwkeys");
23
23
  const synced_1 = require("../../lib-common/processes/synced");
24
24
  const login_1 = require("../../lib-client/mailer-id/login");
25
25
  const key_storage_1 = require("./key-storage");
26
+ const relying_party_1 = require("../../lib-common/mailerid-sigs/relying-party");
27
+ const key_verification_1 = require("../asmail/key-verification");
28
+ const json_utils_1 = require("../../lib-common/json-utils");
26
29
  const CERTIFICATE_DURATION_SECONDS = 16 * 60 * 60;
27
30
  const ASSERTION_VALIDITY = 15 * 60;
28
31
  const MIN_SECS_LEFT_ASSUMED_OK = 10 * 60;
@@ -157,6 +160,33 @@ class IdManager {
157
160
  login: async (serviceUrl) => {
158
161
  const signer = await this.getSigner();
159
162
  return doMidLogin(serviceUrl, this.getId(), this.makeNet(), signer);
163
+ },
164
+ sign: async (content) => {
165
+ const signer = await this.getSigner();
166
+ const { signature, signeeCert, provCert } = signer.sign(content);
167
+ const { rootCert: rootMidCert } = await (0, key_verification_1.getRootCertForKey)(signer.providerCert.kid, this.midServiceFor, this.makeNet(), signer.address);
168
+ return { signature, signeeCert, provCert, rootMidCert };
169
+ },
170
+ verifySignature: async (midSig) => {
171
+ const { signature, signeeCert, provCert, rootMidCert } = midSig;
172
+ const cryptoCheck = (0, relying_party_1.verifySignature)(rootMidCert, provCert, signeeCert, signature);
173
+ if (!cryptoCheck) {
174
+ return { cryptoCheck };
175
+ }
176
+ try {
177
+ const { rootCert, domain } = await (0, key_verification_1.getRootCertForKey)(rootMidCert.kid, this.midServiceFor, this.makeNet(), (0, jwkeys_1.getKeyCert)(signeeCert).cert.principal.address);
178
+ if ((0, json_utils_1.deepEqual)(rootCert, rootMidCert)) {
179
+ return { cryptoCheck, midProviderCheck: 'all-ok' };
180
+ }
181
+ else {
182
+ // XXX indicate more specific error cases
183
+ return { cryptoCheck, midProviderCheck: 'other-fail' };
184
+ }
185
+ }
186
+ catch (err) {
187
+ // XXX indicate more specific error cases
188
+ return { cryptoCheck, midProviderCheck: 'other-fail' };
189
+ }
160
190
  }
161
191
  };
162
192
  return Object.freeze(w);
@@ -23,7 +23,9 @@ const service_side_wrap_1 = require("../../core-ipc/json-ipc-wrapping/service-si
23
23
  function exposeMailerIdCAP(cap) {
24
24
  return {
25
25
  getUserId: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'getUserId'),
26
- login: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'login')
26
+ login: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'login'),
27
+ sign: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'sign'),
28
+ verifySignature: (0, service_side_wrap_1.wrapReqReplySrvMethod)(cap, 'verifySignature')
27
29
  };
28
30
  }
29
31
  function callMailerId(caller, objPath, method) {
@@ -32,7 +34,9 @@ function callMailerId(caller, objPath, method) {
32
34
  function makeMailerIdCaller(caller, objPath) {
33
35
  return {
34
36
  getUserId: callMailerId(caller, objPath, 'getUserId'),
35
- login: callMailerId(caller, objPath, 'login')
37
+ login: callMailerId(caller, objPath, 'login'),
38
+ sign: callMailerId(caller, objPath, 'sign'),
39
+ verifySignature: callMailerId(caller, objPath, 'verifySignature')
36
40
  };
37
41
  }
38
42
  Object.freeze(exports);
@@ -187,7 +187,7 @@ function deserializeArgs(bytes, passedByReference) {
187
187
  args.push(arg);
188
188
  }
189
189
  else {
190
- // XXX throw error here
190
+ args.push(undefined);
191
191
  }
192
192
  }
193
193
  return args;
@@ -3,8 +3,8 @@
3
3
  */
4
4
  import { NetClient } from '../request-utils';
5
5
  import * as api from '../../lib-common/service-api/asmail/delivery';
6
- import { user as mid } from '../../lib-common/mid-sigs-NaCl-Ed';
7
6
  import { ServiceLocator } from '../service-locator';
7
+ import { MailerIdSigner } from '../../lib-common/mailerid-sigs/user';
8
8
  export type FirstSaveReqOpts = api.PutObjFirstQueryOpts;
9
9
  export type FollowingSaveReqOpts = api.PutObjSecondQueryOpts;
10
10
  export type ServiceUrlGetter = (address: string) => Promise<string>;
@@ -97,7 +97,7 @@ export declare class MailSender {
97
97
  * Rejected promise passes an error object, conditionally containing
98
98
  * status field.
99
99
  */
100
- authorizeSender(assertionSigner: mid.MailerIdSigner): Promise<void>;
100
+ authorizeSender(assertionSigner: MailerIdSigner): Promise<void>;
101
101
  /**
102
102
  * This gets recipients initial public key to launch message exchange.
103
103
  * @return a promise resolvable to certificates, received from server.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015, 2017, 2020 3NSoft Inc.
3
+ Copyright (C) 2015, 2017, 2020, 2025 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -1,6 +1,6 @@
1
1
  import { NetClient } from '../request-utils';
2
2
  import { HTTPException } from '../../lib-common/exceptions/http';
3
- import { user as mid } from '../../lib-common/mid-sigs-NaCl-Ed';
3
+ import { MailerIdSigner } from '../../lib-common/mailerid-sigs/user';
4
4
  export interface LoginException extends HTTPException {
5
5
  loginFailed?: boolean;
6
6
  unknownUser?: boolean;
@@ -9,4 +9,4 @@ export declare function startMidSession(userId: string, net: NetClient, loginUrl
9
9
  sessionId?: string;
10
10
  redirect?: string;
11
11
  }>;
12
- export declare function authenticateMidSession(sessionId: string, midSigner: mid.MailerIdSigner, net: NetClient, loginUrl: string): Promise<void>;
12
+ export declare function authenticateMidSession(sessionId: string, midSigner: MailerIdSigner, net: NetClient, loginUrl: string): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015, 2017, 2020 3NSoft Inc.
3
+ Copyright (C) 2015, 2017, 2020, 2025 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -1,10 +1,10 @@
1
1
  import { NetClient } from '../request-utils';
2
2
  import { ServiceUser, ICalcDHSharedKey, LoginCompletion } from '../user-with-pkl-session';
3
- import * as mid from '../../lib-common/mid-sigs-NaCl-Ed';
3
+ import { MailerIdSigner } from '../../lib-common/mailerid-sigs/user';
4
4
  export interface ProvisioningCompletion {
5
5
  keyParams: any;
6
6
  serverPKey: Uint8Array;
7
- complete(dhsharedKeyCalc: ICalcDHSharedKey, certDuration: number, assertDuration?: number): Promise<mid.user.MailerIdSigner>;
7
+ complete(dhsharedKeyCalc: ICalcDHSharedKey, certDuration: number, assertDuration?: number): Promise<MailerIdSigner>;
8
8
  }
9
9
  /**
10
10
  * Certificate provisioner is an object that can do all MailerId's provisioning
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015 - 2017, 2021 3NSoft Inc.
3
+ Copyright (C) 2015 - 2017, 2021, 2025 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -23,11 +23,12 @@ const user_with_pkl_session_1 = require("../user-with-pkl-session");
23
23
  const jwkeys_1 = require("../../lib-common/jwkeys");
24
24
  const json_utils_1 = require("../../lib-common/json-utils");
25
25
  const canonical_address_1 = require("../../lib-common/canonical-address");
26
- const mid = require("../../lib-common/mid-sigs-NaCl-Ed");
27
26
  const random = require("../../lib-common/random-node");
28
27
  const api = require("../../lib-common/service-api/mailer-id/provisioning");
29
28
  const url_1 = require("url");
30
29
  const assert_1 = require("../../lib-common/assert");
30
+ const user_1 = require("../../lib-common/mailerid-sigs/user");
31
+ const relying_party_1 = require("../../lib-common/mailerid-sigs/relying-party");
31
32
  const DEFAULT_ASSERTION_VALIDITY = 20 * 60;
32
33
  /**
33
34
  * Certificate provisioner is an object that can do all MailerId's provisioning
@@ -94,8 +95,7 @@ class MailerIdProvisioner extends user_with_pkl_session_1.ServiceUser {
94
95
  if (!certs.userCert || !certs.provCert) {
95
96
  throw (0, request_utils_1.makeException)(rep, 'Malformed reply: Certificates are missing.');
96
97
  }
97
- const pkeyAndId = mid.relyingParty.verifyChainAndGetUserKey({ user: certs.userCert, prov: certs.provCert,
98
- root: this.rootCert }, this.midDomain, (0, jwkeys_1.getKeyCert)(certs.userCert).issuedAt + 1);
98
+ const pkeyAndId = (0, relying_party_1.verifyChainAndGetUserKey)({ user: certs.userCert, prov: certs.provCert, root: this.rootCert }, this.midDomain, (0, jwkeys_1.getKeyCert)(certs.userCert).issuedAt + 1);
99
99
  if (pkeyAndId.address !== (0, canonical_address_1.toCanonicalAddress)(this.userId)) {
100
100
  throw (0, request_utils_1.makeException)(rep, 'Malformed reply: Certificate is for a wrong address.');
101
101
  }
@@ -133,13 +133,13 @@ class MailerIdProvisioner extends user_with_pkl_session_1.ServiceUser {
133
133
  * Undefined value means that a default key should be used.
134
134
  */
135
135
  async provisionSigner(keyId) {
136
- const pair = mid.user.generateSigningKeyPair(random.bytesSync);
136
+ const pair = (0, user_1.generateSigningKeyPair)(random.bytesSync);
137
137
  await this.setUrlAndDomain();
138
138
  const login = await this.super_login(keyId);
139
139
  const completion = async (dhsharedKeyCalc, certDuration, assertDuration = DEFAULT_ASSERTION_VALIDITY) => {
140
140
  await login.complete(dhsharedKeyCalc);
141
141
  await this.getCertificates(pair.pkey, certDuration);
142
- return mid.user.makeMailerIdSigner(pair.skey, this.userCert, this.provCert, assertDuration);
142
+ return (0, user_1.makeMailerIdSigner)(pair.skey, this.userCert, this.provCert, assertDuration);
143
143
  };
144
144
  return {
145
145
  keyParams: login.keyParams,
@@ -3,9 +3,9 @@
3
3
  * MailerId and uses respectively authenticated session.
4
4
  */
5
5
  import { Reply, RequestOpts, NetClient } from '../lib-client/request-utils';
6
- import { user as mid } from '../lib-common/mid-sigs-NaCl-Ed';
7
6
  import * as WebSocket from 'ws';
8
- export type IGetMailerIdSigner = () => Promise<mid.MailerIdSigner>;
7
+ import { MailerIdSigner } from '../lib-common/mailerid-sigs/user';
8
+ export type IGetMailerIdSigner = () => Promise<MailerIdSigner>;
9
9
  export interface ServiceAccessParams {
10
10
  login: string;
11
11
  logout: string;
@@ -44,7 +44,7 @@ export declare abstract class ServiceUser {
44
44
  * @return a promise, resolvable, when mailerId login successfully
45
45
  * completes.
46
46
  */
47
- login(midSigner?: mid.MailerIdSigner): Promise<void>;
47
+ login(midSigner?: MailerIdSigner): Promise<void>;
48
48
  /**
49
49
  * This method closes current session.
50
50
  * @return a promise for request completion.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*
3
- Copyright (C) 2015, 2017, 2020, 2022 3NSoft Inc.
3
+ Copyright (C) 2015, 2017, 2020, 2022, 2025 3NSoft Inc.
4
4
 
5
5
  This program is free software: you can redistribute it and/or modify it under
6
6
  the terms of the GNU General Public License as published by the Free Software
@@ -462,6 +462,9 @@ class FolderNode extends node_in_fs_1.NodeInFS {
462
462
  return { node, key };
463
463
  }
464
464
  create(type, name, exclusive, changes, linkParams) {
465
+ if ((typeof name !== 'string') || (name.length === 0)) {
466
+ throw (0, file_1.makeFileException)('badFnCallArguments', name, `Given name is invalid for making ${type} node`);
467
+ }
465
468
  return this.doChange(true, async () => {
466
469
  // do check for concurrent creation of a node
467
470
  if (this.getNodeInfo(name, true)) {
@@ -0,0 +1,64 @@
1
+ import { GetRandom, arrays } from "ecma-nacl";
2
+ type JsonKey = web3n.keys.JsonKey;
3
+ type SignedLoad = web3n.keys.SignedLoad;
4
+ export declare const KID_BYTES_LENGTH = 9;
5
+ export declare const MAX_USER_CERT_VALIDITY: number;
6
+ export declare function makeSelfSignedCert(address: string, validityPeriod: number, sjkey: JsonKey, arrFactory?: arrays.Factory): SignedLoad;
7
+ /**
8
+ * One should keep MailerId root key offline, as this key is used only to
9
+ * sign provider keys, which have to work online.
10
+ * @param address is an address of an issuer
11
+ * @param validityPeriod validity period of a generated self-signed
12
+ * certificate in milliseconds
13
+ * @param random
14
+ * @param arrFactory optional array factory
15
+ * @return Generated root key and a self-signed certificate for respective
16
+ * public key.
17
+ */
18
+ export declare function generateRootKey(address: string, validityPeriod: number, random: GetRandom, arrFactory?: arrays.Factory): {
19
+ cert: SignedLoad;
20
+ skey: JsonKey;
21
+ };
22
+ /**
23
+ * @param address is an address of an issuer
24
+ * @param validityPeriod validity period of a generated self-signed
25
+ * certificate in seconds
26
+ * @param rootJKey root key in json format
27
+ * @param random
28
+ * @param arrFactory optional array factory
29
+ * @return Generated provider's key and a certificate for a respective
30
+ * public key.
31
+ */
32
+ export declare function generateProviderKey(address: string, validityPeriod: number, rootJKey: JsonKey, random: GetRandom, arrFactory?: arrays.Factory): {
33
+ cert: SignedLoad;
34
+ skey: JsonKey;
35
+ };
36
+ /**
37
+ * MailerId providing service should use this object to generate certificates.
38
+ */
39
+ export interface IdProviderCertifier {
40
+ /**
41
+ * @param publicKey
42
+ * @param address
43
+ * @param validFor (optional)
44
+ * @return certificate for a given key
45
+ */
46
+ certify(publicKey: JsonKey, address: string, validFor?: number): SignedLoad;
47
+ /**
48
+ * This securely erases internal key.
49
+ * Call this function, when certifier is no longer needed.
50
+ */
51
+ destroy(): void;
52
+ }
53
+ /**
54
+ * @param issuer is a domain of certificate issuer, at which issuer's public
55
+ * key can be found to check the signature
56
+ * @param validityPeriod is a default validity period in seconds, for
57
+ * which certifier shall be making certificates
58
+ * @param signJKey is a certificates signing key
59
+ * @param arrFactory is an optional array factory
60
+ * @return MailerId certificates generator, which shall be used on identity
61
+ * provider's side
62
+ */
63
+ export declare function makeIdProviderCertifier(issuer: string, validityPeriod: number, signJKey: JsonKey, arrFactory?: arrays.Factory): IdProviderCertifier;
64
+ export {};
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (C) 2015 - 2017, 2025 3NSoft Inc.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under
6
+ the terms of the GNU General Public License as published by the Free Software
7
+ Foundation, either version 3 of the License, or (at your option) any later
8
+ version.
9
+
10
+ This program is distributed in the hope that it will be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+ See the GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License along with
16
+ this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.MAX_USER_CERT_VALIDITY = exports.KID_BYTES_LENGTH = void 0;
20
+ exports.makeSelfSignedCert = makeSelfSignedCert;
21
+ exports.generateRootKey = generateRootKey;
22
+ exports.generateProviderKey = generateProviderKey;
23
+ exports.makeIdProviderCertifier = makeIdProviderCertifier;
24
+ const ecma_nacl_1 = require("ecma-nacl");
25
+ const jwkeys_1 = require("../jwkeys");
26
+ const buffer_utils_1 = require("../buffer-utils");
27
+ const index_1 = require("./index");
28
+ function genSignKeyPair(use, kidLen, random, arrFactory) {
29
+ const pair = ecma_nacl_1.signing.generate_keypair(random(32), arrFactory);
30
+ const pkey = {
31
+ use: use,
32
+ alg: ecma_nacl_1.signing.JWK_ALG_NAME,
33
+ kid: buffer_utils_1.base64.pack(random(kidLen)),
34
+ k: buffer_utils_1.base64.pack(pair.pkey)
35
+ };
36
+ const skey = {
37
+ use: pkey.use,
38
+ alg: pkey.alg,
39
+ kid: pkey.kid,
40
+ k: pair.skey
41
+ };
42
+ return { pkey: pkey, skey: skey };
43
+ }
44
+ function makeCert(pkey, principalAddr, issuer, issuedAt, expiresAt, signKey, arrFactory) {
45
+ if (signKey.alg !== ecma_nacl_1.signing.JWK_ALG_NAME) {
46
+ throw (0, index_1.makeMailerIdException)({ algMismatch: true }, { message: `Given signing key is used with unknown algorithm ${signKey.alg}` });
47
+ }
48
+ const cert = {
49
+ cert: {
50
+ publicKey: pkey,
51
+ principal: { address: principalAddr }
52
+ },
53
+ issuer: issuer,
54
+ issuedAt: issuedAt,
55
+ expiresAt: expiresAt
56
+ };
57
+ const certBytes = buffer_utils_1.utf8.pack(JSON.stringify(cert));
58
+ const sigBytes = ecma_nacl_1.signing.signature(certBytes, signKey.k, arrFactory);
59
+ return {
60
+ alg: signKey.alg,
61
+ kid: signKey.kid,
62
+ sig: buffer_utils_1.base64.pack(sigBytes),
63
+ load: buffer_utils_1.base64.pack(certBytes)
64
+ };
65
+ }
66
+ exports.KID_BYTES_LENGTH = 9;
67
+ exports.MAX_USER_CERT_VALIDITY = 24 * 60 * 60;
68
+ function makeSelfSignedCert(address, validityPeriod, sjkey, arrFactory) {
69
+ const skey = (0, jwkeys_1.keyFromJson)(sjkey, index_1.KEY_USE.ROOT, ecma_nacl_1.signing.JWK_ALG_NAME, ecma_nacl_1.signing.SECRET_KEY_LENGTH);
70
+ const pkey = {
71
+ use: sjkey.use,
72
+ alg: sjkey.alg,
73
+ kid: sjkey.kid,
74
+ k: buffer_utils_1.base64.pack(ecma_nacl_1.signing.extract_pkey(skey.k))
75
+ };
76
+ const now = Math.floor(Date.now() / 1000);
77
+ return makeCert(pkey, address, address, now, now + validityPeriod, skey, arrFactory);
78
+ }
79
+ /**
80
+ * One should keep MailerId root key offline, as this key is used only to
81
+ * sign provider keys, which have to work online.
82
+ * @param address is an address of an issuer
83
+ * @param validityPeriod validity period of a generated self-signed
84
+ * certificate in milliseconds
85
+ * @param random
86
+ * @param arrFactory optional array factory
87
+ * @return Generated root key and a self-signed certificate for respective
88
+ * public key.
89
+ */
90
+ function generateRootKey(address, validityPeriod, random, arrFactory) {
91
+ if (validityPeriod < 1) {
92
+ throw new Error(`Illegal validity period: ${validityPeriod}`);
93
+ }
94
+ const rootPair = genSignKeyPair(index_1.KEY_USE.ROOT, exports.KID_BYTES_LENGTH, random, arrFactory);
95
+ const now = Math.floor(Date.now() / 1000);
96
+ const rootCert = makeCert(rootPair.pkey, address, address, now, now + validityPeriod, rootPair.skey, arrFactory);
97
+ return { cert: rootCert, skey: (0, jwkeys_1.keyToJson)(rootPair.skey) };
98
+ }
99
+ /**
100
+ * @param address is an address of an issuer
101
+ * @param validityPeriod validity period of a generated self-signed
102
+ * certificate in seconds
103
+ * @param rootJKey root key in json format
104
+ * @param random
105
+ * @param arrFactory optional array factory
106
+ * @return Generated provider's key and a certificate for a respective
107
+ * public key.
108
+ */
109
+ function generateProviderKey(address, validityPeriod, rootJKey, random, arrFactory) {
110
+ if (validityPeriod < 1) {
111
+ throw new Error(`Illegal validity period: ${validityPeriod}`);
112
+ }
113
+ const rootKey = (0, jwkeys_1.keyFromJson)(rootJKey, index_1.KEY_USE.ROOT, ecma_nacl_1.signing.JWK_ALG_NAME, ecma_nacl_1.signing.SECRET_KEY_LENGTH);
114
+ const provPair = genSignKeyPair(index_1.KEY_USE.PROVIDER, exports.KID_BYTES_LENGTH, random, arrFactory);
115
+ const now = Math.floor(Date.now() / 1000);
116
+ const rootCert = makeCert(provPair.pkey, address, address, now, now + validityPeriod, rootKey, arrFactory);
117
+ return { cert: rootCert, skey: (0, jwkeys_1.keyToJson)(provPair.skey) };
118
+ }
119
+ /**
120
+ * @param issuer is a domain of certificate issuer, at which issuer's public
121
+ * key can be found to check the signature
122
+ * @param validityPeriod is a default validity period in seconds, for
123
+ * which certifier shall be making certificates
124
+ * @param signJKey is a certificates signing key
125
+ * @param arrFactory is an optional array factory
126
+ * @return MailerId certificates generator, which shall be used on identity
127
+ * provider's side
128
+ */
129
+ function makeIdProviderCertifier(issuer, validityPeriod, signJKey, arrFactory) {
130
+ if (!issuer) {
131
+ throw new Error(`Given issuer is illegal: ${issuer}`);
132
+ }
133
+ if ((validityPeriod < 1) || (validityPeriod > exports.MAX_USER_CERT_VALIDITY)) {
134
+ throw new Error(`Given certificate validity is illegal: ${validityPeriod}`);
135
+ }
136
+ let signKey = (0, jwkeys_1.keyFromJson)(signJKey, index_1.KEY_USE.PROVIDER, ecma_nacl_1.signing.JWK_ALG_NAME, ecma_nacl_1.signing.SECRET_KEY_LENGTH);
137
+ signJKey = undefined;
138
+ if (!arrFactory) {
139
+ arrFactory = ecma_nacl_1.arrays.makeFactory();
140
+ }
141
+ return {
142
+ certify: (publicKey, address, validFor) => {
143
+ if (!signKey) {
144
+ throw new Error(`Certifier is already destroyed.`);
145
+ }
146
+ if (publicKey.use !== index_1.KEY_USE.SIGN) {
147
+ throw new Error(`Given public key has use ${publicKey.use} and cannot be used for signing.`);
148
+ }
149
+ if (typeof validFor === 'number') {
150
+ if (validFor > validityPeriod) {
151
+ validFor = validityPeriod;
152
+ }
153
+ else if (validFor < 0) {
154
+ new Error(`Given certificate validity is illegal: ${validFor}`);
155
+ }
156
+ }
157
+ else {
158
+ validFor = validityPeriod;
159
+ }
160
+ const now = Math.floor(Date.now() / 1000);
161
+ return makeCert(publicKey, address, issuer, now, now + validFor, signKey, arrFactory);
162
+ },
163
+ destroy: () => {
164
+ if (!signKey) {
165
+ return;
166
+ }
167
+ ecma_nacl_1.arrays.wipe(signKey.k);
168
+ signKey = undefined;
169
+ arrFactory.wipeRecycled();
170
+ arrFactory = undefined;
171
+ }
172
+ };
173
+ }
174
+ Object.freeze(exports);