Page MenuHomePhabricator

D9940.id33580.diff
No OneTemporary

D9940.id33580.diff

diff --git a/keyserver/src/push/crypto.js b/keyserver/src/push/crypto.js
--- a/keyserver/src/push/crypto.js
+++ b/keyserver/src/push/crypto.js
@@ -1,6 +1,7 @@
// @flow
import apn from '@parse/node-apn';
+import crypto from 'crypto';
import invariant from 'invariant';
import _cloneDeep from 'lodash/fp/cloneDeep.js';
@@ -8,6 +9,7 @@
PlainTextWebNotification,
WebNotification,
} from 'lib/types/notif-types.js';
+import { toBase64URL } from 'lib/utils/base64.js';
import type {
AndroidNotification,
@@ -16,6 +18,7 @@
NotificationTargetDevice,
} from './types.js';
import { encryptAndUpdateOlmSession } from '../updaters/olm-session-updater.js';
+import { encrypt, generateKey } from '../utils/aes-crypto-utils.js';
import { getOlmUtility } from '../utils/olm-utils.js';
async function encryptIOSNotification(
@@ -378,10 +381,37 @@
return Promise.all(notificationPromises);
}
+async function encryptBlobPayload(payload: string): Promise<{
+ +encryptionKey: string,
+ +encryptedPayload: Blob,
+ +encryptedPayloadHash: string,
+}> {
+ const encryptionKey = await generateKey();
+ const encryptedPayload = await encrypt(
+ encryptionKey,
+ new TextEncoder().encode(payload),
+ );
+ const encryptedPayloadBuffer = Buffer.from(encryptedPayload);
+ const blobHashBase64 = await crypto
+ .createHash('sha256')
+ .update(encryptedPayloadBuffer)
+ .digest('base64');
+ const blobHash = toBase64URL(blobHashBase64);
+
+ const payloadBlob = new Blob([encryptedPayloadBuffer]);
+ const encryptionKeyString = Buffer.from(encryptionKey).toString('base64');
+ return {
+ encryptionKey: encryptionKeyString,
+ encryptedPayload: payloadBlob,
+ encryptedPayloadHash: blobHash,
+ };
+}
+
export {
prepareEncryptedIOSNotifications,
prepareEncryptedIOSNotificationRescind,
prepareEncryptedAndroidNotifications,
prepareEncryptedAndroidNotificationRescinds,
prepareEncryptedWebNotifications,
+ encryptBlobPayload,
};
diff --git a/keyserver/src/push/utils.js b/keyserver/src/push/utils.js
--- a/keyserver/src/push/utils.js
+++ b/keyserver/src/push/utils.js
@@ -5,12 +5,14 @@
import invariant from 'invariant';
import nodeFetch from 'node-fetch';
import type { Response } from 'node-fetch';
+import uuid from 'uuid';
import webpush from 'web-push';
import type { PlatformDetails } from 'lib/types/device-types.js';
import { threadSubscriptions } from 'lib/types/subscription-types.js';
import { threadPermissions } from 'lib/types/thread-permission-types.js';
+import { encryptBlobPayload } from './crypto.js';
import {
getAPNPushProfileForCodeVersion,
getFCMPushProfileForCodeVersion,
@@ -389,7 +391,20 @@
}
| { +blobUploadError: string },
> {
- return upload(payload);
+ const blobHolder = uuid.v4();
+ try {
+ const { encryptionKey, encryptedPayload, encryptedPayloadHash } =
+ await encryptBlobPayload(payload);
+ await upload(encryptedPayload, encryptedPayloadHash, blobHolder);
+ return {
+ blobHash: encryptedPayloadHash,
+ encryptionKey,
+ };
+ } catch (e) {
+ return {
+ blobUploadError: e.message,
+ };
+ }
}
export {
diff --git a/keyserver/src/services/blob.js b/keyserver/src/services/blob.js
--- a/keyserver/src/services/blob.js
+++ b/keyserver/src/services/blob.js
@@ -1,48 +1,21 @@
// @flow
-import crypto from 'crypto';
-import uuid from 'uuid';
-
import blobService from 'lib/facts/blob-service.js';
-import { toBase64URL } from 'lib/utils/base64.js';
import { makeBlobServiceEndpointURL } from 'lib/utils/blob-service.js';
import { getMessageForException } from 'lib/utils/errors.js';
-import { encrypt, generateKey } from '../utils/aes-crypto-utils.js';
-
-async function upload(payload: string): Promise<
- | {
- +blobHash: string,
- +encryptionKey: string,
- }
- | { +blobUploadError: string },
-> {
- const encryptionKey = await generateKey();
- const encryptedPayloadBuffer = Buffer.from(
- await encrypt(encryptionKey, new TextEncoder().encode(payload)),
- );
-
- const blobHolder = uuid.v4();
- const blobHashBase64 = await crypto
- .createHash('sha256')
- .update(encryptedPayloadBuffer)
- .digest('base64');
-
- const blobHash = toBase64URL(blobHashBase64);
-
+async function upload(blob: Blob, hash: string, holder: string): Promise<void> {
const formData = new FormData();
- const payloadBlob = new Blob([encryptedPayloadBuffer]);
-
- formData.append('blob_hash', blobHash);
- formData.append('blob_data', payloadBlob);
+ formData.append('blob_hash', hash);
+ formData.append('blob_data', blob);
const assignHolderPromise = fetch(
makeBlobServiceEndpointURL(blobService.httpEndpoints.ASSIGN_HOLDER),
{
method: blobService.httpEndpoints.ASSIGN_HOLDER.method,
body: JSON.stringify({
- holder: blobHolder,
- blob_hash: blobHash,
+ holder,
+ blob_hash: hash,
}),
headers: {
'content-type': 'application/json',
@@ -58,38 +31,31 @@
},
);
+ let assignHolderResponse, uploadBlobResponse;
try {
- const [assignHolderResponse, uploadBlobResponse] = await Promise.all([
+ [assignHolderResponse, uploadBlobResponse] = await Promise.all([
assignHolderPromise,
uploadHolderPromise,
]);
-
- if (!assignHolderResponse.ok) {
- const { status, statusText } = assignHolderResponse;
- return {
- blobUploadError: `Holder assignment failed with HTTP ${status}: ${statusText}`,
- };
- }
-
- if (!uploadBlobResponse.ok) {
- const { status, statusText } = uploadBlobResponse;
- return {
- blobUploadError: `Payload upload failed with HTTP ${status}: ${statusText}`,
- };
- }
} catch (e) {
- return {
- blobUploadError: `Payload upload failed with: ${
+ throw new Error(
+ `Payload upload failed with: ${
getMessageForException(e) ?? 'unknown error'
}`,
- };
+ );
}
- const encryptionKeyString = Buffer.from(encryptionKey).toString('base64');
- return {
- blobHash,
- encryptionKey: encryptionKeyString,
- };
+ if (!assignHolderResponse.ok) {
+ const { status, statusText } = assignHolderResponse;
+ throw new Error(
+ `Holder assignment failed with HTTP ${status}: ${statusText}`,
+ );
+ }
+
+ if (!uploadBlobResponse.ok) {
+ const { status, statusText } = uploadBlobResponse;
+ throw new Error(`Payload upload failed with HTTP ${status}: ${statusText}`);
+ }
}
export { upload };

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 24, 8:23 AM (15 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2699200
Default Alt Text
D9940.id33580.diff (6 KB)

Event Timeline