register multiple pub keys for alerts and private notifications

This commit is contained in:
woodser 2024-04-08 07:46:14 -04:00
parent fd328ceeea
commit b3ec46e769
2 changed files with 64 additions and 25 deletions

View File

@ -31,6 +31,7 @@ import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
@ -47,9 +48,8 @@ public class AlertManager {
private final KeyRing keyRing; private final KeyRing keyRing;
private final User user; private final User user;
private final ObjectProperty<Alert> alertMessageProperty = new SimpleObjectProperty<>(); private final ObjectProperty<Alert> alertMessageProperty = new SimpleObjectProperty<>();
private final boolean useDevPrivilegeKeys;
// Pub key for developer global alert message
private final String pubKeyAsHex;
private ECKey alertSigningKey; private ECKey alertSigningKey;
@ -66,6 +66,7 @@ public class AlertManager {
this.p2PService = p2PService; this.p2PService = p2PService;
this.keyRing = keyRing; this.keyRing = keyRing;
this.user = user; this.user = user;
this.useDevPrivilegeKeys = useDevPrivilegeKeys;
if (!ignoreDevMsg) { if (!ignoreDevMsg) {
p2PService.addHashSetChangedListener(new HashMapChangedListener() { p2PService.addHashSetChangedListener(new HashMapChangedListener() {
@ -93,9 +94,25 @@ public class AlertManager {
} }
}); });
} }
pubKeyAsHex = useDevPrivilegeKeys ? }
DevEnv.DEV_PRIVILEGE_PUB_KEY :
"036d8a1dfcb406886037d2381da006358722823e1940acc2598c844bbc0fd1026f"; protected List<String> getPubKeyList() {
if (useDevPrivilegeKeys) return List.of(DevEnv.DEV_PRIVILEGE_PUB_KEY);
switch (Config.baseCurrencyNetwork()) {
case XMR_LOCAL:
return List.of(
"027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee",
"024baabdba90e7cc0dc4626ef73ea9d722ea7085d1104491da8c76f28187513492");
case XMR_STAGENET:
return List.of(
"036d8a1dfcb406886037d2381da006358722823e1940acc2598c844bbc0fd1026f",
"026c581ad773d987e6bd10785ac7f7e0e64864aedeb8bce5af37046de812a37854",
"025b058c9f2c60d839669dbfa5578cf5a8117d60e6b70e2f0946f8a691273c6a36");
case XMR_MAINNET:
return List.of();
default:
throw new RuntimeException("Unhandled base currency network: " + Config.baseCurrencyNetwork());
}
} }
@ -141,7 +158,7 @@ public class AlertManager {
private boolean isKeyValid(String privKeyString) { private boolean isKeyValid(String privKeyString) {
try { try {
alertSigningKey = ECKey.fromPrivate(new BigInteger(1, HEX.decode(privKeyString))); alertSigningKey = ECKey.fromPrivate(new BigInteger(1, HEX.decode(privKeyString)));
return pubKeyAsHex.equals(Utils.HEX.encode(alertSigningKey.getPubKey())); return getPubKeyList().contains(Utils.HEX.encode(alertSigningKey.getPubKey()));
} catch (Throwable t) { } catch (Throwable t) {
return false; return false;
} }
@ -155,12 +172,15 @@ public class AlertManager {
private boolean verifySignature(Alert alert) { private boolean verifySignature(Alert alert) {
String alertMessageAsHex = Utils.HEX.encode(alert.getMessage().getBytes(Charsets.UTF_8)); String alertMessageAsHex = Utils.HEX.encode(alert.getMessage().getBytes(Charsets.UTF_8));
try { for (String pubKeyAsHex : getPubKeyList()) {
ECKey.fromPublicOnly(HEX.decode(pubKeyAsHex)).verifyMessage(alertMessageAsHex, alert.getSignatureAsBase64()); try {
return true; ECKey.fromPublicOnly(HEX.decode(pubKeyAsHex)).verifyMessage(alertMessageAsHex, alert.getSignatureAsBase64());
} catch (SignatureException e) { return true;
log.warn("verifySignature failed"); } catch (SignatureException e) {
return false; // ignore
}
} }
log.warn("verifySignature failed");
return false;
} }
} }

View File

@ -41,6 +41,7 @@ import haveno.network.p2p.peers.keepalive.messages.Ping;
import haveno.network.p2p.peers.keepalive.messages.Pong; import haveno.network.p2p.peers.keepalive.messages.Pong;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.SignatureException; import java.security.SignatureException;
import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -62,9 +63,7 @@ public class PrivateNotificationManager implements MessageListener {
private final MailboxMessageService mailboxMessageService; private final MailboxMessageService mailboxMessageService;
private final KeyRing keyRing; private final KeyRing keyRing;
private final ObjectProperty<PrivateNotificationPayload> privateNotificationMessageProperty = new SimpleObjectProperty<>(); private final ObjectProperty<PrivateNotificationPayload> privateNotificationMessageProperty = new SimpleObjectProperty<>();
private final boolean useDevPrivilegeKeys;
// Pub key for developer global privateNotification message
private final String pubKeyAsHex;
private ECKey privateNotificationSigningKey; private ECKey privateNotificationSigningKey;
@Nullable @Nullable
@ -88,14 +87,31 @@ public class PrivateNotificationManager implements MessageListener {
this.networkNode = networkNode; this.networkNode = networkNode;
this.mailboxMessageService = mailboxMessageService; this.mailboxMessageService = mailboxMessageService;
this.keyRing = keyRing; this.keyRing = keyRing;
this.useDevPrivilegeKeys = useDevPrivilegeKeys;
if (!ignoreDevMsg) { if (!ignoreDevMsg) {
this.p2PService.addDecryptedDirectMessageListener(this::handleMessage); this.p2PService.addDecryptedDirectMessageListener(this::handleMessage);
this.mailboxMessageService.addDecryptedMailboxListener(this::handleMessage); this.mailboxMessageService.addDecryptedMailboxListener(this::handleMessage);
} }
pubKeyAsHex = useDevPrivilegeKeys ? }
DevEnv.DEV_PRIVILEGE_PUB_KEY :
"02ba7c5de295adfe57b60029f3637a2c6b1d0e969a8aaefb9e0ddc3a7963f26925"; protected List<String> getPubKeyList() {
if (useDevPrivilegeKeys) return List.of(DevEnv.DEV_PRIVILEGE_PUB_KEY);
switch (Config.baseCurrencyNetwork()) {
case XMR_LOCAL:
return List.of(
"027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee",
"024baabdba90e7cc0dc4626ef73ea9d722ea7085d1104491da8c76f28187513492");
case XMR_STAGENET:
return List.of(
"02ba7c5de295adfe57b60029f3637a2c6b1d0e969a8aaefb9e0ddc3a7963f26925",
"026c581ad773d987e6bd10785ac7f7e0e64864aedeb8bce5af37046de812a37854",
"025b058c9f2c60d839669dbfa5578cf5a8117d60e6b70e2f0946f8a691273c6a36");
case XMR_MAINNET:
return List.of();
default:
throw new RuntimeException("Unhandled base currency network: " + Config.baseCurrencyNetwork());
}
} }
private void handleMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, NodeAddress senderNodeAddress) { private void handleMessage(DecryptedMessageWithPubKey decryptedMessageWithPubKey, NodeAddress senderNodeAddress) {
@ -155,7 +171,7 @@ public class PrivateNotificationManager implements MessageListener {
private boolean isKeyValid(String privKeyString) { private boolean isKeyValid(String privKeyString) {
try { try {
privateNotificationSigningKey = ECKey.fromPrivate(new BigInteger(1, HEX.decode(privKeyString))); privateNotificationSigningKey = ECKey.fromPrivate(new BigInteger(1, HEX.decode(privKeyString)));
return pubKeyAsHex.equals(Utils.HEX.encode(privateNotificationSigningKey.getPubKey())); return getPubKeyList().contains(Utils.HEX.encode(privateNotificationSigningKey.getPubKey()));
} catch (Throwable t) { } catch (Throwable t) {
return false; return false;
} }
@ -169,13 +185,16 @@ public class PrivateNotificationManager implements MessageListener {
private boolean verifySignature(PrivateNotificationPayload privateNotification) { private boolean verifySignature(PrivateNotificationPayload privateNotification) {
String privateNotificationMessageAsHex = Utils.HEX.encode(privateNotification.getMessage().getBytes(Charsets.UTF_8)); String privateNotificationMessageAsHex = Utils.HEX.encode(privateNotification.getMessage().getBytes(Charsets.UTF_8));
try { for (String pubKeyAsHex : getPubKeyList()) {
ECKey.fromPublicOnly(HEX.decode(pubKeyAsHex)).verifyMessage(privateNotificationMessageAsHex, privateNotification.getSignatureAsBase64()); try {
return true; ECKey.fromPublicOnly(HEX.decode(pubKeyAsHex)).verifyMessage(privateNotificationMessageAsHex, privateNotification.getSignatureAsBase64());
} catch (SignatureException e) { return true;
log.warn("verifySignature failed"); } catch (SignatureException e) {
return false; // ignore
}
} }
log.warn("verifySignature failed");
return false;
} }
public void sendPing(NodeAddress peersNodeAddress, Consumer<String> resultHandler) { public void sendPing(NodeAddress peersNodeAddress, Consumer<String> resultHandler) {