Unverified Commit b8915117 authored by Hanwen Cheng's avatar Hanwen Cheng Committed by GitHub
Browse files

fix: add sign hash function (#631)

* add hash signing

* add e2e test and add more types for checking

* bump version
parent ea6a0f7a
Pipeline #94560 failed with stages
in 53 seconds
......@@ -134,8 +134,8 @@ android {
minSdkVersion 18
missingDimensionStrategy 'react-native-camera', 'general'
targetSdkVersion 28
versionCode 4300
versionName "4.3.0"
versionCode 4301
versionName "4.3.1"
ndk {
abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
}
......
......@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>4.3.0</string>
<string>4.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>4300</string>
<string>4301</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
......
{
"name": "NativeSigner",
"version": "4.3.0-beta",
"version": "4.3.-beta",
"private": true,
"license": "GPL-3.0",
"engines": {
......
......@@ -120,7 +120,6 @@ export async function processBarCode(
}
try {
console.log('txrequest raw is', txRequestData.rawData);
await parseQrData();
if (scannerStore.getUnsigned() === null) return;
await scannerStore.setData(accounts);
......
......@@ -32,8 +32,10 @@ import {
EthereumParsedData,
isEthereumCompletedParsedData,
isMultipartData,
isSubstrateCompletedParsedData,
SubstrateCompletedParsedData
isSubstrateMessageParsedData,
SubstrateCompletedParsedData,
SubstrateMessageParsedData,
SubstrateTransactionParsedData
} from 'types/scannerTypes';
import { emptyAccount } from 'utils/account';
import {
......@@ -42,7 +44,6 @@ import {
encodeNumber
} from 'utils/decoders';
import {
blake2b,
brainWalletSign,
decryptData,
ethSign,
......@@ -260,7 +261,7 @@ export default class ScannerStore extends Container<ScannerState> {
}
async setDataToSign(
signRequest: CompletedParsedData,
signRequest: SubstrateMessageParsedData | EthereumParsedData,
accountsStore: AccountsStore
): Promise<boolean> {
this.setBusy();
......@@ -271,16 +272,12 @@ export default class ScannerStore extends Container<ScannerState> {
let isOversized = false;
let dataToSign = '';
if (isSubstrateCompletedParsedData(signRequest)) {
// only Substrate payload has crypto field
if (isSubstrateMessageParsedData(signRequest)) {
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));
dataToSign = signRequest.data.data;
message = dataToSign;
} else {
message = signRequest.data.data;
......@@ -307,7 +304,7 @@ export default class ScannerStore extends Container<ScannerState> {
}
async setTXRequest(
txRequest: CompletedParsedData,
txRequest: EthereumParsedData | SubstrateTransactionParsedData,
accountsStore: AccountsStore
): Promise<boolean> {
this.setBusy();
......
......@@ -37,16 +37,32 @@ export type CompletedParsedData =
| SubstrateCompletedParsedData
| EthereumParsedData;
export type SubstrateCompletedParsedData = {
export type SubstrateCompletedParsedData =
| SubstrateTransactionParsedData
| SubstrateMessageParsedData;
export type SubstrateTransactionParsedData = {
data: {
account: string;
crypto: 'ed25519' | 'sr25519' | null;
data: Uint8Array;
genesisHash: string;
};
action: string; //"signTransaction"
action: 'signTransaction';
oversized: boolean;
isHash: boolean;
isHash: false;
};
export type SubstrateMessageParsedData = {
data: {
account: string;
crypto: 'ed25519' | 'sr25519' | null;
data: string;
genesisHash: string;
};
action: 'signData';
oversized: boolean;
isHash: true;
};
export type SubstrateMultiParsedData = {
......@@ -76,6 +92,15 @@ export function isSubstrateCompletedParsedData(
);
}
export function isSubstrateMessageParsedData(
parsedData: ParsedData | null
): parsedData is SubstrateMessageParsedData {
return (
(parsedData as SubstrateCompletedParsedData)?.data?.crypto !== undefined &&
(parsedData as SubstrateCompletedParsedData)?.action === 'signData'
);
}
export function isMultipartData(
parsedData: ParsedData | null
): parsedData is SubstrateMultiParsedData {
......
......@@ -14,7 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { hexStripPrefix, hexToU8a, u8aToHex } from '@polkadot/util';
import {
compactFromU8a,
hexStripPrefix,
hexToU8a,
u8aToHex
} from '@polkadot/util';
import { encodeAddress } from '@polkadot/util-crypto';
import { SUBSTRATE_NETWORK_LIST } from 'constants/networkSpecs';
......@@ -24,6 +29,7 @@ import {
SubstrateCompletedParsedData,
SubstrateMultiParsedData
} from 'types/scannerTypes';
import { blake2b } from 'utils/native';
/*
Example Full Raw Data
......@@ -165,27 +171,39 @@ export async function constructDataFromBytes(
const rawPayload = hexToU8a(hexPayload);
data.data.genesisHash = genesisHash;
const isOversized = rawPayload.length > 256;
let network;
const network = SUBSTRATE_NETWORK_LIST[genesisHash];
if (!network) {
throw new Error(
`Signer does not currently support a chain with genesis hash: ${genesisHash}`
);
}
switch (secondByte) {
case '00': // sign mortal extrinsic
case '02': // sign immortal extrinsic
data.action = isOversized ? 'signData' : 'signTransaction';
data.oversized = isOversized;
data.isHash = isOversized;
data.data.data = rawPayload;
network = SUBSTRATE_NETWORK_LIST[genesisHash];
if (!network) {
throw new Error(
`Signer does not currently support a chain with genesis hash: ${genesisHash}`
);
}
const [offset] = compactFromU8a(rawPayload);
const payload = rawPayload.subarray(offset);
data.data.data = isOversized
? await blake2b(u8aToHex(payload, -1, false))
: rawPayload;
data.data.account = encodeAddress(
publicKeyAsBytes,
network.prefix
); // encode to the prefix;
break;
case '01': // data is a hash
data.action = 'signData';
data.oversized = false;
data.isHash = true;
data.data.data = hexPayload;
data.data.account = encodeAddress(
publicKeyAsBytes,
network.prefix
); // default to Kusama
break;
default:
break;
......
......@@ -18,6 +18,7 @@ export enum ScanTestRequest {
SetRemarkExtrinsicKusama,
TransferExtrinsicKusama,
SetRemarkMultiPartKusama,
SetRemarkHashKusama,
SetRemarkExtrinsicPolkadot,
TransferExtrinsicPolkadot,
SetRemarkMultiPartPolkadot,
......@@ -35,6 +36,8 @@ export const scanRequestDataMap = {
'4040500000200005301025a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe969ed100001dd10696d706f7274202a2061732052656163742066726f6d20277265616374273b0a696d706f7274207b20506c6174666f726d2c205374796c6553686565742c20546578742c2056696577207d2066726f6d202772656163742d6e6174697665273b0a696d706f7274207b204e61746976654d6f64756c6573207d2066726f6d202772656163742d6e6174697665273b0a0a636f6e737420696e737472756374696f6e73203d20506c6174666f726d2e73656c656374287b0a2020696f733a2060507265737320436d642b5220746f2072656c6f61642c5c6e436d642b44206f72207368616b6520666f7220646576206d656e75602c0a2020616e64726f69643a2060446f75626c65207461702052206f6e20796f7572206b6579626f61726420746f2072656c6f61642c5c6e5368616b65206f72207072657373206d656e7520627574746f6e20666f7220646576206d656e75602c0a7d293b0a0a6578706f72742064656661756c742066756e6374696f6e204170702829207b0a0a2020636f6e7374207b205375627374726174655369676e207d203d204e61746976654d6f64756c6573207c7c207b7d3b0a2020636f6e736f6c652e6c6f672827737562737472617465207369676e206973272c205375627374726174655369676e293b0a0a202072657475726e20280a202020203c56696577207374796c653d7b7374796c65732e636f6e7461696e65727d3e0a2020202020203c54657874207374796c653d7b7374796c65732e77656c636f6d657d3e57656c636f6d6520746f205265616374204e6174697665213c2f546578743e0a2020202020203c54657874207374796c653d7b7374796c65732e696e737472756374696f6e737d3e546f2067657420737461727465642c2065646974204170702e6a733c2f546578743e0a2020202020203c54657874207374796c653d7b7374796c65732e696e737472756374696f6e737d3e7b696e737472756374696f6e737d3c2f546578743e0a202020203c2f566965773e0a2020293b0a7d0a0a636f6e7374207374796c6573203d205374796c6553686565742e637265617465287b0a2020636f6e7461696e65723a207b0a20202020666c65783a20312c0a202020206a757374696679436f6e74656e743a202763656e746572272c0a20202020616c69676e4974656d733a202763656e746572272c0a202020206261636b67726f756e64436f6c6f723a202723463546434646272c0a20207d2c0a202077656c636f6d653a207b0a20202020666f6e7453697a653a2032302c0a2020202074657874416c69676e3a202763656e746572272c0a202020206d617267696e3a2031302c0a20207d2c0ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11',
'400cd00000200010a2020696e737472756374696f6e733a207b0a2020202074657874416c69676e3a202763656e746572272c0a20202020636f6c6f723a202723333333333333272c0a202020206d617267696e426f74746f6d3a20352c0a20207d2c0a7d293b0a5500440026040000b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe5e1efdd919bb098a956954a74f230c9466af21bd3911d2f876c9a0564b1b00e1b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe0ec11ec11ec11ec11'
],
[ScanTestRequest.SetRemarkHashKusama]:
'46800000100005301015a4a03f84a19cf8ebda40e62358c592870691a9cf456138bb4829969d10fe96985b8101f780a0e5a087df2243ef1b2aa85e40907eb7be740598e515c025776a1b0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe0ec11',
[ScanTestRequest.SetRemarkExtrinsicPolkadot]:
'4990000010000530102ae8673f5391fa714f18f070edfc7db1c6ccd9ee923d0f9b061f28c5d5978162a1000010411d5010000000000000000000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3547562cde4345701ab5ff4721f720c837e2ab7eace195c141c6ff026871fc24f91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c30ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec11ec',
[ScanTestRequest.TransferExtrinsicPolkadot]:
......
......@@ -41,7 +41,7 @@ const testSignedTx = async (): Promise<void> => {
await testVisible(SignedTx.qrView);
};
const testMultiPartExtrinsic = async (): Promise<void> => {
const testSignedMessage = async (): Promise<void> => {
await testTap(SecurityHeader.scanButton);
await testUnlockPin(pinCode);
await testVisible(SignedMessage.qrView);
......@@ -75,7 +75,12 @@ describe('Signing test', () => {
it('should sign multipart request', async () => {
await launchWithScanRequest(ScanTestRequest.SetRemarkMultiPartKusama);
await testMultiPartExtrinsic();
await testSignedMessage();
});
it('should sign extrinsic hashes', async () => {
await launchWithScanRequest(ScanTestRequest.SetRemarkHashKusama);
await testSignedMessage();
});
});
......@@ -105,7 +110,7 @@ describe('Signing test', () => {
it('should sign multipart request', async () => {
await launchWithScanRequest(ScanTestRequest.SetRemarkMultiPartPolkadot);
await testMultiPartExtrinsic();
await testSignedMessage();
});
});
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment