@icure/api 8.0.0-RC.3 → 8.0.0-RC.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/icc-api/api/IccInsuranceApi.d.ts +2 -0
- package/icc-api/api/IccInsuranceApi.js +12 -0
- package/icc-api/api/IccInsuranceApi.js.map +1 -1
- package/icc-api/api/{IccExchangeDataApi.d.ts → internal/IccExchangeDataApi.d.ts} +4 -4
- package/icc-api/api/{IccExchangeDataApi.js → internal/IccExchangeDataApi.js} +5 -5
- package/icc-api/api/internal/IccExchangeDataApi.js.map +1 -0
- package/icc-api/api/{IccExchangeDataMapApi.d.ts → internal/IccExchangeDataMapApi.d.ts} +4 -4
- package/icc-api/api/{IccExchangeDataMapApi.js → internal/IccExchangeDataMapApi.js} +5 -5
- package/icc-api/api/internal/IccExchangeDataMapApi.js.map +1 -0
- package/icc-api/api/internal/IccRecoveryDataApi.d.ts +19 -0
- package/icc-api/api/internal/IccRecoveryDataApi.js +83 -0
- package/icc-api/api/internal/IccRecoveryDataApi.js.map +1 -0
- package/icc-api/api/{IccSecureDelegationKeyMapApi.d.ts → internal/IccSecureDelegationKeyMapApi.d.ts} +6 -6
- package/icc-api/api/{IccSecureDelegationKeyMapApi.js → internal/IccSecureDelegationKeyMapApi.js} +5 -5
- package/icc-api/api/internal/IccSecureDelegationKeyMapApi.js.map +1 -0
- package/icc-api/model/PaginatedListInsurance.d.ts +20 -0
- package/icc-api/model/PaginatedListInsurance.js +10 -0
- package/icc-api/model/PaginatedListInsurance.js.map +1 -0
- package/icc-api/model/User.d.ts +19 -0
- package/icc-api/model/User.js +6 -0
- package/icc-api/model/User.js.map +1 -1
- package/icc-api/model/internal/ExchangeData.d.ts +20 -4
- package/icc-api/model/internal/ExchangeData.js +8 -2
- package/icc-api/model/internal/ExchangeData.js.map +1 -1
- package/icc-api/model/internal/RecoveryData.d.ts +47 -0
- package/icc-api/model/internal/RecoveryData.js +34 -0
- package/icc-api/model/internal/RecoveryData.js.map +1 -0
- package/icc-x-api/auth/JwtBridgedAuthService.d.ts +1 -0
- package/icc-x-api/auth/JwtBridgedAuthService.js +10 -3
- package/icc-x-api/auth/JwtBridgedAuthService.js.map +1 -1
- package/icc-x-api/crypto/BaseExchangeDataManager.d.ts +37 -25
- package/icc-x-api/crypto/BaseExchangeDataManager.js +123 -64
- package/icc-x-api/crypto/BaseExchangeDataManager.js.map +1 -1
- package/icc-x-api/crypto/CryptoPrimitives.d.ts +3 -0
- package/icc-x-api/crypto/CryptoPrimitives.js +5 -0
- package/icc-x-api/crypto/CryptoPrimitives.js.map +1 -1
- package/icc-x-api/crypto/DelegationsDeAnonymization.js +1 -1
- package/icc-x-api/crypto/DelegationsDeAnonymization.js.map +1 -1
- package/icc-x-api/crypto/ExchangeDataManager.js +14 -6
- package/icc-x-api/crypto/ExchangeDataManager.js.map +1 -1
- package/icc-x-api/crypto/ExchangeDataMapManager.d.ts +1 -1
- package/icc-x-api/crypto/ExchangeDataMapManager.js.map +1 -1
- package/icc-x-api/crypto/HMACUtils.d.ts +10 -0
- package/icc-x-api/crypto/HMACUtils.js +48 -0
- package/icc-x-api/crypto/HMACUtils.js.map +1 -0
- package/icc-x-api/crypto/SecureDelegationsManager.js +3 -0
- package/icc-x-api/crypto/SecureDelegationsManager.js.map +1 -1
- package/icc-x-api/icc-icure-maintenance-x-api.d.ts +1 -1
- package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -1
- package/icc-x-api/icc-recovery-x-api.d.ts +0 -0
- package/icc-x-api/icc-recovery-x-api.js +2 -0
- package/icc-x-api/icc-recovery-x-api.js.map +1 -0
- package/icc-x-api/index.js +2 -2
- package/icc-x-api/index.js.map +1 -1
- package/package.json +1 -1
- package/icc-api/api/IccExchangeDataApi.js.map +0 -1
- package/icc-api/api/IccExchangeDataMapApi.js.map +0 -1
- package/icc-api/api/IccSecureDelegationKeyMapApi.js.map +0 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal this entity is meant for internal use only
|
|
3
|
+
*/
|
|
4
|
+
export declare class RecoveryData {
|
|
5
|
+
constructor(json: JSON | any);
|
|
6
|
+
id?: string;
|
|
7
|
+
rev?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Id of the data owner that this recovery data is meant for
|
|
10
|
+
*/
|
|
11
|
+
recipient: string;
|
|
12
|
+
/**
|
|
13
|
+
* Encrypted recovery data. The structure of the decrypted data depends on the [type] of the recovery data.
|
|
14
|
+
*/
|
|
15
|
+
encryptedSelf: string;
|
|
16
|
+
/**
|
|
17
|
+
* Type of the recovery data.
|
|
18
|
+
*/
|
|
19
|
+
type: RecoveryData.Type;
|
|
20
|
+
/**
|
|
21
|
+
* Timestamp (unix epoch in ms) at which this recovery data will expire. If null, this recovery data will never
|
|
22
|
+
* expire. Negative values or zero mean the data is already expired.
|
|
23
|
+
*/
|
|
24
|
+
expirationInstant?: number;
|
|
25
|
+
/**
|
|
26
|
+
* hard delete (unix epoch in ms) timestamp of the object. Filled automatically when the delete method is called.
|
|
27
|
+
*/
|
|
28
|
+
deletionDate?: number;
|
|
29
|
+
}
|
|
30
|
+
export declare namespace RecoveryData {
|
|
31
|
+
/**
|
|
32
|
+
* Represents possible types of recovery data.
|
|
33
|
+
*/
|
|
34
|
+
enum Type {
|
|
35
|
+
/**
|
|
36
|
+
* This recovery data is meant to be used to recover a keypair of the recipient. This could be for making a key
|
|
37
|
+
* available on another device, or for recovering a keypair that has been fully lost.
|
|
38
|
+
*/
|
|
39
|
+
KEYPAIR_RECOVERY = "KEYPAIR_RECOVERY",
|
|
40
|
+
/**
|
|
41
|
+
* This recovery data is meant to be used to recover an exchange key of the recipient. The main purpose of this
|
|
42
|
+
* is to allow data owners to share data with other data owners that do not have created a keypair yet, but it
|
|
43
|
+
* can also be used as part of the give-access-back recovery mechanism.
|
|
44
|
+
*/
|
|
45
|
+
EXCHANGE_KEY_RECOVERY = "EXCHANGE_KEY_RECOVERY"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RecoveryData = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @internal this entity is meant for internal use only
|
|
6
|
+
*/
|
|
7
|
+
class RecoveryData {
|
|
8
|
+
constructor(json) {
|
|
9
|
+
if (!json.recipient || !json.encryptedSelf || !json.type)
|
|
10
|
+
throw new Error(`Recovery data json is missing required properties.\n${JSON.stringify(json)}`);
|
|
11
|
+
Object.assign(this, json);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.RecoveryData = RecoveryData;
|
|
15
|
+
(function (RecoveryData) {
|
|
16
|
+
/**
|
|
17
|
+
* Represents possible types of recovery data.
|
|
18
|
+
*/
|
|
19
|
+
let Type;
|
|
20
|
+
(function (Type) {
|
|
21
|
+
/**
|
|
22
|
+
* This recovery data is meant to be used to recover a keypair of the recipient. This could be for making a key
|
|
23
|
+
* available on another device, or for recovering a keypair that has been fully lost.
|
|
24
|
+
*/
|
|
25
|
+
Type["KEYPAIR_RECOVERY"] = "KEYPAIR_RECOVERY";
|
|
26
|
+
/**
|
|
27
|
+
* This recovery data is meant to be used to recover an exchange key of the recipient. The main purpose of this
|
|
28
|
+
* is to allow data owners to share data with other data owners that do not have created a keypair yet, but it
|
|
29
|
+
* can also be used as part of the give-access-back recovery mechanism.
|
|
30
|
+
*/
|
|
31
|
+
Type["EXCHANGE_KEY_RECOVERY"] = "EXCHANGE_KEY_RECOVERY";
|
|
32
|
+
})(Type = RecoveryData.Type || (RecoveryData.Type = {}));
|
|
33
|
+
})(RecoveryData = exports.RecoveryData || (exports.RecoveryData = {}));
|
|
34
|
+
//# sourceMappingURL=RecoveryData.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecoveryData.js","sourceRoot":"","sources":["../../../../icc-api/model/internal/RecoveryData.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,YAAY;IACvB,YAAY,IAAgB;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,IAAI;YACtD,MAAM,IAAI,KAAK,CAAC,uDAAuD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChG,MAAM,CAAC,MAAM,CAAC,IAAoB,EAAE,IAAI,CAAC,CAAA;IAC3C,CAAC;CAyBF;AA9BD,oCA8BC;AACD,WAAiB,YAAY;IAC3B;;OAEG;IACH,IAAY,IAYX;IAZD,WAAY,IAAI;QACd;;;WAGG;QACH,6CAAqC,CAAA;QACrC;;;;WAIG;QACH,uDAA+C,CAAA;IACjD,CAAC,EAZW,IAAI,GAAJ,iBAAI,KAAJ,iBAAI,QAYf;AACH,CAAC,EAjBgB,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAiB5B","sourcesContent":["/**\n * @internal this entity is meant for internal use only\n */\nexport class RecoveryData {\n constructor(json: JSON | any) {\n if (!json.recipient || !json.encryptedSelf || !json.type)\n throw new Error(`Recovery data json is missing required properties.\\n${JSON.stringify(json)}`)\n Object.assign(this as RecoveryData, json)\n }\n\n id?: string\n rev?: string\n /**\n * Id of the data owner that this recovery data is meant for\n */\n recipient!: string\n /**\n * Encrypted recovery data. The structure of the decrypted data depends on the [type] of the recovery data.\n */\n encryptedSelf!: string\n /**\n * Type of the recovery data.\n */\n type!: RecoveryData.Type\n /**\n * Timestamp (unix epoch in ms) at which this recovery data will expire. If null, this recovery data will never\n * expire. Negative values or zero mean the data is already expired.\n */\n expirationInstant?: number\n /**\n * hard delete (unix epoch in ms) timestamp of the object. Filled automatically when the delete method is called.\n */\n deletionDate?: number\n}\nexport namespace RecoveryData {\n /**\n * Represents possible types of recovery data.\n */\n export enum Type {\n /**\n * This recovery data is meant to be used to recover a keypair of the recipient. This could be for making a key\n * available on another device, or for recovering a keypair that has been fully lost.\n */\n KEYPAIR_RECOVERY = 'KEYPAIR_RECOVERY',\n /**\n * This recovery data is meant to be used to recover an exchange key of the recipient. The main purpose of this\n * is to allow data owners to share data with other data owners that do not have created a keypair yet, but it\n * can also be used as part of the give-access-back recovery mechanism.\n */\n EXCHANGE_KEY_RECOVERY = 'EXCHANGE_KEY_RECOVERY',\n }\n}\n"]}
|
|
@@ -20,6 +20,7 @@ export declare class JwtBridgedAuthService implements AuthService {
|
|
|
20
20
|
token: string;
|
|
21
21
|
refreshToken: string;
|
|
22
22
|
} | undefined>;
|
|
23
|
+
getJWT(): Promise<string | undefined>;
|
|
23
24
|
getAuthHeaders(): Promise<Array<Header>>;
|
|
24
25
|
private _refreshAuthJwt;
|
|
25
26
|
private _loginAndGetTokens;
|
|
@@ -32,7 +32,7 @@ class JwtBridgedAuthService {
|
|
|
32
32
|
getIcureTokens() {
|
|
33
33
|
return this.getAuthHeaders().then(() => this._currentPromise.then(({ authJwt, refreshJwt }) => ({ token: authJwt, refreshToken: refreshJwt })));
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
getJWT() {
|
|
36
36
|
return __awaiter(this, void 0, void 0, function* () {
|
|
37
37
|
return this._currentPromise
|
|
38
38
|
.then(({ authJwt, refreshJwt }) => {
|
|
@@ -52,8 +52,15 @@ class JwtBridgedAuthService {
|
|
|
52
52
|
throw this._error;
|
|
53
53
|
}
|
|
54
54
|
return this._currentPromise;
|
|
55
|
-
})
|
|
56
|
-
|
|
55
|
+
}).then(({ authJwt }) => {
|
|
56
|
+
return authJwt;
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
getAuthHeaders() {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
return this.getJWT()
|
|
63
|
+
.then((authJwt) => {
|
|
57
64
|
return [new XHR_1.XHR.Header('Authorization', `Bearer ${authJwt}`)];
|
|
58
65
|
});
|
|
59
66
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JwtBridgedAuthService.js","sourceRoot":"","sources":["../../../icc-x-api/auth/JwtBridgedAuthService.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,+CAA2C;AAE3C,2EAAuE;AAEvE,oCAA8B;AAE9B,IAAO,QAAQ,GAAG,SAAG,CAAC,QAAQ,CAAA;AAE9B;;GAEG;AACH,MAAa,qBAAqB;IAIhC,YACU,OAAmB,EACnB,QAAgB,EAChB,QAAgB,EAChB,mBAAqD,EAAE;QAHvD,YAAO,GAAP,OAAO,CAAY;QACnB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,qBAAgB,GAAhB,gBAAgB,CAAuC;QAPzD,WAAM,GAAiB,IAAI,CAAA;QAC3B,oBAAe,GAAuD,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAO9F,CAAC;IAEJ,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAiB,CAAC,CAAA;IAC9D,CAAC;IACD,cAAc;QACZ,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,OAAQ,EAAE,YAAY,EAAE,UAAW,EAAE,CAAC,CAAC,CAAC,CAAA;IACnJ,CAAC;IAEK,
|
|
1
|
+
{"version":3,"file":"JwtBridgedAuthService.js","sourceRoot":"","sources":["../../../icc-x-api/auth/JwtBridgedAuthService.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthService } from './AuthService'\nimport { XHR } from '../../icc-api/api/XHR'\nimport { IccAuthApi, OAuthThirdParty } from '../../icc-api'\nimport { LoginCredentials } from '../../icc-api/model/LoginCredentials'\nimport Header = XHR.Header\nimport { a2b } from '../utils'\nimport { AuthenticationResponse } from '../../icc-api/model/AuthenticationResponse'\nimport XHRError = XHR.XHRError\n\n/**\n * Differs from JwtAuthService in that it can create new refresh tokens if the old one is expired\n */\nexport class JwtBridgedAuthService implements AuthService {\n private _error: Error | null = null\n private _currentPromise: Promise<{ authJwt?: string; refreshJwt?: string }> = Promise.resolve({})\n\n constructor(\n private authApi: IccAuthApi,\n private username: string,\n private password: string,\n private thirdPartyTokens: { [thirdParty: string]: string } = {}\n ) {}\n\n get refreshToken(): Promise<string | undefined> {\n return this._currentPromise.then((x) => x.refreshJwt as any)\n }\n getIcureTokens(): Promise<{ token: string; refreshToken: string } | undefined> {\n return this.getAuthHeaders().then(() => this._currentPromise.then(({ authJwt, refreshJwt }) => ({ token: authJwt!, refreshToken: refreshJwt! })))\n }\n\n async getJWT(): Promise<string | undefined> {\n return this._currentPromise\n .then(({ authJwt, refreshJwt }) => {\n if (!authJwt || this._isJwtInvalidOrExpired(authJwt)) {\n // If it does not have the JWT, tries to get it\n // If the JWT is expired, tries to refresh it\n\n this._currentPromise = this._refreshAuthJwt(refreshJwt).then((updatedTokens) => {\n // If here the token is null,\n // it goes in a suspension status\n if (!updatedTokens.authJwt) {\n throw new Error('Your iCure back-end version does not support JWT authentication')\n }\n\n return updatedTokens\n })\n } else if (!!this._error) {\n throw this._error\n }\n return this._currentPromise\n }).then(({authJwt}) => {\n return authJwt\n })\n }\n\n async getAuthHeaders(): Promise<Array<Header>> {\n return this.getJWT()\n .then((authJwt) => {\n return [new XHR.Header('Authorization', `Bearer ${authJwt}`)]\n })\n }\n\n private async _refreshAuthJwt(refreshJwt: string | undefined): Promise<{ authJwt?: string; refreshJwt?: string }> {\n // If I do not have a refresh JWT or the refresh JWT is expired,\n // I have to log in again\n if (!refreshJwt || this._isJwtInvalidOrExpired(refreshJwt)) {\n return this._loginAndGetTokens()\n } else {\n return this.authApi.refreshAuthenticationJWT(refreshJwt).then((refreshResponse) => ({\n authJwt: refreshResponse.token,\n refreshJwt: refreshJwt,\n }))\n }\n }\n\n private async _loginAndGetTokens(): Promise<{ authJwt?: string; refreshJwt?: string }> {\n let authResponse: AuthenticationResponse | undefined\n let firstError: XHRError | undefined\n if (this.username && this.password) {\n try {\n authResponse = await this.authApi.login(\n new LoginCredentials({\n username: this.username,\n password: this.password,\n })\n )\n } catch (e) {\n firstError = e as XHRError\n }\n }\n if (!authResponse) {\n authResponse = await (Object.entries(this.thirdPartyTokens) as [OAuthThirdParty, string][]).reduce(async (acc, [thirdParty, token]) => {\n const prev = await acc\n return (\n prev ??\n (token\n ? this.authApi.loginWithThirdPartyToken(thirdParty, token).catch((e) => {\n if (!firstError) {\n firstError = e as XHRError\n }\n return Promise.resolve() as Promise<undefined>\n })\n : undefined)\n )\n }, Promise.resolve() as Promise<AuthenticationResponse | undefined>)\n }\n\n if (!authResponse) {\n if (firstError) throw firstError\n throw new XHRError('', 'Unknown error', 401, 'Unauthorized', new Headers())\n }\n\n return {\n authJwt: authResponse.token,\n refreshJwt: authResponse.refreshToken,\n }\n }\n\n private _isJwtInvalidOrExpired(jwt: string): boolean {\n const parts = jwt.split('.')\n if (parts.length !== 3) {\n return true\n }\n const payload = this._base64Decode(parts[1])\n // Using the 'exp' string is safe to use as it is part of the JWT RFC and cannot be modified by us.\n return !('exp' in payload) || payload['exp'] * 1000 < new Date().getTime()\n }\n\n private _base64Decode(encodedString: string): any {\n return JSON.parse(a2b(encodedString))\n }\n\n invalidateHeader(error: Error): void {\n this._error = error\n }\n\n isInErrorState(): boolean {\n return !!this._error\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IccDataOwnerXApi } from '../icc-data-owner-x-api';
|
|
2
2
|
import { KeyPair } from './RSA';
|
|
3
3
|
import { ExchangeData } from '../../icc-api/model/internal/ExchangeData';
|
|
4
|
-
import { IccExchangeDataApi } from '../../icc-api/api/IccExchangeDataApi';
|
|
4
|
+
import { IccExchangeDataApi } from '../../icc-api/api/internal/IccExchangeDataApi';
|
|
5
5
|
import { CryptoPrimitives } from './CryptoPrimitives';
|
|
6
6
|
/**
|
|
7
7
|
* @internal this class is intended for internal use only and may be modified without notice
|
|
@@ -35,27 +35,27 @@ export declare class BaseExchangeDataManager {
|
|
|
35
35
|
* @return the exchange data with the provided id or undefined if no exchange data with such id could be found.
|
|
36
36
|
*/
|
|
37
37
|
getExchangeDataById(exchangeDataId: string): Promise<ExchangeData | undefined>;
|
|
38
|
-
/**
|
|
39
|
-
* Filters exchange data returning only the instances that could be verified using their signature and the provided verification
|
|
40
|
-
* keys.
|
|
41
|
-
* Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
|
|
42
|
-
* will always be unverified.
|
|
43
|
-
* @param exchangeData the exchange data to verify.
|
|
44
|
-
* @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
|
|
45
|
-
* @return the exchange data which could be verified given his signature and the available verification keys.
|
|
46
|
-
* @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
|
|
47
|
-
*/
|
|
48
|
-
filterVerifiedExchangeData(exchangeData: ExchangeData[], getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>): Promise<ExchangeData[]>;
|
|
49
38
|
/**
|
|
50
39
|
* Verifies the authenticity of the exchange data by checking the signature.
|
|
51
40
|
* Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
|
|
52
41
|
* will always be unverified.
|
|
53
|
-
* @param
|
|
42
|
+
* @param data collects the following information about the exchange data being verified:
|
|
43
|
+
* - exchangeData the exchange data to verify.
|
|
44
|
+
* - decryptedAccessControlSecret the access control secret decrypted from the exchange data.
|
|
45
|
+
* - decryptedExchangeKey the exchange key decrypted from the exchange data.
|
|
46
|
+
* - decryptedSharedSignatureKey the shared signature key decrypted from the exchange data.
|
|
54
47
|
* @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
|
|
48
|
+
* @param verifyAsDelegator if true the method will also verify that the hmac key used for the signature was created by the delegator of the
|
|
49
|
+
* exchange data. If true and the data was not created by the current data owner this method will return false.
|
|
55
50
|
* @return the exchange data which could be verified given his signature and the available verification keys.
|
|
56
51
|
* @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
|
|
57
52
|
*/
|
|
58
|
-
verifyExchangeData(
|
|
53
|
+
verifyExchangeData(data: {
|
|
54
|
+
exchangeData: ExchangeData;
|
|
55
|
+
decryptedAccessControlSecret: string;
|
|
56
|
+
decryptedExchangeKey: CryptoKey;
|
|
57
|
+
decryptedSharedSignatureKey: CryptoKey;
|
|
58
|
+
}, getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>, verifyAsDelegator: boolean): Promise<boolean>;
|
|
59
59
|
/**
|
|
60
60
|
* Extracts and decrypts the access control secret from the provided exchange data.
|
|
61
61
|
* These need to be hashed together with the entity class and confidentiality level in order to get the actual access control key
|
|
@@ -86,6 +86,20 @@ export declare class BaseExchangeDataManager {
|
|
|
86
86
|
successfulDecryptions: CryptoKey[];
|
|
87
87
|
failedDecryptions: ExchangeData[];
|
|
88
88
|
}>;
|
|
89
|
+
/**
|
|
90
|
+
* Extract and decrypts the shared signature key from the provided exchange data.
|
|
91
|
+
* @param exchangeData the exchange data from which to extract exchange keys.
|
|
92
|
+
* @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.
|
|
93
|
+
* @return an object composed of:
|
|
94
|
+
* - successfulDecryptions: array containing the successfully decrypted exchange keys.
|
|
95
|
+
* - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).
|
|
96
|
+
*/
|
|
97
|
+
tryDecryptSharedSignatureKeys(exchangeData: ExchangeData[], decryptionKeys: {
|
|
98
|
+
[publicKeyFingerprint: string]: KeyPair<CryptoKey>;
|
|
99
|
+
}): Promise<{
|
|
100
|
+
successfulDecryptions: CryptoKey[];
|
|
101
|
+
failedDecryptions: ExchangeData[];
|
|
102
|
+
}>;
|
|
89
103
|
private tryDecryptExchangeData;
|
|
90
104
|
private tryDecrypt;
|
|
91
105
|
/**
|
|
@@ -113,15 +127,9 @@ export declare class BaseExchangeDataManager {
|
|
|
113
127
|
* where one of the data owners involved in the exchange data has lost one of his keys.
|
|
114
128
|
* If the content of the exchange data could not be decrypted using the provided keys the method will not update anything and will return undefined.
|
|
115
129
|
* This method assumes that the new encryption keys have been verified.
|
|
116
|
-
* If the current data owner is also the delegator of the provided exchange data and at least one of the verification keys can be used to
|
|
117
|
-
* validate the current exchange data then the signature will be updated using the signature keys.
|
|
118
|
-
* Instead, if the current data owner is not the delegator of the provided exchange data, or the exchange data could not be verified using
|
|
119
|
-
* the provided verification keys then the updated exchange data will become unverified, and won't ever be verifiable again.
|
|
120
130
|
* @param exchangeData exchange data to update.
|
|
121
131
|
* @param decryptionKeys keys to use to extract the content of the exchange data which will be shared with the new keys.
|
|
122
|
-
* @param signatureKeys keys to use for the new signature of the updated exchange data.
|
|
123
132
|
* @param newEncryptionKeys new keys to add to the exchange data.
|
|
124
|
-
* @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
|
|
125
133
|
* @return the updated exchange data, and its decrypted exchange key and access control secret, or undefined if the exchange data content could not
|
|
126
134
|
* be decrypted and the exchange data could not be updated.
|
|
127
135
|
*/
|
|
@@ -129,18 +137,22 @@ export declare class BaseExchangeDataManager {
|
|
|
129
137
|
[publicKeyFingerprint: string]: KeyPair<CryptoKey>;
|
|
130
138
|
}, newEncryptionKeys: {
|
|
131
139
|
[keyPairFingerprint: string]: CryptoKey;
|
|
132
|
-
}
|
|
133
|
-
[keyPairFingerprint: string]: CryptoKey;
|
|
134
|
-
}, getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>): Promise<{
|
|
140
|
+
}): Promise<{
|
|
135
141
|
exchangeData: ExchangeData;
|
|
136
142
|
exchangeKey: CryptoKey;
|
|
137
143
|
accessControlSecret: string;
|
|
138
144
|
} | undefined>;
|
|
139
|
-
private
|
|
145
|
+
private bytesToSignForSharedSignature;
|
|
146
|
+
private bytesToSignForDelegatorSignature;
|
|
140
147
|
private generateExchangeKey;
|
|
141
148
|
private importExchangeKey;
|
|
149
|
+
private generateSharedSignatureKey;
|
|
150
|
+
private importSharedSignatureKey;
|
|
142
151
|
private generateAccessControlSecret;
|
|
143
152
|
private importAccessControlSecret;
|
|
144
153
|
private encryptDataWithKeys;
|
|
145
|
-
private
|
|
154
|
+
private signDataWithDelegatorKeys;
|
|
155
|
+
private verifyDelegatorSignature;
|
|
156
|
+
private signDataWithSharedKey;
|
|
157
|
+
private verifyDataWithSharedKey;
|
|
146
158
|
}
|
|
@@ -78,47 +78,41 @@ class BaseExchangeDataManager {
|
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Filters exchange data returning only the instances that could be verified using their signature and the provided verification
|
|
83
|
-
* keys.
|
|
84
|
-
* Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
|
|
85
|
-
* will always be unverified.
|
|
86
|
-
* @param exchangeData the exchange data to verify.
|
|
87
|
-
* @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
|
|
88
|
-
* @return the exchange data which could be verified given his signature and the available verification keys.
|
|
89
|
-
* @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
|
|
90
|
-
*/
|
|
91
|
-
filterVerifiedExchangeData(exchangeData, getVerificationKey) {
|
|
92
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
-
const verified = [];
|
|
94
|
-
for (const ed of exchangeData) {
|
|
95
|
-
if (yield this.verifyExchangeData(ed, (x) => getVerificationKey(x)))
|
|
96
|
-
verified.push(ed);
|
|
97
|
-
}
|
|
98
|
-
return verified;
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
81
|
/**
|
|
102
82
|
* Verifies the authenticity of the exchange data by checking the signature.
|
|
103
83
|
* Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
|
|
104
84
|
* will always be unverified.
|
|
105
|
-
* @param
|
|
85
|
+
* @param data collects the following information about the exchange data being verified:
|
|
86
|
+
* - exchangeData the exchange data to verify.
|
|
87
|
+
* - decryptedAccessControlSecret the access control secret decrypted from the exchange data.
|
|
88
|
+
* - decryptedExchangeKey the exchange key decrypted from the exchange data.
|
|
89
|
+
* - decryptedSharedSignatureKey the shared signature key decrypted from the exchange data.
|
|
106
90
|
* @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
|
|
91
|
+
* @param verifyAsDelegator if true the method will also verify that the hmac key used for the signature was created by the delegator of the
|
|
92
|
+
* exchange data. If true and the data was not created by the current data owner this method will return false.
|
|
107
93
|
* @return the exchange data which could be verified given his signature and the available verification keys.
|
|
108
94
|
* @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
|
|
109
95
|
*/
|
|
110
|
-
verifyExchangeData(
|
|
96
|
+
verifyExchangeData(data, getVerificationKey, verifyAsDelegator) {
|
|
111
97
|
return __awaiter(this, void 0, void 0, function* () {
|
|
112
|
-
|
|
113
|
-
if (exchangeData.delegator !== dataOwnerId)
|
|
98
|
+
if (verifyAsDelegator && data.exchangeData.delegator !== (yield this.dataOwnerApi.getCurrentDataOwnerId()))
|
|
114
99
|
return false;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
100
|
+
if (verifyAsDelegator && !(yield this.verifyDelegatorSignature(data.exchangeData, data.decryptedSharedSignatureKey, getVerificationKey)))
|
|
101
|
+
return false;
|
|
102
|
+
const sharedSignatureData = yield this.bytesToSignForSharedSignature({
|
|
103
|
+
decryptedAccessControlSecret: data.decryptedAccessControlSecret,
|
|
104
|
+
decryptedExchangeKey: data.decryptedExchangeKey,
|
|
105
|
+
delegator: data.exchangeData.delegator,
|
|
106
|
+
delegate: data.exchangeData.delegate,
|
|
107
|
+
publicKeysFingerprintsV2: [
|
|
108
|
+
...new Set([
|
|
109
|
+
...Object.keys(data.exchangeData.exchangeKey),
|
|
110
|
+
...Object.keys(data.exchangeData.accessControlSecret),
|
|
111
|
+
...Object.keys(data.exchangeData.sharedSignatureKey),
|
|
112
|
+
]),
|
|
113
|
+
],
|
|
114
|
+
});
|
|
115
|
+
return yield this.verifyDataWithSharedKey(sharedSignatureData, data.decryptedSharedSignatureKey, data.exchangeData.sharedSignature);
|
|
122
116
|
});
|
|
123
117
|
}
|
|
124
118
|
/**
|
|
@@ -149,6 +143,19 @@ class BaseExchangeDataManager {
|
|
|
149
143
|
return yield this.tryDecryptExchangeData(exchangeData, decryptionKeys, (ed) => ed.exchangeKey, (d) => this.importExchangeKey(new Uint8Array(d)));
|
|
150
144
|
});
|
|
151
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Extract and decrypts the shared signature key from the provided exchange data.
|
|
148
|
+
* @param exchangeData the exchange data from which to extract exchange keys.
|
|
149
|
+
* @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.
|
|
150
|
+
* @return an object composed of:
|
|
151
|
+
* - successfulDecryptions: array containing the successfully decrypted exchange keys.
|
|
152
|
+
* - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).
|
|
153
|
+
*/
|
|
154
|
+
tryDecryptSharedSignatureKeys(exchangeData, decryptionKeys) {
|
|
155
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
156
|
+
return yield this.tryDecryptExchangeData(exchangeData, decryptionKeys, (ed) => ed.sharedSignatureKey, (d) => this.importSharedSignatureKey(new Uint8Array(d)));
|
|
157
|
+
});
|
|
158
|
+
}
|
|
152
159
|
tryDecryptExchangeData(exchangeData, decryptionKeys, encryptedDataSelector, unmarshalDecrypted) {
|
|
153
160
|
return __awaiter(this, void 0, void 0, function* () {
|
|
154
161
|
const successfulDecryptions = [];
|
|
@@ -180,7 +187,7 @@ class BaseExchangeDataManager {
|
|
|
180
187
|
try {
|
|
181
188
|
const key = (_a = decryptionKeysWithV2Fp[fp]) === null || _a === void 0 ? void 0 : _a.privateKey;
|
|
182
189
|
if (key)
|
|
183
|
-
return
|
|
190
|
+
return yield this.primitives.RSA.decrypt(key, (0, utils_1.b64_2ua)(encrypted));
|
|
184
191
|
}
|
|
185
192
|
catch (e) {
|
|
186
193
|
// Try with another key
|
|
@@ -205,17 +212,29 @@ class BaseExchangeDataManager {
|
|
|
205
212
|
}
|
|
206
213
|
const exchangeKey = yield this.generateExchangeKey();
|
|
207
214
|
const accessControlSecret = yield this.generateAccessControlSecret();
|
|
215
|
+
const sharedSignatureKey = yield this.generateSharedSignatureKey();
|
|
208
216
|
const encryptedExchangeKey = yield this.encryptDataWithKeys(exchangeKey.rawBytes, encryptionKeys);
|
|
209
217
|
const encryptedAccessControlSecret = yield this.encryptDataWithKeys(accessControlSecret.rawBytes, encryptionKeys);
|
|
218
|
+
const encryptedSharedSignatureKey = yield this.encryptDataWithKeys(sharedSignatureKey.rawBytes, encryptionKeys);
|
|
210
219
|
const baseExchangeData = {
|
|
211
220
|
id: (_a = optionalAttributes.id) !== null && _a !== void 0 ? _a : this.primitives.randomUuid(),
|
|
212
221
|
delegator: yield this.dataOwnerApi.getCurrentDataOwnerId(),
|
|
213
222
|
delegate: delegateId,
|
|
214
223
|
exchangeKey: encryptedExchangeKey,
|
|
215
224
|
accessControlSecret: encryptedAccessControlSecret,
|
|
225
|
+
sharedSignatureKey: encryptedSharedSignatureKey,
|
|
216
226
|
};
|
|
217
|
-
const
|
|
218
|
-
|
|
227
|
+
const sharedSignature = yield this.signDataWithSharedKey(yield this.bytesToSignForSharedSignature({
|
|
228
|
+
delegate: baseExchangeData.delegate,
|
|
229
|
+
delegator: baseExchangeData.delegator,
|
|
230
|
+
decryptedAccessControlSecret: accessControlSecret.secret,
|
|
231
|
+
decryptedExchangeKey: exchangeKey.key,
|
|
232
|
+
publicKeysFingerprintsV2: Object.keys(encryptionKeys).map(utils_2.fingerprintV1toV2),
|
|
233
|
+
}), sharedSignatureKey.key);
|
|
234
|
+
const delegatorSignature = yield this.signDataWithDelegatorKeys(yield this.bytesToSignForDelegatorSignature({
|
|
235
|
+
sharedSignatureKey: sharedSignatureKey.key,
|
|
236
|
+
}), signatureKeys);
|
|
237
|
+
const exchangeData = new ExchangeData_1.ExchangeData(Object.assign(Object.assign({}, baseExchangeData), { delegatorSignature, sharedSignature }));
|
|
219
238
|
return {
|
|
220
239
|
exchangeData: yield this.api.createExchangeData(exchangeData),
|
|
221
240
|
exchangeKey: exchangeKey.key,
|
|
@@ -228,67 +247,73 @@ class BaseExchangeDataManager {
|
|
|
228
247
|
* where one of the data owners involved in the exchange data has lost one of his keys.
|
|
229
248
|
* If the content of the exchange data could not be decrypted using the provided keys the method will not update anything and will return undefined.
|
|
230
249
|
* This method assumes that the new encryption keys have been verified.
|
|
231
|
-
* If the current data owner is also the delegator of the provided exchange data and at least one of the verification keys can be used to
|
|
232
|
-
* validate the current exchange data then the signature will be updated using the signature keys.
|
|
233
|
-
* Instead, if the current data owner is not the delegator of the provided exchange data, or the exchange data could not be verified using
|
|
234
|
-
* the provided verification keys then the updated exchange data will become unverified, and won't ever be verifiable again.
|
|
235
250
|
* @param exchangeData exchange data to update.
|
|
236
251
|
* @param decryptionKeys keys to use to extract the content of the exchange data which will be shared with the new keys.
|
|
237
|
-
* @param signatureKeys keys to use for the new signature of the updated exchange data.
|
|
238
252
|
* @param newEncryptionKeys new keys to add to the exchange data.
|
|
239
|
-
* @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
|
|
240
253
|
* @return the updated exchange data, and its decrypted exchange key and access control secret, or undefined if the exchange data content could not
|
|
241
254
|
* be decrypted and the exchange data could not be updated.
|
|
242
255
|
*/
|
|
243
|
-
tryUpdateExchangeData(exchangeData, decryptionKeys, newEncryptionKeys
|
|
256
|
+
tryUpdateExchangeData(exchangeData, decryptionKeys, newEncryptionKeys) {
|
|
244
257
|
return __awaiter(this, void 0, void 0, function* () {
|
|
245
258
|
const dataOwnerId = yield this.dataOwnerApi.getCurrentDataOwnerId();
|
|
246
259
|
const rawExchangeKey = yield this.tryDecrypt(exchangeData.exchangeKey, decryptionKeys);
|
|
247
260
|
const rawAccessControlSecret = yield this.tryDecrypt(exchangeData.accessControlSecret, decryptionKeys);
|
|
248
|
-
|
|
261
|
+
const rawSharedSignatureKey = yield this.tryDecrypt(exchangeData.sharedSignatureKey, decryptionKeys);
|
|
262
|
+
if (!rawExchangeKey || !rawAccessControlSecret || !rawSharedSignatureKey)
|
|
249
263
|
return undefined;
|
|
250
264
|
const exchangeKey = yield this.importExchangeKey(new Uint8Array(rawExchangeKey));
|
|
251
265
|
const accessControlSecret = yield this.importAccessControlSecret(new Uint8Array(rawAccessControlSecret));
|
|
266
|
+
const sharedSignatureKey = yield this.importSharedSignatureKey(new Uint8Array(rawSharedSignatureKey));
|
|
252
267
|
const existingExchangeKeyEntries = new Set(Object.keys(exchangeData.exchangeKey));
|
|
253
268
|
const existingAcsEntries = new Set(Object.keys(exchangeData.accessControlSecret));
|
|
254
|
-
const
|
|
269
|
+
const existingSharedSignatureKeyEntries = new Set(Object.keys(exchangeData.sharedSignatureKey));
|
|
270
|
+
const missingEntries = Object.keys(newEncryptionKeys).filter((fp) => !existingAcsEntries.has(fp) || !existingExchangeKeyEntries.has(fp) || !existingSharedSignatureKeyEntries.has(fp));
|
|
255
271
|
if (!missingEntries.length)
|
|
256
272
|
return { exchangeData, exchangeKey, accessControlSecret };
|
|
257
273
|
const encryptionKeysForMissingEntries = missingEntries.reduce((obj, fp) => {
|
|
258
274
|
obj[fp] = newEncryptionKeys[fp];
|
|
259
275
|
return obj;
|
|
260
276
|
}, {});
|
|
261
|
-
const isVerified = exchangeData.delegator == dataOwnerId && (yield this.verifyExchangeData(exchangeData, (fp) => getVerificationKey(fp)));
|
|
262
277
|
const updatedExchangeData = _.cloneDeep(exchangeData);
|
|
263
278
|
updatedExchangeData.exchangeKey = Object.assign(Object.assign({}, exchangeData.exchangeKey), (yield this.encryptDataWithKeys(rawExchangeKey, encryptionKeysForMissingEntries)));
|
|
264
279
|
updatedExchangeData.accessControlSecret = Object.assign(Object.assign({}, exchangeData.accessControlSecret), (yield this.encryptDataWithKeys(rawAccessControlSecret, encryptionKeysForMissingEntries)));
|
|
280
|
+
updatedExchangeData.sharedSignatureKey = Object.assign(Object.assign({}, exchangeData.sharedSignatureKey), (yield this.encryptDataWithKeys(rawSharedSignatureKey, encryptionKeysForMissingEntries)));
|
|
281
|
+
const isVerified = yield this.verifyExchangeData({
|
|
282
|
+
exchangeData,
|
|
283
|
+
decryptedAccessControlSecret: accessControlSecret,
|
|
284
|
+
decryptedExchangeKey: exchangeKey,
|
|
285
|
+
decryptedSharedSignatureKey: sharedSignatureKey,
|
|
286
|
+
}, () => Promise.resolve(undefined), false);
|
|
265
287
|
if (isVerified) {
|
|
266
|
-
|
|
267
|
-
|
|
288
|
+
updatedExchangeData.sharedSignature = yield this.signDataWithSharedKey(yield this.bytesToSignForSharedSignature({
|
|
289
|
+
delegate: updatedExchangeData.delegate,
|
|
290
|
+
delegator: updatedExchangeData.delegator,
|
|
291
|
+
decryptedAccessControlSecret: accessControlSecret,
|
|
292
|
+
decryptedExchangeKey: exchangeKey,
|
|
293
|
+
publicKeysFingerprintsV2: Object.keys(updatedExchangeData.exchangeKey),
|
|
294
|
+
}), sharedSignatureKey);
|
|
268
295
|
}
|
|
269
296
|
return { exchangeData: yield this.api.modifyExchangeData(new ExchangeData_1.ExchangeData(updatedExchangeData)), exchangeKey, accessControlSecret };
|
|
270
297
|
});
|
|
271
298
|
}
|
|
272
|
-
|
|
273
|
-
// Equivalent json representations of the exchange data should provide the same bytes (even if the order of entries
|
|
274
|
-
// is different).
|
|
275
|
-
bytesToSign(exchangeData) {
|
|
299
|
+
bytesToSignForSharedSignature(data) {
|
|
276
300
|
return __awaiter(this, void 0, void 0, function* () {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
.sort()
|
|
280
|
-
.reduce((sorted, key) => {
|
|
281
|
-
return [...sorted, [key, obj[key]]];
|
|
282
|
-
}, []);
|
|
283
|
-
}
|
|
301
|
+
// Use array of array to ensure that order is preserved regardless of how the specific js implementation orders
|
|
302
|
+
// the keys of an object
|
|
284
303
|
const signObject = [
|
|
285
|
-
['delegator',
|
|
286
|
-
['delegate',
|
|
287
|
-
['exchangeKey',
|
|
288
|
-
['accessControlSecret',
|
|
304
|
+
['delegator', data.delegator],
|
|
305
|
+
['delegate', data.delegate],
|
|
306
|
+
['exchangeKey', (0, utils_1.ua2hex)(yield this.primitives.AES.exportKey(data.decryptedExchangeKey, 'raw'))],
|
|
307
|
+
['accessControlSecret', data.decryptedAccessControlSecret],
|
|
308
|
+
['publicKeysFingerprints', data.publicKeysFingerprintsV2.sort()],
|
|
289
309
|
];
|
|
290
310
|
const signJson = JSON.stringify(signObject);
|
|
291
|
-
return
|
|
311
|
+
return (0, utils_1.utf8_2ua)(signJson);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
bytesToSignForDelegatorSignature(data) {
|
|
315
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
316
|
+
return this.primitives.sha256(yield this.primitives.HMAC.exportKey(data.sharedSignatureKey));
|
|
292
317
|
});
|
|
293
318
|
}
|
|
294
319
|
// Generates a new exchange key
|
|
@@ -306,6 +331,17 @@ class BaseExchangeDataManager {
|
|
|
306
331
|
return yield this.primitives.AES.importKey('raw', decryptedBytes);
|
|
307
332
|
});
|
|
308
333
|
}
|
|
334
|
+
generateSharedSignatureKey() {
|
|
335
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
336
|
+
const key = yield this.primitives.HMAC.generateKey();
|
|
337
|
+
return { key, rawBytes: yield this.primitives.HMAC.exportKey(key) };
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
importSharedSignatureKey(decryptedBytes) {
|
|
341
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
return yield this.primitives.HMAC.importKey(decryptedBytes);
|
|
343
|
+
});
|
|
344
|
+
}
|
|
309
345
|
// Generates a new access control secret
|
|
310
346
|
generateAccessControlSecret() {
|
|
311
347
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -323,12 +359,12 @@ class BaseExchangeDataManager {
|
|
|
323
359
|
return __awaiter(this, void 0, void 0, function* () {
|
|
324
360
|
const res = {};
|
|
325
361
|
for (const [fp, key] of Object.entries(keys)) {
|
|
326
|
-
res[(0, utils_2.fingerprintIsV1)(fp) ? (0, utils_2.fingerprintV1toV2)(fp) : fp] = (0, utils_1.ua2b64)(yield this.primitives.RSA.encrypt(key,
|
|
362
|
+
res[(0, utils_2.fingerprintIsV1)(fp) ? (0, utils_2.fingerprintV1toV2)(fp) : fp] = (0, utils_1.ua2b64)(yield this.primitives.RSA.encrypt(key, new Uint8Array(rawData)));
|
|
327
363
|
}
|
|
328
364
|
return res;
|
|
329
365
|
});
|
|
330
366
|
}
|
|
331
|
-
|
|
367
|
+
signDataWithDelegatorKeys(rawData, keys) {
|
|
332
368
|
return __awaiter(this, void 0, void 0, function* () {
|
|
333
369
|
const res = {};
|
|
334
370
|
for (const [fp, key] of Object.entries(keys)) {
|
|
@@ -337,6 +373,29 @@ class BaseExchangeDataManager {
|
|
|
337
373
|
return res;
|
|
338
374
|
});
|
|
339
375
|
}
|
|
376
|
+
verifyDelegatorSignature(exchangeData, decryptedSharedSignatureKey, getVerificationKey) {
|
|
377
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
378
|
+
const delegatorSignatureData = yield this.bytesToSignForDelegatorSignature({
|
|
379
|
+
sharedSignatureKey: decryptedSharedSignatureKey,
|
|
380
|
+
});
|
|
381
|
+
for (const [fp, signature] of Object.entries(exchangeData.delegatorSignature)) {
|
|
382
|
+
const verificationKey = yield getVerificationKey(fp.slice(-32));
|
|
383
|
+
if (verificationKey && (yield this.primitives.RSA.verifySignature(verificationKey, (0, utils_1.b64_2ua)(signature), delegatorSignatureData)))
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
return false;
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
signDataWithSharedKey(rawData, key) {
|
|
390
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
391
|
+
return (0, utils_1.ua2b64)(yield this.primitives.HMAC.sign(key, new Uint8Array(rawData)));
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
verifyDataWithSharedKey(rawData, key, signature) {
|
|
395
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
396
|
+
return yield this.primitives.HMAC.verify(key, new Uint8Array(rawData), (0, utils_1.b64_2ua)(signature));
|
|
397
|
+
});
|
|
398
|
+
}
|
|
340
399
|
}
|
|
341
400
|
exports.BaseExchangeDataManager = BaseExchangeDataManager;
|
|
342
401
|
//# sourceMappingURL=BaseExchangeDataManager.js.map
|