From 0ea7a6b05e408037c071ba981286b6f33b3bda49 Mon Sep 17 00:00:00 2001 From: Vishal <64505169+vishalxl@users.noreply.github.com> Date: Wed, 9 Nov 2022 23:30:18 +0530 Subject: [PATCH] added unused or skeletal code to eventually do sig check for incoming events --- lib/console_ui.dart | 18 ++++----- lib/event_ds.dart | 94 +++++++++++++++++++++++++++++++++++++++++---- lib/relays.dart | 11 ++++-- 3 files changed, 103 insertions(+), 20 deletions(-) diff --git a/lib/console_ui.dart b/lib/console_ui.dart index 964375f..cb8f15e 100644 --- a/lib/console_ui.dart +++ b/lib/console_ui.dart @@ -54,7 +54,7 @@ Future sendReplyPostLike(Store node, String replyToId, String replyKind, S } int createdAt = DateTime.now().millisecondsSinceEpoch ~/1000; - String id = getShaId(userPublicKey, createdAt, replyKind, strTags, content); + String id = getShaId(userPublicKey, createdAt.toString(), replyKind, strTags, content); // generate POW if required String vanityTag = strTags; @@ -70,7 +70,7 @@ Future sendReplyPostLike(Store node, String replyToId, String replyKind, S int numShaDone = 0; for( numShaDone = 0; numShaDone < 100000000; numShaDone++) { vanityTag = strTags + ',["nonce","$numShaDone","$gDifficulty"]'; - id = getShaId(userPublicKey, createdAt, replyKind, vanityTag, content); + id = getShaId(userPublicKey, createdAt.toString(), replyKind, vanityTag, content); if( id.substring(0, numBytes) == zeroString) { break; } @@ -80,7 +80,7 @@ Future sendReplyPostLike(Store node, String replyToId, String replyKind, S } String sig = mySign(userPrivateKey, id); - + String toSendMessage = '["EVENT",{"id":"$id","pubkey":"$userPublicKey","created_at":$createdAt,"kind":$replyKind,"tags":[$vanityTag],"content":"$content","sig":"$sig"}]'; sendRequest( gListRelayUrls1, toSendMessage); } @@ -91,7 +91,7 @@ Future sendPublicChannelMessage(Store node, String channelId, String messa String strTags = node.getTagStr(channelId, exename); int createdAt = DateTime.now().millisecondsSinceEpoch ~/1000; - String id = getShaId(userPublicKey, createdAt, replyKind, strTags, messageToSend); + String id = getShaId(userPublicKey, createdAt.toString(), replyKind, strTags, messageToSend); String sig = mySign(userPrivateKey, id); String toSendMessage = '["EVENT",{"id":"$id","pubkey":"$userPublicKey","created_at":$createdAt,"kind":$replyKind,"tags":[$strTags],"content":"$messageToSend","sig":"$sig"}]'; @@ -111,7 +111,7 @@ Future sendPublicChannelReply(Store node, Channel channel, String replyTo, String strTags = node.getTagStrForChannel(channel, replyTo, exename); int createdAt = DateTime.now().millisecondsSinceEpoch ~/1000; - String id = getShaId(userPublicKey, createdAt, replyKind, strTags, messageToSend); + String id = getShaId(userPublicKey, createdAt.toString(), replyKind, strTags, messageToSend); String sig = mySign(userPrivateKey, id); String toSendMessage = '["EVENT",{"id":"$id","pubkey":"$userPublicKey","created_at":$createdAt,"kind":$replyKind,"tags":[$strTags],"content":"$messageToSend","sig":"$sig"}]'; @@ -137,7 +137,7 @@ Future sendDirectMessage(Store node, String otherPubkey, String messageToS strTags += gWhetherToSendClientTag?',["client","nostr_console"]':''; int createdAt = DateTime.now().millisecondsSinceEpoch ~/1000; - String id = getShaId(userPublicKey, createdAt, replyKind, strTags, encryptedMessageToSend); + String id = getShaId(userPublicKey, createdAt.toString(), replyKind, strTags, encryptedMessageToSend); String sig = mySign(userPrivateKey, id); String eventStrToSend = '["EVENT",{"id":"$id","pubkey":"$userPublicKey","created_at":$createdAt,"kind":$replyKind,"tags":[$strTags],"content":"$encryptedMessageToSend","sig":"$sig"}]'; @@ -179,7 +179,7 @@ Future sendEvent(Store node, Event e) async { strTags += '["client","nostr_console"]'; } - String id = getShaId(userPublicKey, createdAt, e.eventData.kind.toString(), strTags, content); + String id = getShaId(userPublicKey, createdAt.toString(), e.eventData.kind.toString(), strTags, content); String sig = mySign(userPrivateKey, id); String toSendMessage = '["EVENT",{"id":"$id","pubkey":"$userPublicKey","created_at":$createdAt,"kind":${e.eventData.kind.toString()},"tags":[$strTags],"content":"$content","sig":"$sig"}]'; @@ -199,7 +199,7 @@ Future sendEventWithTags(Store node, Event e, String tags) async { int createdAt = DateTime.now().millisecondsSinceEpoch ~/1000; String content = addEscapeChars( e.eventData.content); - String id = getShaId(userPublicKey, createdAt, e.eventData.kind.toString(), strTags, content); + String id = getShaId(userPublicKey, createdAt.toString(), e.eventData.kind.toString(), strTags, content); String sig = mySign(userPrivateKey, id); String toSendMessage = '["EVENT",{"id":"$id","pubkey":"$userPublicKey","created_at":$createdAt,"kind":${e.eventData.kind.toString()},"tags":[$strTags],"content":"$content","sig":"$sig"}]'; @@ -227,7 +227,7 @@ bool sendDeleteEvent(Store node, String eventIdToDelete) { strTags += gWhetherToSendClientTag?',["client","nostr_console"]':''; int createdAt = DateTime.now().millisecondsSinceEpoch ~/1000; - String id = getShaId(userPublicKey, createdAt, replyKind, strTags, content); + String id = getShaId(userPublicKey, createdAt.toString(), replyKind, strTags, content); String sig = mySign(userPrivateKey, id); String toSendMessage = '["EVENT",{"id":"$id","pubkey":"$userPublicKey","created_at":$createdAt,"kind":$replyKind,"tags":[$strTags],"content":"$content","sig":"$sig"}]'; diff --git a/lib/event_ds.dart b/lib/event_ds.dart index 46e91f7..a4050a3 100644 --- a/lib/event_ds.dart +++ b/lib/event_ds.dart @@ -12,12 +12,10 @@ import 'dart:convert' as convert; import "package:pointycastle/export.dart"; import 'package:kepler/kepler.dart'; - String getStrInColor(String s, String commentColor) => stdout.supportsAnsiEscapes ?"$commentColor$s$gColorEndMarker":s; void printInColor(String s, String commentColor) => stdout.supportsAnsiEscapes ?stdout.write("$commentColor$s$gColorEndMarker"):stdout.write(s); void printWarning(String s) => stdout.supportsAnsiEscapes ?stdout.write("$gWarningColor$s$gColorEndMarker\n"):stdout.write("$s\n"); - // translate GoogleTranslator? translator; // initialized in main when argument given @@ -50,6 +48,62 @@ Map< String, List> > gReactions = {}; // is updated as kind 3 events are received Map< String, List> gContactLists = {}; +// returns tags as string that can be used to calculate event has. called from EventData constructor +String getStrTagsFromJson(dynamic json) { + String str = ""; + + int i = 0; + for( dynamic tag in json ) { + if( i != 0) { + str += ","; + } + + str += "["; + int j = 0; + for(dynamic e in tag) { + if( j != 0) { + str += ","; + } + str += "\"${e.toString()}\""; + j++; + } + str += "]"; + i++; + } + return str; +} + +bool verifyEvent(dynamic json) { + String createdAt = json['created_at'].toString(); + + List listTags = json['tags']; + //print(listTags); + String strTags = json['tags'].toString(); + + strTags = getStrTagsFromJson(json['tags']); + + //print("strTags = $strTags"); + + String id = json['id']; + String eventPubkey = json['pubkey']; + String strKind = json['kind'].toString(); + String content = json['content']; + + + String calculatedId = getShaId(eventPubkey, createdAt.toString(), strKind, strTags, content); + //print("\ncalculated id = $calculatedId actual id = $id"); + bool verified = true;//verify( eventPubkey, calculatedId, sig); + + if( !verified ) { + //printWarning("wrong sig event sig = $sig event id = $id calculated id = $calculatedId " ); + //print("Event: kind = $strKind"); + throw Exception(); + } else { + //printInColor("verified correct sig", gCommentColor); + } + return true; +} + class EventData { String id; String pubkey; @@ -88,6 +142,7 @@ class EventData { return ""; } + EventData(this.id, this.pubkey, this.createdAt, this.kind, this.content, this.eTags, this.pTags, this.contactList,this.tags, this.newLikes, { @@ -105,6 +160,25 @@ class EventData { var jsonTags = json['tags']; var numTags = jsonTags.length; + + //print("\n----\nIn fromJson\n"); + String sig = json['sig']; + if(sig.length == 128) { + //print("found sig == 128 bytes"); + //if(json['id'] == "15dd45769dd0ccb9c4ca1c69fcd27011d53c4b95c8b7c786265bf7377bc7fdad") { + // printInColor("found 15dd45769dd0ccb9c4ca1c69fcd27011d53c4b95c8b7c786265bf7377bc7fdad sig ${json['sig']}", gCommentColor); + //} + + try { + //verifyEvent(json); + + } on Exception catch(e) { + //printWarning("verify gave exception $e"); + throw Exception("in Event constructor: sig verify gave exception"); + } + + } + // NIP 02: if the event is a contact list type, then populate contactList if(json['kind'] == 3) { for( int i = 0; i < numTags; i++) { @@ -657,24 +731,27 @@ class Event { factory Event.fromJson(String d, String relay, [bool fromFile = false]) { try { dynamic json = jsonDecode(d); + if( json.length < 3) { String e = ""; e = json.length > 1? json[0]: ""; - if( gDebug> 0) { - print("Could not create event. returning dummy event. json.length = ${json.length} string d= $d $e"); + if( gDebug > 0) { + print("Could not create event. json.length = ${json.length} string d= $d $e"); } - return Event(e,"",EventData("non","", 0, 0, "", [], [], [], [[]], {}), [relay], "[json]", fromFile); + throw Exception("Event json has less than 3 elements"); } + EventData newEventData = EventData.fromJson(json[2]); if( !fromFile) newEventData.isNotification = true; return Event(json[0] as String, json[1] as String, newEventData, [relay], d, fromFile ); } on Exception catch(e) { if( gDebug> 0) { - print("Could not create event. returning dummy event. $e"); + print("Could not create event. $e"); print("problem str: $d\n"); } - return Event("","",EventData("non","", 0, 0, "", [], [], [], [[]], {}), [relay], "[json]", fromFile); + //print("Caught an exception in Event.fromJson"); + throw e; } } @@ -1144,8 +1221,9 @@ String addEscapeChars(String str) { return str.replaceAll("\"", "\\\""); } -String getShaId(String pubkey, int createdAt, String kind, String strTags, String content) { +String getShaId(String pubkey, String createdAt, String kind, String strTags, String content) { String buf = '[0,"$pubkey",$createdAt,$kind,[$strTags],"$content"]'; + //print("in getShaId for buf: |$buf|"); var bufInBytes = utf8.encode(buf); var value = sha256.convert(bufInBytes); return value.toString(); diff --git a/lib/relays.dart b/lib/relays.dart index a17a34c..1532e24 100644 --- a/lib/relays.dart +++ b/lib/relays.dart @@ -195,7 +195,8 @@ class Relays { if( gDebug > 0) print( 'in Relay::sendRequset. FormatException in sendRequest for event'); return; } catch(err) { - if( gDebug > 0) print('in Relay::sendRequset. exception = "$err" ; for relay $relay'); + //dynamic json = jsonDecode(d); + if( gDebug > 0) print('---\nin Relay::sendRequset. exception = "$err" ; for relay $relay d = \n${d}'); return; } }, @@ -205,8 +206,12 @@ class Relays { } on WebSocketException { print('WebSocketException exception for relay $relay'); return; - } catch(err) { - if( gDebug > 0) print('exception generic $err for relay $relay'); + } on Exception catch(ex) { + printWarning("Invalid event\n"); + } + + catch(err) { + if( gDebug >= 0) printWarning('exception generic $err for relay $relay\n'); return; } }