Skip to content

Commit

Permalink
fix: #426 (Payload Details When Signing Hash), #427 (Multipart Missed…
Browse files Browse the repository at this point in the history
… Frames) (#428)

* fix: show prehash image along with hash

* fix: lint

* fix: display missed frames by index

* fix: remove from missed frames list once scanned

* fix: edge case for multiple  loops

* fix: multiple loops

* fix: off by one error

* fix: asyn cscanner state clear

* chore: bump @polkadot-js deps

* fix: make tests pass

* fix: qrcodehash

* fix: blake2s -> blake2b

* fix: signing hash

* fix: hash the correct thing ffs

* fix: stray print

* fix: show payload details along with hash

* fix: stray logs

* fix: minor grumble

* make android able to sign single part

* fix: ethereum sign msg

* fix: ethereum sign msg

* fix: undeifned

* fix: prehash optional
  • Loading branch information
pmespresso authored Oct 30, 2019
1 parent f18775e commit 5c587fd
Show file tree
Hide file tree
Showing 20 changed files with 1,906 additions and 1,748 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void keccak(String data, Promise promise) {
}

@ReactMethod
public void blake2s(String data, Promise promise) {
public void blake2b(String data, Promise promise) {
try {
promise.resolve(ethkeyBlake(data));
} catch (Exception e) {
Expand Down
2 changes: 1 addition & 1 deletion ios/NativeSigner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1F426F93208D332A00CA43DB /* libRCTAnimation.a in Frameworks */,
3946D2A52364A7E700BAC371 /* libRCTActionSheet.a in Frameworks */,
3972BABE230D88B200202B52 /* libRNSecureStorage.a in Frameworks */,
391AD3F022F9D848005136A0 /* libRNCNetInfo.a in Frameworks */,
Expand All @@ -527,7 +528,6 @@
399D1B0E22DDDE1B00A815EB /* JavaScriptCore.framework in Frameworks */,
1F73EE2721777A1D00706E91 /* libsigner.a in Frameworks */,
1F426F95208D334200CA43DB /* libReact.a in Frameworks */,
1F426F93208D332A00CA43DB /* libRCTAnimation.a in Frameworks */,
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
Expand Down
2 changes: 1 addition & 1 deletion ios/NativeSigner/EthkeyBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ + (BOOL)requiresMainQueueSetup
RCT_EXTERN_METHOD(qrCodeHex:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateAddress:(NSString*)seed version:(NSUInteger*)version resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(substrateSign:(NSString*)seed message:(NSString*)message resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(blake2s:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(blake2b:(NSString*)data resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)

@end
2 changes: 1 addition & 1 deletion ios/NativeSigner/EthkeyBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class EthkeyBridge: NSObject {
}
}

@objc func blake2s(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
@objc func blake2b(_ data: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
var error: UInt32 = 0
var data_ptr = data.asPtr()
let hash_rust_str = blake(&error, &data_ptr)
Expand Down
3,260 changes: 1,609 additions & 1,651 deletions ios/main.jsbundle

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions rust/signer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use rlp::decode_list;
use rustc_hex::{ToHex, FromHex};
use tiny_keccak::Keccak;
use tiny_keccak::keccak256 as keccak;
use blake2_rfc::blake2s::blake2s;
use blake2_rfc::blake2b::blake2b;

const CRYPTO_ITERATIONS: u32 = 10240;

Expand Down Expand Up @@ -144,7 +144,7 @@ export! {
fn blake(data: &str) -> Option<String> {
let data: Vec<u8> = data.from_hex().ok()?;

Some(blake2s(32, &[], &data).as_bytes().to_hex())
Some(blake2b(32, &[], &data).as_bytes().to_hex())
}

@Java_io_parity_signer_EthkeyBridge_ethkeyBlockiesIcon
Expand Down Expand Up @@ -232,6 +232,18 @@ export! {
mod tests {
use super::*;

#[test]
fn test_blake() {
let data = "454545454545454545454545454545454545454545454545454545454545454501\
000000000000002481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa01\
53c31f4a29dbdbf025dd4a69a6f4ee6e1577b251b655097e298b692cb34c18d318\
2cac3de0dc00000000";
let expected = "1025e5db74fdaf4d2818822dccf0e1604ae9ccc62f26cecfde23448ff0248abf";
let result = blake(data);

assert_eq!(Some(expected.to_string()), result);
}

#[test]
fn test_rlp_item() {
let rlp = "f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804";
Expand Down
2 changes: 1 addition & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const globalStackNavigationOptions = {
},
headerTintColor: colors.card_bg,
headerTitleStyle: {
display: 'none'
// display: 'none'
}
};

Expand Down
5 changes: 4 additions & 1 deletion src/components/PayloadDetailsCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import colors from '../colors';
import { SUBSTRATE_NETWORK_LIST, SubstrateNetworkKeys } from '../constants';
import kusamaMetadata from '../util/static-kusama';
import substrateDevMetadata from '../util/static-substrate';
import { shortString } from '../util/strings';

export default class PayloadDetailsCard extends React.PureComponent {
static propTypes = {
Expand Down Expand Up @@ -280,7 +281,9 @@ function ExtrinsicPart({ label, fallback, prefix, value }) {
paramArgs.map(([param, arg]) => (
<View key={param} style={styles.callDetails}>
<Text style={styles.subLabel}>{param}: </Text>
<Text style={styles.secondaryText}>{arg}</Text>
<Text style={styles.secondaryText}>
{arg && arg.length > 50 ? shortString(arg) : arg}
</Text>
</View>
))
) : (
Expand Down
3 changes: 2 additions & 1 deletion src/components/QrView.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ export default function QrView(props) {
console.error(e);
}
}

displayQrCode(props.data);
}, [props.data]);
}, [props]);

const { width: deviceWidth } = Dimensions.get('window');
let size = props.size || deviceWidth - 80;
Expand Down
37 changes: 31 additions & 6 deletions src/screens/MessageDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,25 @@

'use strict';

import { GenericExtrinsicPayload } from '@polkadot/types';
import { isU8a, u8aToHex } from '@polkadot/util';
import PropTypes from 'prop-types';
import React from 'react';
import { Alert, ScrollView, StyleSheet, Text } from 'react-native';
import { Subscribe } from 'unstated';
import colors from '../colors';
import {
NETWORK_LIST,
NetworkProtocols,
SUBSTRATE_NETWORK_LIST
} from '../constants';
import fonts from '../fonts';
import AccountCard from '../components/AccountCard';
import Background from '../components/Background';
import Button from '../components/Button';
import AccountsStore from '../stores/AccountsStore';
import PayloadDetailsCard from '../components/PayloadDetailsCard';
import ScannerStore from '../stores/ScannerStore';
import { hexToAscii, isAscii } from '../util/message';
import { hexToAscii, isAscii } from '../util/strings';

export default class MessageDetails extends React.PureComponent {
static navigationOptions = {
Expand All @@ -37,8 +43,8 @@ export default class MessageDetails extends React.PureComponent {
};
render() {
return (
<Subscribe to={[ScannerStore, AccountsStore]}>
{(scannerStore, accounts) => {
<Subscribe to={[ScannerStore]}>
{scannerStore => {
const dataToSign = scannerStore.getDataToSign();
const message = scannerStore.getMessage();

Expand All @@ -52,6 +58,7 @@ export default class MessageDetails extends React.PureComponent {
dataToSign={
isU8a(dataToSign) ? u8aToHex(dataToSign) : dataToSign
}
prehash={scannerStore.getPrehashPayload()}
isHash={scannerStore.getIsHash()}
onNext={async () => {
try {
Expand Down Expand Up @@ -79,11 +86,17 @@ export class MessageDetailsView extends React.PureComponent {
isHash: PropTypes.bool,
message: PropTypes.string.isRequired,
onNext: PropTypes.func.isRequired,
prehash: PropTypes.instanceOf(GenericExtrinsicPayload),
sender: PropTypes.object.isRequired
};

render() {
const { dataToSign, isHash, message, onNext, sender } = this.props;
const { dataToSign, isHash, message, onNext, prehash, sender } = this.props;

const isEthereum =
NETWORK_LIST[sender.networkKey].protocol === NetworkProtocols.ETHEREUM;
const prefix =
!isEthereum && SUBSTRATE_NETWORK_LIST[sender.networkKey].prefix;

return (
<ScrollView
Expand All @@ -98,7 +111,19 @@ export class MessageDetailsView extends React.PureComponent {
address={sender.address}
networkKey={sender.networkKey}
/>
<Text style={styles.title}>MESSAGE</Text>
{!isEthereum && prehash && prefix ? (
<PayloadDetailsCard
style={{ marginBottom: 20 }}
description="You are about to confirm sending the following extrinsic. We will sign the hash of the payload as it is oversized."
payload={prehash}
prefix={prefix}
/>
) : null}
{isHash ? (
<Text style={styles.title}>HASH</Text>
) : (
<Text style={styles.title}>MESSAGE</Text>
)}
<Text style={styles.message}>
{isHash
? message
Expand Down
22 changes: 18 additions & 4 deletions src/screens/QrScanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export default class Scanner extends React.PureComponent {
this.setState({ enableScan: false });
Alert.alert(title, message, [
{
onPress: () => {
scannerStore.cleanup();
onPress: async () => {
await scannerStore.cleanup();
this.setState({ enableScan: true });
},
text: 'Try again'
Expand All @@ -61,10 +61,11 @@ export default class Scanner extends React.PureComponent {
return (
<QrScannerView
completedFramesCount={scannerStore.getCompletedFramesCount()}
totalFramesCount={scannerStore.getTotalFramesCount()}
isMultipart={scannerStore.getTotalFramesCount() > 1}
missedFrames={scannerStore.getMissedFrames()}
navigation={this.props.navigation}
scannerStore={scannerStore}
totalFramesCount={scannerStore.getTotalFramesCount()}
onBarCodeRead={async txRequestData => {
if (scannerStore.isBusy() || !this.state.enableScan) {
return;
Expand Down Expand Up @@ -152,6 +153,9 @@ export class QrScannerView extends React.Component {
}

render() {
const missedFrames = this.props.scannerStore.getMissedFrames();
const missedFramesMessage = missedFrames && missedFrames.join(', ');

if (this.props.scannerStore.isBusy()) {
return <View style={styles.inactive} />;
}
Expand Down Expand Up @@ -193,6 +197,15 @@ export class QrScannerView extends React.Component {
</Text>
</View>
)}
{missedFrames && missedFrames.length >= 1 ? (
<View style={styles.bottom}>
<Text style={styles.descTitle}>
You missed the following frames: {missedFramesMessage}
</Text>
</View>
) : (
undefined
)}
</View>
</RNCamera>
);
Expand All @@ -216,7 +229,8 @@ const styles = StyleSheet.create({
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
flex: 1,
justifyContent: 'center'
justifyContent: 'center',
paddingHorizontal: 15
},
descSecondary: {
color: colors.bg_text,
Expand Down
20 changes: 12 additions & 8 deletions src/screens/SignedMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ import { Subscribe } from 'unstated';
import colors from '../colors';
import fonts from '../fonts';
import QrView from '../components/QrView';
import AccountsStore from '../stores/AccountsStore';
import ScannerStore from '../stores/ScannerStore';
import { hexToAscii, isAscii } from '../util/message';
import { hexToAscii, isAscii } from '../util/strings';

export default class SignedMessage extends React.PureComponent {
render() {
return (
<Subscribe to={[ScannerStore, AccountsStore]}>
{(scannerStore, accountsStore) => {
<Subscribe to={[ScannerStore]}>
{scannerStore => {
return (
<SignedMessageView
data={scannerStore.getSignedTxData()}
Expand All @@ -47,9 +46,9 @@ export default class SignedMessage extends React.PureComponent {

export class SignedMessageView extends React.PureComponent {
static propTypes = {
data: PropTypes.string.isRequired,
data: PropTypes.string.isRequired, // post sign
isHash: PropTypes.bool,
message: PropTypes.string
message: PropTypes.string // pre sign
};

render() {
Expand All @@ -59,9 +58,14 @@ export class SignedMessageView extends React.PureComponent {
<ScrollView style={styles.body} contentContainerStyle={{ padding: 20 }}>
<Text style={styles.topTitle}>SCAN SIGNATURE</Text>
<View style={styles.qr}>
<QrView data={this.props.data} />
<QrView data={data} />
</View>
<Text style={styles.title}>MESSAGE</Text>
<Text style={styles.title}>{!isHash && 'MESSAGE'}</Text>
{isHash ? (
<Text style={styles.title}>HASH</Text>
) : (
<Text style={styles.title}>MESSAGE</Text>
)}
<Text style={styles.message}>
{isHash ? message : isAscii(message) ? hexToAscii(message) : data}
</Text>
Expand Down
28 changes: 17 additions & 11 deletions src/screens/TxDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@ import { ScrollView, StyleSheet, Text } from 'react-native';
import { Subscribe } from 'unstated';

import colors from '../colors';
import { NETWORK_LIST } from '../constants';
import {
NETWORK_LIST,
NetworkProtocols,
SUBSTRATE_NETWORK_LIST
} from '../constants';
import fonts from '../fonts';
import AccountCard from '../components/AccountCard';
import Background from '../components/Background';
import Button from '../components/Button';
import TxDetailsCard from '../components/TxDetailsCard';
import AccountsStore from '../stores/AccountsStore';
import ScannerStore from '../stores/ScannerStore';
import { NetworkProtocols, SUBSTRATE_NETWORK_LIST } from '../constants';
import PayloadDetailsCard from '../components/PayloadDetailsCard';
import { GenericExtrinsicPayload } from '@polkadot/types';

export default class TxDetails extends React.PureComponent {
static navigationOptions = {
Expand All @@ -53,7 +57,8 @@ export default class TxDetails extends React.PureComponent {
scannerStore={scannerStore}
sender={scannerStore.getSender()}
recipient={scannerStore.getRecipient()}
dataToSign={scannerStore.getDataToSign()}
// dataToSign={scannerStore.getDataToSign()}
prehash={scannerStore.getPrehashPayload()}
onNext={async () => {
try {
this.props.navigation.navigate('AccountUnlockAndSign');
Expand All @@ -74,26 +79,27 @@ export default class TxDetails extends React.PureComponent {

export class TxDetailsView extends React.PureComponent {
static propTypes = {
dataToSign: PropTypes.oneOfType([PropTypes.string, PropTypes.object])
.isRequired,
// dataToSign: PropTypes.oneOfType([PropTypes.string, PropTypes.object])
// .isRequired,
gas: PropTypes.string,
gasPrice: PropTypes.string,
nonce: PropTypes.string,
onNext: PropTypes.func.isRequired,
prehash: PropTypes.instanceOf(GenericExtrinsicPayload),
recipient: PropTypes.object.isRequired,
sender: PropTypes.object.isRequired,
value: PropTypes.string
};

render() {
const {
dataToSign,
sender,
recipient,
value,
// nonce,
// dataToSign,
gas,
gasPrice,
prehash,
recipient,
sender,
value,
onNext
} = this.props;

Expand Down Expand Up @@ -137,7 +143,7 @@ export class TxDetailsView extends React.PureComponent {
<PayloadDetailsCard
style={{ marginBottom: 20 }}
description="You are about to confirm sending the following extrinsic"
payload={dataToSign}
payload={prehash}
prefix={prefix}
/>
)}
Expand Down
Loading

0 comments on commit 5c587fd

Please sign in to comment.