Skip to content

Commit

Permalink
fix: Signing on Polkadot CC1 (#629)
Browse files Browse the repository at this point in the history
* fix: signing on polkadot, adjust with polkadot js

* add polkadot e2e test

* fix e2e polkadot signing test

* bump version to 4.3

* fix passworded signing problem and add e2e passworded test

* refine message details view
  • Loading branch information
hanwencheng authored May 27, 2020
1 parent d880c81 commit ea6a0f7
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 187 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ android {
minSdkVersion 18
missingDimensionStrategy 'react-native-camera', 'general'
targetSdkVersion 28
versionCode 4207
versionName "4.2.7"
versionCode 4300
versionName "4.3.0"
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
Expand Down
4 changes: 2 additions & 2 deletions ios/NativeSigner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.2.7</string>
<string>4.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>4207</string>
<string>4300</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "NativeSigner",
"version": "4.2.7-beta",
"version": "4.3.0-beta",
"private": true,
"license": "GPL-3.0",
"engines": {
Expand Down
4 changes: 2 additions & 2 deletions src/constants/networkSpecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const SubstrateNetworkKeys: {
KUSAMA_DEV:
'0x5e9679182f658e148f33d3f760f11179977398bb3da8d1f0bf7b267fe6b3ebb0',
POLKADOT:
'0x0000000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a',
'0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3',
SUBSTRATE_DEV:
'0x0d667fd278ec412cd9fccdb066f09ed5b4cfd9c9afa9eb747213acb02b1e70bc', // substrate --dev commit ac6a2a783f0e1f4a814cf2add40275730cd41be1 hosted on wss://dev-node.substrate.dev .
WESTEND: '0x4a31f96525a77959d97e267c8fc3066ca333d9ade161720e1b7de8d35ccc6bd2'
Expand Down Expand Up @@ -171,7 +171,7 @@ const substrateNetworkBase: {
[SubstrateNetworkKeys.POLKADOT]: {
color: '#e7007a',
decimals: 12,
genesisHash: null,
genesisHash: SubstrateNetworkKeys.POLKADOT,
logo: require('res/img/logos/polkadot.png'),
order: 1,
pathId: 'polkadot',
Expand Down
4 changes: 3 additions & 1 deletion src/modules/sign/components/MessageDetailsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export default function MessageDetailsCard({
}): React.ReactElement {
return (
<View style={[styles.messageContainer, style]}>
<Text style={styles.titleText}>{isHash ? 'Hash' : 'Message'}</Text>
<Text style={styles.titleText}>
{isHash ? 'Message Hash' : 'Message'}
</Text>
{isHash ? (
<Text style={styles.hashText}>{message}</Text>
) : (
Expand Down
11 changes: 10 additions & 1 deletion src/modules/sign/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export async function processBarCode(
if (seedRef === undefined || !seedRef.isValid()) {
if (sender.hasPassword) {
//need unlock with password
[password] = await unlockSeedPhraseWithPassword(
password = await unlockSeedPhraseWithPassword(
navigation,
false,
senderIdentity
Expand All @@ -93,6 +93,14 @@ export async function processBarCode(
await unlockSeedPhrase(navigation, false, senderIdentity);
}
seedRef = getSeedRef(sender.encryptedSeed, seedRefs)!;
} else {
if (sender.hasPassword) {
password = await unlockSeedPhraseWithPassword(
navigation,
true,
senderIdentity
);
}
}
// 3. sign data
if (isEthereum) {
Expand All @@ -112,6 +120,7 @@ export async function processBarCode(
}

try {
console.log('txrequest raw is', txRequestData.rawData);
await parseQrData();
if (scannerStore.getUnsigned() === null) return;
await scannerStore.setData(accounts);
Expand Down
5 changes: 2 additions & 3 deletions src/modules/unlock/screens/PinUnlockWithPassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ function PinUnlockWithPassword({

async function submit(): Promise<void> {
const { pin, password } = state;
const resolvePassword = route.params.resolve;
if (!route.params.isSeedRefValid) {
const resolveWithSeedRef = route.params.resolve;
if (pin.length >= 6 && targetIdentity) {
try {
await createSeedRef(pin);
resolveWithSeedRef(password);
resolvePassword(password);
resetState();
} catch (e) {
updateState({ password: '', pin: '', pinMismatch: true });
Expand All @@ -52,7 +52,6 @@ function PinUnlockWithPassword({
updateState({ pinTooShort: true });
}
} else {
const resolvePassword = route.params.resolve;
resolvePassword(password);
resetState();
}
Expand Down
99 changes: 42 additions & 57 deletions src/stores/ScannerStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,43 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { GenericExtrinsicPayload } from '@polkadot/types';
import {
compactFromU8a,
hexStripPrefix,
hexToU8a,
isU8a,
u8aToHex,
u8aConcat
u8aConcat,
u8aToHex
} from '@polkadot/util';
import { Container } from 'unstated';
import { ExtrinsicPayload } from '@polkadot/types/interfaces';

import AccountsStore from 'stores/AccountsStore';
import { NETWORK_LIST, NetworkProtocols } from 'constants/networkSpecs';
import { TryBrainWalletSignFunc, TrySignFunc } from 'utils/seedRefHooks';
import { isAscii } from 'utils/strings';
import {
brainWalletSign,
decryptData,
keccak,
ethSign,
substrateSign
} from 'utils/native';
import transaction, { Transaction } from 'utils/transaction';
import {
constructDataFromBytes,
asciiToHex,
encodeNumber
} from 'utils/decoders';
import AccountsStore from 'stores/AccountsStore';
import { Account, FoundAccount } from 'types/identityTypes';
import { emptyAccount } from 'utils/account';
import {
CompletedParsedData,
EthereumParsedData,
isEthereumCompletedParsedData,
isMultipartData,
isSubstrateCompletedParsedData,
SubstrateCompletedParsedData
} from 'types/scannerTypes';
import { emptyAccount } from 'utils/account';
import {
asciiToHex,
constructDataFromBytes,
encodeNumber
} from 'utils/decoders';
import {
blake2b,
brainWalletSign,
decryptData,
ethSign,
keccak,
substrateSign
} from 'utils/native';
import { TryBrainWalletSignFunc, TrySignFunc } from 'utils/seedRefHooks';
import { isAscii } from 'utils/strings';
import transaction, { Transaction } from 'utils/transaction';

type TXRequest = Record<string, any>;

Expand All @@ -70,7 +72,6 @@ type ScannerState = {
missedFrames: Array<number>;
multipartData: null | Array<Uint8Array | null>;
multipartComplete: boolean;
prehash: GenericExtrinsicPayload | null;
recipient: FoundAccount | null;
sender: FoundAccount | null;
signedData: string;
Expand All @@ -92,7 +93,6 @@ const DEFAULT_STATE = Object.freeze({
missedFrames: [],
multipartComplete: false,
multipartData: null,
prehash: null,
recipient: null,
sender: null,
signedData: '',
Expand Down Expand Up @@ -144,14 +144,6 @@ export default class ScannerStore extends Container<ScannerState> {
await this.setState({
unsignedData: parsedData
});

// set payload before it got hashed.
// signature will be generated from the hash, but we still want to display it.
if (parsedData.hasOwnProperty('preHash')) {
this.setPrehashPayload(
(parsedData as SubstrateCompletedParsedData).preHash
);
}
}

async integrateMultiPartData(): Promise<void> {
Expand Down Expand Up @@ -274,23 +266,25 @@ export default class ScannerStore extends Container<ScannerState> {
this.setBusy();

const address = signRequest.data.account;
const message = signRequest.data.data;
const crypto = (signRequest as SubstrateCompletedParsedData).data?.crypto;
const isHash =
(signRequest as SubstrateCompletedParsedData)?.isHash || false;
const isOversized =
(signRequest as SubstrateCompletedParsedData)?.oversized || false;

let message = '';
let isHash = false;
let isOversized = false;
let dataToSign = '';
const messageString = message?.toString();
if (messageString === undefined)
throw new Error('No message data to sign.');

if (crypto === 'sr25519' || crypto === 'ed25519') {
if (isSubstrateCompletedParsedData(signRequest)) {
// only Substrate payload has crypto field
dataToSign = message!.toString();
if (signRequest.data.crypto !== 'sr25519')
throw new Error('currently Parity Signer only support sr25519');
isHash = signRequest.isHash;
isOversized = signRequest.oversized;
const rawPayload = signRequest.data.data;
const [offset] = compactFromU8a(rawPayload);
const payload = rawPayload.subarray(offset);
dataToSign = await blake2b(u8aToHex(payload, -1, false));
message = dataToSign;
} else {
dataToSign = await ethSign(message!.toString());
message = signRequest.data.data;
dataToSign = await ethSign(message.toString());
}

const sender = accountsStore.getAccountByAddress(address);
Expand Down Expand Up @@ -342,11 +336,12 @@ export default class ScannerStore extends Container<ScannerState> {
// For Substrate, only sign the blake2 hash if payload bytes length > 256 bytes (handled in decoder.js).
dataToSign = await keccak(txRequest.data.rlp);
} else {
tx = txRequest.data.data;
networkKey = (txRequest.data
.data as ExtrinsicPayload)?.genesisHash.toHex();
const payloadU8a = txRequest.data.data;
const [offset] = compactFromU8a(payloadU8a);
tx = payloadU8a;
networkKey = txRequest.data.genesisHash;
recipientAddress = txRequest.data.account;
dataToSign = txRequest.data.data;
dataToSign = payloadU8a.subarray(offset);
}

const sender = await accountsStore.getById({
Expand Down Expand Up @@ -569,14 +564,4 @@ export default class ScannerStore extends Container<ScannerState> {
getMissedFrames(): number[] {
return this.state.missedFrames;
}

getPrehashPayload(): GenericExtrinsicPayload | null {
return this.state.prehash;
}

setPrehashPayload(prehash: GenericExtrinsicPayload): void {
this.setState({
prehash
});
}
}
7 changes: 3 additions & 4 deletions src/types/scannerTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ExtrinsicPayload } from '@polkadot/types/interfaces';
import { Point, Size } from 'react-native-camera/types';

export interface TxRequestData {
Expand Down Expand Up @@ -40,14 +39,14 @@ export type CompletedParsedData =

export type SubstrateCompletedParsedData = {
data: {
crypto: 'ed25519' | 'sr25519' | null;
data: ExtrinsicPayload | Uint8Array | string;
account: string;
crypto: 'ed25519' | 'sr25519' | null;
data: Uint8Array;
genesisHash: string;
};
action: string; //"signTransaction"
oversized: boolean;
isHash: boolean;
preHash: ExtrinsicPayload;
};

export type SubstrateMultiParsedData = {
Expand Down
Loading

0 comments on commit ea6a0f7

Please sign in to comment.