Use the libsignal-client for curve operations

This commit is contained in:
Jack Lloyd 2021-01-27 17:39:09 -05:00 committed by GitHub
parent 1da724edf2
commit a769402c0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 67 additions and 91 deletions

View file

@ -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

View file

@ -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}/**"
]
}

View file

@ -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;

View file

@ -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
View file

@ -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;
}

View file

@ -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;
}

View file

@ -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==