Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3388400
D10666.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D10666.diff
View Options
diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js
--- a/lib/types/crypto-types.js
+++ b/lib/types/crypto-types.js
@@ -8,6 +8,11 @@
+ed25519: string,
+curve25519: string,
};
+const olmIdentityKeysValidator: TInterface<OLMIdentityKeys> =
+ tShape<OLMIdentityKeys>({
+ ed25519: t.String,
+ curve25519: t.String,
+ });
export type OLMPrekey = {
+curve25519: {
@@ -47,6 +52,11 @@
+primaryIdentityPublicKeys: OLMIdentityKeys,
+notificationIdentityPublicKeys: OLMIdentityKeys,
};
+export const identityKeysBlobValidator: TInterface<IdentityKeysBlob> =
+ tShape<IdentityKeysBlob>({
+ primaryIdentityPublicKeys: olmIdentityKeysValidator,
+ notificationIdentityPublicKeys: olmIdentityKeysValidator,
+ });
export type SignedIdentityKeysBlob = {
+payload: string,
diff --git a/lib/types/identity-service-types.js b/lib/types/identity-service-types.js
--- a/lib/types/identity-service-types.js
+++ b/lib/types/identity-service-types.js
@@ -1,5 +1,17 @@
// @flow
+import t, { type TInterface } from 'tcomb';
+
+import {
+ identityKeysBlobValidator,
+ type IdentityKeysBlob,
+} from './crypto-types.js';
+import {
+ type OlmSessionInitializationInfo,
+ olmSessionInitializationInfoValidator,
+} from './request-types.js';
+import { tShape } from '../utils/validation-utils.js';
+
export type UserLoginResponse = {
+userId: string,
+accessToken: string,
@@ -19,9 +31,25 @@
+oneTimeNotifPrekey: ?string,
};
+export type KeyserverKeys = {
+ +identityKeysBlob: IdentityKeysBlob,
+ +contentInitializationInfo: OlmSessionInitializationInfo,
+ +notifInitializationInfo: OlmSessionInitializationInfo,
+ +payloadSignature: string,
+ +socialProof: ?string,
+};
+export const keyserverKeysValidator: TInterface<KeyserverKeys> =
+ tShape<KeyserverKeys>({
+ identityKeysBlob: identityKeysBlobValidator,
+ contentInitializationInfo: olmSessionInitializationInfoValidator,
+ notifInitializationInfo: olmSessionInitializationInfoValidator,
+ payloadSignature: t.String,
+ socialProof: t.maybe(t.String),
+ });
+
export interface IdentityServiceClient {
+deleteUser: () => Promise<void>;
- +getKeyserverKeys: string => Promise<?OutboundKeyInfoResponse>;
+ +getKeyserverKeys: string => Promise<KeyserverKeys>;
+registerUser?: (
username: string,
password: string,
diff --git a/native/identity-service/identity-service-context-provider.react.js b/native/identity-service/identity-service-context-provider.react.js
--- a/native/identity-service/identity-service-context-provider.react.js
+++ b/native/identity-service/identity-service-context-provider.react.js
@@ -4,12 +4,14 @@
import { getOneTimeKeyArray } from 'lib/shared/crypto-utils.js';
import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
-import type {
- IdentityServiceClient,
- OutboundKeyInfoResponse,
- UserLoginResponse,
+import {
+ type IdentityServiceClient,
+ type UserLoginResponse,
+ type KeyserverKeys,
+ keyserverKeysValidator,
} from 'lib/types/identity-service-types.js';
import { ONE_TIME_KEYS_NUMBER } from 'lib/types/identity-service-types.js';
+import { assertWithValidator } from 'lib/utils/validation-utils.js';
import { getCommServicesAuthMetadataEmitter } from '../event-emitters/csa-auth-metadata-emitter.js';
import { commCoreModule, commRustModule } from '../native-modules.js';
@@ -68,7 +70,7 @@
const { deviceID, userID, accessToken } = await getAuthMetadata();
return commRustModule.deleteUser(userID, deviceID, accessToken);
},
- getKeyserverKeys: async (keyserverID: string) => {
+ getKeyserverKeys: async (keyserverID: string): Promise<KeyserverKeys> => {
const { deviceID, userID, accessToken } = await getAuthMetadata();
const result = await commRustModule.getKeyserverKeys(
userID,
@@ -76,18 +78,33 @@
accessToken,
keyserverID,
);
- const resultObject: OutboundKeyInfoResponse = JSON.parse(result);
- if (
- !resultObject.payload ||
- !resultObject.payloadSignature ||
- !resultObject.contentPrekey ||
- !resultObject.contentPrekeySignature ||
- !resultObject.notifPrekey ||
- !resultObject.notifPrekeySignature
- ) {
- throw new Error('Invalid response from Identity service');
+ const resultObject = JSON.parse(result);
+ const payload = resultObject?.payload;
+
+ const keyserverKeys = {
+ identityKeysBlob: payload ? JSON.parse(payload) : null,
+ contentInitializationInfo: {
+ prekey: resultObject?.contentPrekey,
+ prekeySignature: resultObject?.contentPrekeySignature,
+ oneTimeKey: resultObject?.oneTimeContentPrekey,
+ },
+ notifInitializationInfo: {
+ prekey: resultObject?.notifPrekey,
+ prekeySignature: resultObject?.notifPrekeySignature,
+ oneTimeKey: resultObject?.oneTimeNotifPrekey,
+ },
+ payloadSignature: resultObject?.payloadSignature,
+ socialProof: resultObject?.socialProof,
+ };
+
+ if (!keyserverKeys.contentInitializationInfo.oneTimeKey) {
+ throw new Error('Missing content one time key');
}
- return resultObject;
+ if (!keyserverKeys.notifInitializationInfo.oneTimeKey) {
+ throw new Error('Missing notif one time key');
+ }
+
+ return assertWithValidator(keyserverKeys, keyserverKeysValidator);
},
registerUser: async (username: string, password: string) => {
await commCoreModule.initializeCryptoAccount();
diff --git a/web/grpc/identity-service-client-wrapper.js b/web/grpc/identity-service-client-wrapper.js
--- a/web/grpc/identity-service-client-wrapper.js
+++ b/web/grpc/identity-service-client-wrapper.js
@@ -1,11 +1,13 @@
// @flow
import identityServiceConfig from 'lib/facts/identity-service.js';
-import type {
- IdentityServiceAuthLayer,
- IdentityServiceClient,
- OutboundKeyInfoResponse,
+import {
+ type IdentityServiceAuthLayer,
+ type IdentityServiceClient,
+ type KeyserverKeys,
+ keyserverKeysValidator,
} from 'lib/types/identity-service-types.js';
+import { assertWithValidator } from 'lib/utils/validation-utils.js';
import { VersionInterceptor, AuthInterceptor } from './interceptor.js';
import * as IdentityAuthClient from '../protobufs/identity-auth-client.cjs';
@@ -79,41 +81,49 @@
await this.authClient.deleteUser(new Empty());
};
- getKeyserverKeys: (keyserverID: string) => Promise<?OutboundKeyInfoResponse> =
- async (keyserverID: string) => {
- const client = this.authClient;
- if (!client) {
- throw new Error('Identity service client is not initialized');
- }
-
- const request = new IdentityAuthStructs.OutboundKeysForUserRequest();
- request.setUserId(keyserverID);
- const response = await client.getKeyserverKeys(request);
- const keyserverInfo = response.getKeyserverInfo();
- if (!response.hasKeyserverInfo() || !keyserverInfo) {
- return null;
- }
-
- const identityInfo = keyserverInfo.getIdentityInfo();
- const contentPreKey = keyserverInfo.getContentPrekey();
- const notifPreKey = keyserverInfo.getNotifPrekey();
-
- if (!identityInfo || !contentPreKey || !notifPreKey) {
- return null;
- }
-
- return {
- payload: identityInfo.getPayload(),
- payloadSignature: identityInfo.getPayloadSignature(),
- socialProof: identityInfo.getSocialProof(),
- contentPrekey: contentPreKey.getPrekey(),
- contentPrekeySignature: contentPreKey.getPrekeySignature(),
- notifPrekey: notifPreKey.getPrekey(),
- notifPrekeySignature: notifPreKey.getPrekeySignature(),
- oneTimeContentPrekey: keyserverInfo.getOneTimeContentPrekey(),
- oneTimeNotifPrekey: keyserverInfo.getOneTimeNotifPrekey(),
- };
+ getKeyserverKeys: (keyserverID: string) => Promise<KeyserverKeys> = async (
+ keyserverID: string,
+ ) => {
+ const client = this.authClient;
+ if (!client) {
+ throw new Error('Identity service client is not initialized');
+ }
+
+ const request = new IdentityAuthStructs.OutboundKeysForUserRequest();
+ request.setUserId(keyserverID);
+ const response = await client.getKeyserverKeys(request);
+
+ const keyserverInfo = response.getKeyserverInfo();
+ const identityInfo = keyserverInfo?.getIdentityInfo();
+ const contentPreKey = keyserverInfo?.getContentPrekey();
+ const notifPreKey = keyserverInfo?.getNotifPrekey();
+ const payload = identityInfo?.getPayload();
+
+ const keyserverKeys = {
+ identityKeysBlob: payload ? JSON.parse(payload) : null,
+ contentInitializationInfo: {
+ prekey: contentPreKey?.getPrekey(),
+ prekeySignature: contentPreKey?.getPrekeySignature(),
+ oneTimeKey: keyserverInfo?.getOneTimeContentPrekey(),
+ },
+ notifInitializationInfo: {
+ prekey: notifPreKey?.getPrekey(),
+ prekeySignature: notifPreKey?.getPrekeySignature(),
+ oneTimeKey: keyserverInfo?.getOneTimeNotifPrekey(),
+ },
+ payloadSignature: identityInfo?.getPayloadSignature(),
+ socialProof: identityInfo?.getSocialProof(),
};
+
+ if (!keyserverKeys.contentInitializationInfo.oneTimeKey) {
+ throw new Error('Missing content one time key');
+ }
+ if (!keyserverKeys.notifInitializationInfo.oneTimeKey) {
+ throw new Error('Missing notif one time key');
+ }
+
+ return assertWithValidator(keyserverKeys, keyserverKeysValidator);
+ };
}
export { IdentityServiceClientWrapper };
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 30, 2:06 PM (20 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2601222
Default Alt Text
D10666.diff (9 KB)
Attached To
Mode
D10666: [lib][native][web] Parse keyserver keys payload and validate the result
Attached
Detach File
Event Timeline
Log In to Comment