Use the libsignal-client for curve operations
This commit is contained in:
parent
1da724edf2
commit
a769402c0c
7 changed files with 67 additions and 91 deletions
|
@ -446,31 +446,6 @@ Signal Desktop makes use of the following open source projects.
|
|||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
## curve25519-n
|
||||
|
||||
Copyright (c) 2011 Jann Horn
|
||||
|
||||
This license and copyright notice don't apply to the file curve25519-donna.c,
|
||||
look into it.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
## dashdash
|
||||
|
||||
# This is the MIT license
|
||||
|
|
15
package.json
15
package.json
|
@ -75,7 +75,6 @@
|
|||
"classnames": "2.2.5",
|
||||
"config": "1.28.1",
|
||||
"copy-text-to-clipboard": "2.1.0",
|
||||
"curve25519-n": "https://github.com/scottnonnenberg-signal/node-curve25519.git#3e94f60bc54b2426476520d8d1a0aa835c25f5cc",
|
||||
"dashdash": "1.14.1",
|
||||
"emoji-datasource": "6.0.0",
|
||||
"emoji-datasource-apple": "6.0.0",
|
||||
|
@ -149,7 +148,8 @@
|
|||
"underscore": "1.9.0",
|
||||
"uuid": "3.3.2",
|
||||
"websocket": "1.0.28",
|
||||
"zkgroup": "https://github.com/signalapp/signal-zkgroup-node.git#2d7db946cc88492b65cc66e9aa9de0c9e664fd8d"
|
||||
"zkgroup": "https://github.com/signalapp/signal-zkgroup-node.git#2d7db946cc88492b65cc66e9aa9de0c9e664fd8d",
|
||||
"libsignal-client": "https://github.com/signalapp/libsignal-client-node.git#b6f498fa544bcce3bee0be037a7b6445d4efda45"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.7.7",
|
||||
|
@ -273,7 +273,8 @@
|
|||
"mac": {
|
||||
"asarUnpack": [
|
||||
"**/*.node",
|
||||
"node_modules/zkgroup/libzkgroup.*"
|
||||
"node_modules/zkgroup/libzkgroup.*",
|
||||
"node_modules/libsignal-client/build/*.node"
|
||||
],
|
||||
"artifactName": "${name}-mac-${version}.${ext}",
|
||||
"category": "public.app-category.social-networking",
|
||||
|
@ -298,7 +299,8 @@
|
|||
"**/*.node",
|
||||
"node_modules/spellchecker/vendor/hunspell_dictionaries",
|
||||
"node_modules/sharp",
|
||||
"node_modules/zkgroup/libzkgroup.*"
|
||||
"node_modules/zkgroup/libzkgroup.*",
|
||||
"node_modules/libsignal-client/build/*.node"
|
||||
],
|
||||
"artifactName": "${name}-win-${version}.${ext}",
|
||||
"certificateSubjectName": "Signal (Quiet Riddle Ventures, LLC)",
|
||||
|
@ -327,7 +329,8 @@
|
|||
"**/*.node",
|
||||
"node_modules/spellchecker/vendor/hunspell_dictionaries",
|
||||
"node_modules/sharp",
|
||||
"node_modules/zkgroup/libzkgroup.*"
|
||||
"node_modules/zkgroup/libzkgroup.*",
|
||||
"node_modules/libsignal-client/build/*.node"
|
||||
],
|
||||
"target": [
|
||||
"deb"
|
||||
|
@ -397,7 +400,6 @@
|
|||
"!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,__pycache__,thumbs.db,.gitignore,.gitattributes,.flowconfig,.yarn-metadata.json,.idea,appveyor.yml,.travis.yml,circle.yml,npm-debug.log,.nyc_output,yarn.lock,.yarn-integrity}",
|
||||
"node_modules/spellchecker/build/Release/*.node",
|
||||
"node_modules/websocket/build/Release/*.node",
|
||||
"node_modules/curve25519-n/build/Release/*.node",
|
||||
"node_modules/ref-napi/build/Release/*.node",
|
||||
"node_modules/ffi-napi/build/Release/*.node",
|
||||
"node_modules/socks/build/*.js",
|
||||
|
@ -409,6 +411,7 @@
|
|||
"!node_modules/@journeyapps/sqlcipher/deps/*",
|
||||
"!node_modules/@journeyapps/sqlcipher/build/*",
|
||||
"!node_modules/@journeyapps/sqlcipher/lib/binding/node-*",
|
||||
"node_modules/libsignal-client/build/*.node",
|
||||
"node_modules/ringrtc/build/${platform}/**"
|
||||
]
|
||||
}
|
||||
|
|
54
preload.js
54
preload.js
|
@ -8,7 +8,7 @@
|
|||
try {
|
||||
const electron = require('electron');
|
||||
const semver = require('semver');
|
||||
const curve = require('curve25519-n');
|
||||
const client = require('libsignal-client');
|
||||
const _ = require('lodash');
|
||||
const { installGetter, installSetter } = require('./preload_utils');
|
||||
|
||||
|
@ -484,40 +484,45 @@ try {
|
|||
}
|
||||
const externalCurve = {
|
||||
generateKeyPair: () => {
|
||||
const { privKey, pubKey } = curve.generateKeyPair();
|
||||
const privKey = client.PrivateKey.generate();
|
||||
const pubKey = privKey.getPublicKey();
|
||||
|
||||
return {
|
||||
privKey: window.Signal.Crypto.typedArrayToArrayBuffer(privKey),
|
||||
pubKey: window.Signal.Crypto.typedArrayToArrayBuffer(pubKey),
|
||||
privKey: privKey.serialize().buffer,
|
||||
pubKey: pubKey.serialize().buffer,
|
||||
};
|
||||
},
|
||||
createKeyPair: incomingKey => {
|
||||
const incomingKeyBuffer = Buffer.from(incomingKey);
|
||||
const { privKey, pubKey } = curve.createKeyPair(incomingKeyBuffer);
|
||||
const privKey = client.PrivateKey.deserialize(incomingKeyBuffer);
|
||||
const pubKey = privKey.getPublicKey();
|
||||
|
||||
return {
|
||||
privKey: window.Signal.Crypto.typedArrayToArrayBuffer(privKey),
|
||||
pubKey: window.Signal.Crypto.typedArrayToArrayBuffer(pubKey),
|
||||
privKey: privKey.serialize().buffer,
|
||||
pubKey: pubKey.serialize().buffer,
|
||||
};
|
||||
},
|
||||
calculateAgreement: (pubKey, privKey) => {
|
||||
const pubKeyBuffer = Buffer.from(pubKey);
|
||||
const privKeyBuffer = Buffer.from(privKey);
|
||||
|
||||
const buffer = curve.calculateAgreement(pubKeyBuffer, privKeyBuffer);
|
||||
|
||||
return window.Signal.Crypto.typedArrayToArrayBuffer(buffer);
|
||||
const pubKeyObj = client.PublicKey.deserialize(
|
||||
Buffer.concat([
|
||||
Buffer.from([0x05]),
|
||||
externalCurve.validatePubKeyFormat(pubKeyBuffer),
|
||||
])
|
||||
);
|
||||
const privKeyObj = client.PrivateKey.deserialize(privKeyBuffer);
|
||||
const sharedSecret = privKeyObj.agree(pubKeyObj);
|
||||
return sharedSecret.buffer;
|
||||
},
|
||||
verifySignature: (pubKey, message, signature) => {
|
||||
const pubKeyBuffer = Buffer.from(pubKey);
|
||||
const messageBuffer = Buffer.from(message);
|
||||
const signatureBuffer = Buffer.from(signature);
|
||||
|
||||
const result = curve.verifySignature(
|
||||
pubKeyBuffer,
|
||||
messageBuffer,
|
||||
signatureBuffer
|
||||
);
|
||||
const pubKeyObj = client.PublicKey.deserialize(pubKeyBuffer);
|
||||
const result = !pubKeyObj.verify(messageBuffer, signatureBuffer);
|
||||
|
||||
return result;
|
||||
},
|
||||
|
@ -525,14 +530,23 @@ try {
|
|||
const privKeyBuffer = Buffer.from(privKey);
|
||||
const messageBuffer = Buffer.from(message);
|
||||
|
||||
const buffer = curve.calculateSignature(privKeyBuffer, messageBuffer);
|
||||
|
||||
return window.Signal.Crypto.typedArrayToArrayBuffer(buffer);
|
||||
const privKeyObj = client.PrivateKey.deserialize(privKeyBuffer);
|
||||
const signature = privKeyObj.sign(messageBuffer);
|
||||
return signature.buffer;
|
||||
},
|
||||
validatePubKeyFormat: pubKey => {
|
||||
const pubKeyBuffer = Buffer.from(pubKey);
|
||||
if (
|
||||
pubKey === undefined ||
|
||||
((pubKey.byteLength !== 33 || new Uint8Array(pubKey)[0] !== 5) &&
|
||||
pubKey.byteLength !== 32)
|
||||
) {
|
||||
throw new Error('Invalid public key');
|
||||
}
|
||||
if (pubKey.byteLength === 33) {
|
||||
return pubKey.slice(1);
|
||||
}
|
||||
|
||||
return curve.validatePubKeyFormat(pubKeyBuffer);
|
||||
return pubKey;
|
||||
},
|
||||
};
|
||||
externalCurve.ECDHE = externalCurve.calculateAgreement;
|
||||
|
|
|
@ -13,7 +13,11 @@ const {
|
|||
optionalDependencies = {},
|
||||
} = require('../package.json');
|
||||
|
||||
const SKIPPED_DEPENDENCIES = new Set(['ringrtc', 'zkgroup']);
|
||||
const SKIPPED_DEPENDENCIES = new Set([
|
||||
'ringrtc',
|
||||
'zkgroup',
|
||||
'libsignal-client',
|
||||
]);
|
||||
|
||||
const rootDir = join(__dirname, '..');
|
||||
const nodeModulesPath = join(rootDir, 'node_modules');
|
||||
|
|
16
ts/curve25519-n.d.ts
vendored
16
ts/curve25519-n.d.ts
vendored
|
@ -1,16 +0,0 @@
|
|||
// Copyright 2019-2020 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
declare module 'curve25519-n' {
|
||||
export function generateKeyPair(
|
||||
privKey: Buffer
|
||||
): { pubKey: Buffer; privKey: Buffer };
|
||||
|
||||
export function calculateSignature(privKey: Buffer, message: Buffer): Buffer;
|
||||
|
||||
export function verifySignature(
|
||||
publicKey: Buffer,
|
||||
message: Buffer,
|
||||
signature: Buffer
|
||||
): Buffer;
|
||||
}
|
|
@ -1,25 +1,22 @@
|
|||
// Copyright 2019-2020 Signal Messenger, LLC
|
||||
// Copyright 2019-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { randomBytes } from 'crypto';
|
||||
import {
|
||||
calculateSignature,
|
||||
generateKeyPair,
|
||||
verifySignature,
|
||||
} from 'curve25519-n';
|
||||
import { PrivateKey, PublicKey } from 'libsignal-client';
|
||||
|
||||
export function keyPair(): Record<string, Buffer> {
|
||||
const privateKey = randomBytes(32);
|
||||
const { pubKey, privKey } = generateKeyPair(privateKey);
|
||||
const privKey = PrivateKey.generate();
|
||||
const pubKey = privKey.getPublicKey();
|
||||
|
||||
return {
|
||||
publicKey: pubKey,
|
||||
privateKey: privKey,
|
||||
publicKey: pubKey.serialize(),
|
||||
privateKey: privKey.serialize(),
|
||||
};
|
||||
}
|
||||
|
||||
export function sign(privateKey: Buffer, message: Buffer): Buffer {
|
||||
return calculateSignature(privateKey, message);
|
||||
const privKeyObj = PrivateKey.deserialize(privateKey);
|
||||
const signature = privKeyObj.sign(message);
|
||||
return signature;
|
||||
}
|
||||
|
||||
export function verify(
|
||||
|
@ -27,7 +24,7 @@ export function verify(
|
|||
message: Buffer,
|
||||
signature: Buffer
|
||||
): boolean {
|
||||
const failed = verifySignature(publicKey, message, signature);
|
||||
|
||||
return !failed;
|
||||
const pubKeyObj = PublicKey.deserialize(publicKey);
|
||||
const result = pubKeyObj.verify(message, signature);
|
||||
return result;
|
||||
}
|
||||
|
|
15
yarn.lock
15
yarn.lock
|
@ -5739,13 +5739,6 @@ currently-unhandled@^0.4.1:
|
|||
dependencies:
|
||||
array-find-index "^1.0.1"
|
||||
|
||||
"curve25519-n@https://github.com/scottnonnenberg-signal/node-curve25519.git#3e94f60bc54b2426476520d8d1a0aa835c25f5cc":
|
||||
version "1.5.0"
|
||||
resolved "https://github.com/scottnonnenberg-signal/node-curve25519.git#3e94f60bc54b2426476520d8d1a0aa835c25f5cc"
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
nan "^2.14.0"
|
||||
|
||||
cyclist@~0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
|
||||
|
@ -10290,6 +10283,12 @@ levn@~0.3.0:
|
|||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
"libsignal-client@https://github.com/signalapp/libsignal-client-node.git#b6f498fa544bcce3bee0be037a7b6445d4efda45":
|
||||
version "0.2.0"
|
||||
resolved "https://github.com/signalapp/libsignal-client-node.git#b6f498fa544bcce3bee0be037a7b6445d4efda45"
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
|
||||
lie@*:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/lie/-/lie-3.2.0.tgz#4f13f2f8bbb027d383db338c43043545791aa8dc"
|
||||
|
@ -11271,7 +11270,7 @@ nan@^2.10.0, nan@^2.11.0:
|
|||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
|
||||
integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==
|
||||
|
||||
nan@^2.12.1, nan@^2.13.2, nan@^2.14.0:
|
||||
nan@^2.12.1, nan@^2.13.2:
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
||||
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
|
||||
|
|
Loading…
Reference in a new issue