-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multisig: Connect request and SignMultisigTransaction request #458
base: master
Are you sure you want to change the base?
Conversation
08af4d0
to
08748bb
Compare
0482b2d
to
da83212
Compare
26cbddd
to
58a01c6
Compare
from participants' public keys
Missing multisig-specific UI elements
Because CSP doesn't allow inline-scripts. This required getting the types for node-forge correct, too.
Requires passing the parameters in the request to ensure generation of the correct decryption key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, quite a bit too many shortcuts have been taken, for example regarding missing i18n, unencrypted storage of private keys and omission of of relevant information in the UI.
There were also several serious security issues:
- generated RSA keys are orders of magnitude weaker than they should be, due to the way they are generated.
- (almost) arbitrary Nimiq messages are blindly signed, which can be used to impersonate the user.
- malicious apps are able to trick the Keyguard into storing and using RSA private keys known to them.
Additionally, this PR points out opportunities for further security hardening, code cleanup, code deduplication, smaller fixes, stricter parsing etc..
@@ -1,3 +1,4 @@ | |||
*.min.* | |||
src/lib/bitcoin/BitcoinJS.js | |||
src/lib/polygon/OpenGSN.js | |||
src/lib/multisig/wasm/pkg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This folder has been removed again in fbbcf06.
export type SignMultisigTransactionRequestCommon = Transform<SignTransactionRequestCommon, 'keyLabel' | 'senderLabel', { | ||
keyLabel: string, // Not optional | ||
senderLabel: string, // Not optional | ||
}> & { | ||
multisigConfig: MultisigConfig, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could also be
export type SignMultisigTransactionRequestCommon = Transform<SignTransactionRequestCommon, 'keyLabel' | 'senderLabel', { | |
keyLabel: string, // Not optional | |
senderLabel: string, // Not optional | |
}> & { | |
multisigConfig: MultisigConfig, | |
}; | |
export type SignMultisigTransactionRequestCommon = Transform< | |
SignTransactionRequestCommon, | |
'keyLabel' | 'senderLabel', | |
Required<Pick<SignTransactionRequestCommon, 'keyLabel' | 'senderLabel'>> | |
> & { | |
multisigConfig: MultisigConfig, | |
}; |
This ensures that there are no discrepancies if the original types of keyLabel
or senderLabel
were to change in SignTransactionRequestCommon
, or if they were to be removed there. Obviously, in this case this benefit is of a rather theoretical nature. I just wanted to mention this alternative.
@@ -94,6 +94,7 @@ export type BitcoinTransactionInfo = { | |||
}; | |||
|
|||
export type SignTransactionRequestLayout = 'standard' | 'checkout' | 'cashlink'; | |||
export type SignMultisigTransactionRequestLayout = 'standard'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you planning to add other layouts?
@@ -593,8 +652,11 @@ export type Result = RedirectResult | IFrameResult; | |||
// Derived Result types | |||
|
|||
export type ResultType<T extends RedirectRequest> = | |||
T extends Is<T, SignMessageRequest> | Is<T, SignTransactionRequest> ? SignatureResult : | |||
T extends Is<T, SignMessageRequest> ? SignatureResult : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should SignMessageRequest
also receive an alias SignMessageResult
for SignatureResult
, similar to SignMultisigTransactionResult
? Also in RedirectResult
above and ResultByCommand
below.
type EncryptionKeyParams = { | ||
kdf: string | ||
iterations: number | ||
keySize: number | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be used as KeyguardRequest.EncryptionKeyParams
without copying it from PublicRequest.ts
.
type EncryptionKeyParams = { | |
kdf: string | |
iterations: number | |
keySize: number | |
} | |
type EncryptionKeyParams = KeyguardRequest.EncryptionKeyParams; |
$badge.classList.add('multisig-badge', 'nq-blue-bg'); | ||
$badge.innerHTML = TemplateTags.hasVars(2)` | ||
${this._addressInfo.multisig.signers} | ||
<span class="of">of</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing i18n.
padding: 0.375rem 0.75rem; | ||
line-height: 1; | ||
border: 0.5rem solid white; | ||
word-spacing: -0.071428571em; // 1/14 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid CSS comment (should be /* 1/14 */
). But probably better as calc(-1em / 14)
anyways.
word-spacing: -0.071428571em; // 1/14 | |
word-spacing: calc(-1em / 14); |
|
||
class LoginFileAccountIcon { // eslint-disable-line no-unused-vars | ||
/** | ||
* @param {string} [address] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the address allowed to be undefined
? It's nowhere used in such a fashion.
@@ -365,6 +366,7 @@ cp -v favicon.ico dist | |||
cp -rv src/assets/* dist/assets/ | |||
cp -v src/lib/QrScannerWorker.js dist/lib/ | |||
cp -v node_modules/@nimiq/style/nimiq-style.icons.svg dist/assets/ | |||
cp -v src/lib/rsa/sandboxed/* dist/lib/rsa/sandboxed/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Integrity hashes on the js files would be good.
<div><a href="/demos/SignMultisigTransaction.html">Sign Multisig TX</a></div> | ||
<div><a href="/demos/RSAKeys.html">RSA Keys</a></div> | ||
<div><a href="/demos/ConnectAccount.html">Connect Account</a></div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These demos don't work currently.
Related: nimiq/hub#521
This PR adds two requests:
Connect
For this request, I am adding deterministic RSA key generation from the user's Key's
secret
. The public RSA key is then shared with the connected app, to be able to encrypt data that only the Keyguard can decrypt again. Encryption and decryption uses thewindow.crypto.subtle
APIs.SignMultisigRequest
Nothing special added, this uses the code from the @nimiq/core SDK to do multisig signatures.