use byte[] for signatures instead of strings
This commit is contained in:
parent
ead70751dc
commit
4650003838
@ -20,12 +20,15 @@ package haveno.core.offer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import haveno.common.crypto.Hash;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.proto.ProtoUtil;
|
||||
import haveno.common.util.CollectionUtils;
|
||||
import haveno.common.util.Hex;
|
||||
import haveno.common.util.JsonExclude;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
import haveno.network.p2p.storage.payload.ExpirablePayload;
|
||||
import haveno.network.p2p.storage.payload.ProtectedStoragePayload;
|
||||
@ -81,7 +84,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
||||
protected NodeAddress arbitratorSigner;
|
||||
@Setter
|
||||
@Nullable
|
||||
protected String arbitratorSignature;
|
||||
protected byte[] arbitratorSignature;
|
||||
@Setter
|
||||
@Nullable
|
||||
protected List<String> reserveTxKeyImages;
|
||||
@ -191,7 +194,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
||||
@Nullable Map<String, String> extraDataMap,
|
||||
int protocolVersion,
|
||||
@Nullable NodeAddress arbitratorSigner,
|
||||
@Nullable String arbitratorSignature,
|
||||
@Nullable byte[] arbitratorSignature,
|
||||
@Nullable List<String> reserveTxKeyImages) {
|
||||
this.id = id;
|
||||
this.date = date;
|
||||
@ -302,7 +305,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
||||
Optional.ofNullable(acceptedCountryCodes).ifPresent(builder::addAllAcceptedCountryCodes);
|
||||
Optional.ofNullable(hashOfChallenge).ifPresent(builder::setHashOfChallenge);
|
||||
Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraData);
|
||||
Optional.ofNullable(arbitratorSignature).ifPresent(builder::setArbitratorSignature);
|
||||
Optional.ofNullable(arbitratorSignature).ifPresent(e -> builder.setArbitratorSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(reserveTxKeyImages).ifPresent(builder::addAllReserveTxKeyImages);
|
||||
|
||||
return protobuf.StoragePayload.newBuilder().setOfferPayload(builder).build();
|
||||
@ -352,7 +355,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
||||
extraDataMapMap,
|
||||
proto.getProtocolVersion(),
|
||||
proto.hasArbitratorSigner() ? NodeAddress.fromProto(proto.getArbitratorSigner()) : null,
|
||||
ProtoUtil.stringOrNullFromProto(proto.getArbitratorSignature()),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getArbitratorSignature()),
|
||||
proto.getReserveTxKeyImagesList() == null ? null : new ArrayList<String>(proto.getReserveTxKeyImagesList()));
|
||||
}
|
||||
|
||||
@ -375,8 +378,6 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
||||
",\r\n pubKeyRing=" + pubKeyRing +
|
||||
",\r\n hash=" + (hash != null ? Hex.encode(hash) : "null") +
|
||||
",\r\n extraDataMap=" + extraDataMap +
|
||||
",\r\n arbitratorSigner=" + arbitratorSigner +
|
||||
",\r\n arbitratorSignature=" + arbitratorSignature +
|
||||
",\r\n reserveTxKeyImages=" + reserveTxKeyImages +
|
||||
",\r\n marketPriceMargin=" + marketPriceMarginPct +
|
||||
",\r\n useMarketBasedPrice=" + useMarketBasedPrice +
|
||||
@ -398,7 +399,7 @@ public final class OfferPayload implements ProtectedStoragePayload, ExpirablePay
|
||||
",\r\n isPrivateOffer=" + isPrivateOffer +
|
||||
",\r\n hashOfChallenge='" + hashOfChallenge + '\'' +
|
||||
",\n arbitratorSigner=" + arbitratorSigner +
|
||||
",\n arbitratorSignature=" + arbitratorSignature +
|
||||
",\n arbitratorSignature=" + Utilities.bytesAsHexString(arbitratorSignature) +
|
||||
"\r\n} ";
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ import haveno.common.app.Capability;
|
||||
import haveno.common.app.Version;
|
||||
import haveno.common.crypto.KeyRing;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.handlers.ErrorMessageHandler;
|
||||
import haveno.common.handlers.ResultHandler;
|
||||
import haveno.common.persistence.PersistenceManager;
|
||||
@ -1000,7 +999,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
|
||||
// arbitrator signs offer to certify they have valid reserve tx
|
||||
String offerPayloadAsJson = JsonUtil.objectToJson(request.getOfferPayload());
|
||||
String signature = Sig.sign(keyRing.getSignatureKeyPair().getPrivate(), offerPayloadAsJson);
|
||||
byte[] signature = HavenoUtils.sign(keyRing, offerPayloadAsJson);
|
||||
OfferPayload signedOfferPayload = request.getOfferPayload();
|
||||
signedOfferPayload.setArbitratorSignature(signature);
|
||||
|
||||
@ -1119,7 +1118,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
try {
|
||||
Optional<OpenOffer> openOfferOptional = getOpenOfferById(request.offerId);
|
||||
AvailabilityResult availabilityResult;
|
||||
String makerSignature = null;
|
||||
byte[] makerSignature = null;
|
||||
if (openOfferOptional.isPresent()) {
|
||||
OpenOffer openOffer = openOfferOptional.get();
|
||||
if (!apiUserDeniedByOffer(request)) {
|
||||
@ -1130,7 +1129,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
|
||||
// maker signs taker's request
|
||||
String tradeRequestAsJson = JsonUtil.objectToJson(request.getTradeRequest());
|
||||
makerSignature = Sig.sign(keyRing.getSignatureKeyPair().getPrivate(), tradeRequestAsJson);
|
||||
makerSignature = HavenoUtils.sign(keyRing, tradeRequestAsJson);
|
||||
|
||||
try {
|
||||
// Check also tradePrice to avoid failures after taker fee is paid caused by a too big difference
|
||||
|
@ -17,10 +17,14 @@
|
||||
|
||||
package haveno.core.offer;
|
||||
|
||||
import haveno.common.proto.ProtoUtil;
|
||||
import haveno.common.proto.persistable.PersistablePayload;
|
||||
import haveno.core.util.JsonUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -48,7 +52,7 @@ public final class SignedOffer implements PersistablePayload {
|
||||
@Getter
|
||||
private final long reserveTxMinerFee;
|
||||
@Getter
|
||||
private final String arbitratorSignature;
|
||||
private final byte[] arbitratorSignature;
|
||||
|
||||
public SignedOffer(long timeStamp,
|
||||
int traderId,
|
||||
@ -59,7 +63,7 @@ public final class SignedOffer implements PersistablePayload {
|
||||
String reserveTxHex,
|
||||
List<String> reserveTxKeyImages,
|
||||
long reserveTxMinerFee,
|
||||
String arbitratorSignature) {
|
||||
byte[] arbitratorSignature) {
|
||||
this.timeStamp = timeStamp;
|
||||
this.traderId = traderId;
|
||||
this.offerId = offerId;
|
||||
@ -88,7 +92,7 @@ public final class SignedOffer implements PersistablePayload {
|
||||
.setReserveTxHex(reserveTxHex)
|
||||
.addAllReserveTxKeyImages(reserveTxKeyImages)
|
||||
.setReserveTxMinerFee(reserveTxMinerFee)
|
||||
.setArbitratorSignature(arbitratorSignature);
|
||||
.setArbitratorSignature(ByteString.copyFrom(arbitratorSignature));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@ -102,7 +106,7 @@ public final class SignedOffer implements PersistablePayload {
|
||||
proto.getReserveTxHex(),
|
||||
proto.getReserveTxKeyImagesList(),
|
||||
proto.getReserveTxMinerFee(),
|
||||
proto.getArbitratorSignature());
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getArbitratorSignature()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ public class OfferAvailabilityModel implements Model {
|
||||
@Nullable
|
||||
@Setter
|
||||
@Getter
|
||||
private String makerSignature;
|
||||
private byte[] makerSignature;
|
||||
|
||||
// Added in v1.5.5
|
||||
@Getter
|
||||
|
@ -17,9 +17,7 @@
|
||||
|
||||
package haveno.core.offer.availability.tasks;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import haveno.common.app.Version;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.taskrunner.Task;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.monetary.Price;
|
||||
@ -59,7 +57,7 @@ public class SendOfferAvailabilityRequest extends Task<OfferAvailabilityModel> {
|
||||
String payoutAddress = walletService.getOrCreateAddressEntry(offer.getId(), XmrAddressEntry.Context.TRADE_PAYOUT).getAddressString(); // reserve new payout address
|
||||
|
||||
// taker signs offer using offer id as nonce to avoid challenge protocol
|
||||
byte[] sig = Sig.sign(model.getP2PService().getKeyRing().getSignatureKeyPair().getPrivate(), offer.getId().getBytes(Charsets.UTF_8));
|
||||
byte[] sig = HavenoUtils.sign(model.getP2PService().getKeyRing(), offer.getId());
|
||||
|
||||
// get price
|
||||
Price price = offer.getPrice();
|
||||
|
@ -31,6 +31,8 @@ import lombok.Value;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
// We add here the SupportedCapabilitiesMessage interface as that message always predates a direct connection
|
||||
// to the trading peer
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ -41,11 +43,11 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
|
||||
private final Capabilities supportedCapabilities;
|
||||
|
||||
@Nullable
|
||||
private final String makerSignature;
|
||||
private byte[] makerSignature;
|
||||
|
||||
public OfferAvailabilityResponse(String offerId,
|
||||
AvailabilityResult availabilityResult,
|
||||
String makerSignature) {
|
||||
@Nullable byte[] makerSignature) {
|
||||
this(offerId,
|
||||
availabilityResult,
|
||||
Capabilities.app,
|
||||
@ -64,7 +66,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
|
||||
@Nullable Capabilities supportedCapabilities,
|
||||
String messageVersion,
|
||||
@Nullable String uid,
|
||||
String makerSignature) {
|
||||
byte[] makerSignature) {
|
||||
super(messageVersion, offerId, uid);
|
||||
this.availabilityResult = availabilityResult;
|
||||
this.supportedCapabilities = supportedCapabilities;
|
||||
@ -79,7 +81,7 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
|
||||
|
||||
Optional.ofNullable(supportedCapabilities).ifPresent(e -> builder.addAllSupportedCapabilities(Capabilities.toIntList(supportedCapabilities)));
|
||||
Optional.ofNullable(uid).ifPresent(e -> builder.setUid(uid));
|
||||
Optional.ofNullable(makerSignature).ifPresent(e -> builder.setMakerSignature(makerSignature));
|
||||
Optional.ofNullable(makerSignature).ifPresent(e -> builder.setMakerSignature(ByteString.copyFrom(e)));
|
||||
|
||||
return getNetworkEnvelopeBuilder()
|
||||
.setOfferAvailabilityResponse(builder)
|
||||
@ -92,6 +94,6 @@ public final class OfferAvailabilityResponse extends OfferMessage implements Sup
|
||||
Capabilities.fromIntList(proto.getSupportedCapabilitiesList()),
|
||||
messageVersion,
|
||||
proto.getUid().isEmpty() ? null : proto.getUid(),
|
||||
proto.getMakerSignature().isEmpty() ? null : proto.getMakerSignature());
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getMakerSignature()));
|
||||
}
|
||||
}
|
||||
|
@ -104,9 +104,9 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
||||
private final String payoutTxId;
|
||||
private String contractAsJson;
|
||||
@Nullable
|
||||
private final String makerContractSignature;
|
||||
private final byte[] makerContractSignature;
|
||||
@Nullable
|
||||
private final String takerContractSignature;
|
||||
private final byte[] takerContractSignature;
|
||||
private final PubKeyRing agentPubKeyRing; // dispute agent
|
||||
private final boolean isSupportTicket;
|
||||
private final ObservableList<ChatMessage> chatMessages = FXCollections.observableArrayList();
|
||||
@ -179,8 +179,8 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
||||
@Nullable String depositTxId,
|
||||
@Nullable String payoutTxId,
|
||||
String contractAsJson,
|
||||
@Nullable String makerContractSignature,
|
||||
@Nullable String takerContractSignature,
|
||||
@Nullable byte[] makerContractSignature,
|
||||
@Nullable byte[] takerContractSignature,
|
||||
@Nullable PaymentAccountPayload makerPaymentAccountPayload,
|
||||
@Nullable PaymentAccountPayload takerPaymentAccountPayload,
|
||||
PubKeyRing agentPubKeyRing,
|
||||
@ -251,8 +251,8 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
||||
Optional.ofNullable(depositTxId).ifPresent(builder::setDepositTxId);
|
||||
Optional.ofNullable(payoutTxId).ifPresent(builder::setPayoutTxId);
|
||||
Optional.ofNullable(disputePayoutTxId).ifPresent(builder::setDisputePayoutTxId);
|
||||
Optional.ofNullable(makerContractSignature).ifPresent(builder::setMakerContractSignature);
|
||||
Optional.ofNullable(takerContractSignature).ifPresent(builder::setTakerContractSignature);
|
||||
Optional.ofNullable(makerContractSignature).ifPresent(e -> builder.setMakerContractSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(takerContractSignature).ifPresent(e -> builder.setTakerContractSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(makerPaymentAccountPayload).ifPresent(e -> builder.setMakerPaymentAccountPayload((protobuf.PaymentAccountPayload) makerPaymentAccountPayload.toProtoMessage()));
|
||||
Optional.ofNullable(takerPaymentAccountPayload).ifPresent(e -> builder.setTakerPaymentAccountPayload((protobuf.PaymentAccountPayload) takerPaymentAccountPayload.toProtoMessage()));
|
||||
Optional.ofNullable(disputeResultProperty.get()).ifPresent(result -> builder.setDisputeResult(disputeResultProperty.get().toProtoMessage()));
|
||||
@ -281,8 +281,8 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
||||
ProtoUtil.stringOrNullFromProto(proto.getDepositTxId()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getPayoutTxId()),
|
||||
proto.getContractAsJson(),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getMakerContractSignature()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getTakerContractSignature()),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getMakerContractSignature()),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getTakerContractSignature()),
|
||||
proto.hasMakerPaymentAccountPayload() ? coreProtoResolver.fromProto(proto.getMakerPaymentAccountPayload()) : null,
|
||||
proto.hasTakerPaymentAccountPayload() ? coreProtoResolver.fromProto(proto.getTakerPaymentAccountPayload()) : null,
|
||||
PubKeyRing.fromProto(proto.getAgentPubKeyRing()),
|
||||
@ -524,8 +524,8 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
||||
",\n depositTxId='" + depositTxId + '\'' +
|
||||
",\n payoutTxId='" + payoutTxId + '\'' +
|
||||
",\n contractAsJson='" + contractAsJson + '\'' +
|
||||
",\n makerContractSignature='" + makerContractSignature + '\'' +
|
||||
",\n takerContractSignature='" + takerContractSignature + '\'' +
|
||||
",\n makerContractSignature='" + Utilities.bytesAsHexString(makerContractSignature) + '\'' +
|
||||
",\n takerContractSignature='" + Utilities.bytesAsHexString(takerContractSignature) + '\'' +
|
||||
",\n agentPubKeyRing=" + agentPubKeyRing +
|
||||
",\n isSupportTicket=" + isSupportTicket +
|
||||
",\n chatMessages=" + chatMessages +
|
||||
|
@ -17,16 +17,14 @@
|
||||
|
||||
package haveno.core.support.dispute;
|
||||
|
||||
import haveno.common.crypto.CryptoException;
|
||||
import haveno.common.crypto.Hash;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.support.dispute.agent.DisputeAgent;
|
||||
import haveno.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -46,10 +44,10 @@ public class DisputeSummaryVerification {
|
||||
KeyPair signatureKeyPair = disputeManager.getSignatureKeyPair();
|
||||
String sigAsHex;
|
||||
try {
|
||||
byte[] signature = Sig.sign(signatureKeyPair.getPrivate(), hash);
|
||||
byte[] signature = HavenoUtils.sign(signatureKeyPair.getPrivate(), hash);
|
||||
sigAsHex = Utilities.encodeToHex(signature);
|
||||
disputeResult.setArbitratorSignature(signature);
|
||||
} catch (CryptoException e) {
|
||||
} catch (Exception e) {
|
||||
sigAsHex = "Signing failed";
|
||||
}
|
||||
|
||||
@ -69,19 +67,13 @@ public class DisputeSummaryVerification {
|
||||
NodeAddress nodeAddress = new NodeAddress(fullAddress);
|
||||
DisputeAgent disputeAgent = arbitratorMediator.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
|
||||
checkNotNull(disputeAgent, "Dispute agent is null");
|
||||
PublicKey pubKey = disputeAgent.getPubKeyRing().getSignaturePubKey();
|
||||
|
||||
String sigString = parts[1].split(SEPARATOR2)[0];
|
||||
byte[] sig = Utilities.decodeFromHex(sigString);
|
||||
byte[] hash = Hash.getSha256Hash(textToSign);
|
||||
try {
|
||||
boolean result = Sig.verify(pubKey, hash, sig);
|
||||
if (result) {
|
||||
return;
|
||||
} else {
|
||||
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.failed"));
|
||||
}
|
||||
} catch (CryptoException e) {
|
||||
HavenoUtils.verifySignature(disputeAgent.getPubKeyRing(), hash, sig);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.failed"));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
|
@ -18,12 +18,11 @@
|
||||
package haveno.core.support.dispute;
|
||||
|
||||
import haveno.common.config.Config;
|
||||
import haveno.common.crypto.CryptoException;
|
||||
import haveno.common.crypto.Hash;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.util.Tuple3;
|
||||
import haveno.core.support.SupportType;
|
||||
import haveno.core.trade.Contract;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.Trade;
|
||||
import haveno.core.util.JsonUtil;
|
||||
import haveno.core.util.validation.RegexValidatorFactory;
|
||||
@ -64,23 +63,11 @@ public class DisputeValidation {
|
||||
checkArgument(Arrays.equals(Objects.requireNonNull(dispute.getContractHash()), Hash.getSha256Hash(checkNotNull(dispute.getContractAsJson()))),
|
||||
"Invalid contractHash");
|
||||
|
||||
try {
|
||||
// Only the dispute opener has set the signature
|
||||
String makerContractSignature = dispute.getMakerContractSignature();
|
||||
if (makerContractSignature != null) {
|
||||
Sig.verify(contract.getMakerPubKeyRing().getSignaturePubKey(),
|
||||
dispute.getContractAsJson(),
|
||||
makerContractSignature);
|
||||
}
|
||||
String takerContractSignature = dispute.getTakerContractSignature();
|
||||
if (takerContractSignature != null) {
|
||||
Sig.verify(contract.getTakerPubKeyRing().getSignaturePubKey(),
|
||||
dispute.getContractAsJson(),
|
||||
takerContractSignature);
|
||||
}
|
||||
} catch (CryptoException e) {
|
||||
throw new ValidationException(dispute, e.getMessage());
|
||||
}
|
||||
// Only the dispute opener has set the signature
|
||||
byte[] makerContractSignature = dispute.getMakerContractSignature();
|
||||
if (makerContractSignature != null) HavenoUtils.verifySignature(contract.getMakerPubKeyRing(), dispute.getContractAsJson(), makerContractSignature);
|
||||
byte[] takerContractSignature = dispute.getTakerContractSignature();
|
||||
if (takerContractSignature != null) HavenoUtils.verifySignature(contract.getTakerPubKeyRing(), dispute.getContractAsJson(), takerContractSignature);
|
||||
} catch (Throwable t) {
|
||||
throw new ValidationException(dispute, t.getMessage());
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Charsets;
|
||||
import haveno.common.config.Config;
|
||||
import haveno.common.crypto.Hash;
|
||||
import haveno.common.crypto.KeyRing;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.util.Utilities;
|
||||
@ -39,7 +40,7 @@ import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
@ -236,6 +237,170 @@ public class HavenoUtils {
|
||||
return feePerXmrAsDecimal.multiply(amountMultiplier).toBigInteger();
|
||||
}
|
||||
|
||||
// ------------------------ SIGNING AND VERIFYING -------------------------
|
||||
|
||||
public static byte[] sign(KeyRing keyRing, String message) {
|
||||
return sign(keyRing.getSignatureKeyPair().getPrivate(), message);
|
||||
}
|
||||
|
||||
public static byte[] sign(PrivateKey privateKey, String message) {
|
||||
return sign(privateKey, message.getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
public static byte[] sign(PrivateKey privateKey, byte[] bytes) {
|
||||
try {
|
||||
return Sig.sign(privateKey, bytes);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void verifySignature(PubKeyRing pubKeyRing, String message, byte[] signature) {
|
||||
verifySignature(pubKeyRing, message.getBytes(Charsets.UTF_8), signature);
|
||||
}
|
||||
|
||||
public static void verifySignature(PubKeyRing pubKeyRing, byte[] bytes, byte[] signature) {
|
||||
try {
|
||||
Sig.verify(pubKeyRing.getSignaturePubKey(), bytes, signature);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSignatureValid(PubKeyRing pubKeyRing, String message, byte[] signature) {
|
||||
return isSignatureValid(pubKeyRing, message.getBytes(Charsets.UTF_8), signature);
|
||||
}
|
||||
|
||||
public static boolean isSignatureValid(PubKeyRing pubKeyRing, byte[] bytes, byte[] signature) {
|
||||
try {
|
||||
verifySignature(pubKeyRing, bytes, signature);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the arbitrator signature is valid for an offer.
|
||||
*
|
||||
* @param offer is a signed offer with payload
|
||||
* @param arbitrator is the original signing arbitrator
|
||||
* @return true if the arbitrator's signature is valid for the offer
|
||||
*/
|
||||
public static boolean isArbitratorSignatureValid(Offer offer, Arbitrator arbitrator) {
|
||||
|
||||
// copy offer payload
|
||||
OfferPayload offerPayloadCopy = OfferPayload.fromProto(offer.toProtoMessage().getOfferPayload());
|
||||
|
||||
// remove arbitrator signature from signed payload
|
||||
byte[] signature = offerPayloadCopy.getArbitratorSignature();
|
||||
offerPayloadCopy.setArbitratorSignature(null);
|
||||
|
||||
// get unsigned offer payload as json string
|
||||
String unsignedOfferAsJson = JsonUtil.objectToJson(offerPayloadCopy);
|
||||
|
||||
// verify signature
|
||||
return isSignatureValid(arbitrator.getPubKeyRing(), unsignedOfferAsJson, signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the maker signature for a trade request is valid.
|
||||
*
|
||||
* @param request is the trade request to check
|
||||
* @return true if the maker's signature is valid for the trade request
|
||||
*/
|
||||
public static boolean isMakerSignatureValid(InitTradeRequest request, byte[] signature, PubKeyRing makerPubKeyRing) {
|
||||
|
||||
// re-create trade request with signed fields
|
||||
InitTradeRequest signedRequest = new InitTradeRequest(
|
||||
request.getTradeId(),
|
||||
request.getSenderNodeAddress(),
|
||||
request.getPubKeyRing(),
|
||||
request.getTradeAmount(),
|
||||
request.getTradePrice(),
|
||||
request.getTradeFee(),
|
||||
request.getAccountId(),
|
||||
request.getPaymentAccountId(),
|
||||
request.getPaymentMethodId(),
|
||||
request.getUid(),
|
||||
request.getMessageVersion(),
|
||||
request.getAccountAgeWitnessSignatureOfOfferId(),
|
||||
request.getCurrentDate(),
|
||||
request.getMakerNodeAddress(),
|
||||
request.getTakerNodeAddress(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
request.getPayoutAddress(),
|
||||
null
|
||||
);
|
||||
|
||||
// get trade request as string
|
||||
String tradeRequestAsJson = JsonUtil.objectToJson(signedRequest);
|
||||
|
||||
// verify maker signature
|
||||
return isSignatureValid(makerPubKeyRing, tradeRequestAsJson, signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the buyer signature for a PaymentSentMessage.
|
||||
*
|
||||
* @param trade - the trade to verify
|
||||
* @param message - signed payment sent message to verify
|
||||
* @return true if the buyer's signature is valid for the message
|
||||
*/
|
||||
public static void verifyPaymentSentMessage(Trade trade, PaymentSentMessage message) {
|
||||
|
||||
// remove signature from message
|
||||
byte[] signature = message.getBuyerSignature();
|
||||
message.setBuyerSignature(null);
|
||||
|
||||
// get unsigned message as json string
|
||||
String unsignedMessageAsJson = JsonUtil.objectToJson(message);
|
||||
|
||||
// replace signature
|
||||
message.setBuyerSignature(signature);
|
||||
|
||||
// verify signature
|
||||
if (!isSignatureValid(trade.getBuyer().getPubKeyRing(), unsignedMessageAsJson, signature)) {
|
||||
throw new IllegalArgumentException("The buyer signature is invalid for the " + message.getClass().getSimpleName() + " for " + trade.getClass().getSimpleName() + " " + trade.getId());
|
||||
}
|
||||
|
||||
// verify trade id
|
||||
if (!trade.getId().equals(message.getTradeId())) throw new IllegalArgumentException("The " + message.getClass().getSimpleName() + " has the wrong trade id, expected " + trade.getId() + " but was " + message.getTradeId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the seller signature for a PaymentReceivedMessage.
|
||||
*
|
||||
* @param trade - the trade to verify
|
||||
* @param message - signed payment received message to verify
|
||||
* @return true if the seller's signature is valid for the message
|
||||
*/
|
||||
public static void verifyPaymentReceivedMessage(Trade trade, PaymentReceivedMessage message) {
|
||||
|
||||
// remove signature from message
|
||||
byte[] signature = message.getSellerSignature();
|
||||
message.setSellerSignature(null);
|
||||
|
||||
// get unsigned message as json string
|
||||
String unsignedMessageAsJson = JsonUtil.objectToJson(message);
|
||||
|
||||
// replace signature
|
||||
message.setSellerSignature(signature);
|
||||
|
||||
// verify signature
|
||||
if (!isSignatureValid(trade.getSeller().getPubKeyRing(), unsignedMessageAsJson, signature)) {
|
||||
throw new IllegalArgumentException("The seller signature is invalid for the " + message.getClass().getSimpleName() + " for " + trade.getClass().getSimpleName() + " " + trade.getId());
|
||||
}
|
||||
|
||||
// verify trade id
|
||||
if (!trade.getId().equals(message.getTradeId())) throw new IllegalArgumentException("The " + message.getClass().getSimpleName() + " has the wrong trade id, expected " + trade.getId() + " but was " + message.getTradeId());
|
||||
|
||||
// verify buyer signature of payment sent message
|
||||
verifyPaymentSentMessage(trade, message.getPaymentSentMessage());
|
||||
}
|
||||
|
||||
// ----------------------------- OTHER UTILS ------------------------------
|
||||
|
||||
@ -282,144 +447,6 @@ public class HavenoUtils {
|
||||
return Utilities.bytesAsHexString(Hash.getSha256Ripemd160hash(uniqueId.getBytes(Charsets.UTF_8)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the arbitrator signature is valid for an offer.
|
||||
*
|
||||
* @param offer is a signed offer with payload
|
||||
* @param arbitrator is the original signing arbitrator
|
||||
* @return true if the arbitrator's signature is valid for the offer
|
||||
*/
|
||||
public static boolean isArbitratorSignatureValid(Offer offer, Arbitrator arbitrator) {
|
||||
|
||||
// copy offer payload
|
||||
OfferPayload offerPayloadCopy = OfferPayload.fromProto(offer.toProtoMessage().getOfferPayload());
|
||||
|
||||
// remove arbitrator signature from signed payload
|
||||
String signature = offerPayloadCopy.getArbitratorSignature();
|
||||
offerPayloadCopy.setArbitratorSignature(null);
|
||||
|
||||
// get unsigned offer payload as json string
|
||||
String unsignedOfferAsJson = JsonUtil.objectToJson(offerPayloadCopy);
|
||||
|
||||
// verify arbitrator signature
|
||||
try {
|
||||
return Sig.verify(arbitrator.getPubKeyRing().getSignaturePubKey(), unsignedOfferAsJson, signature);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the maker signature for a trade request is valid.
|
||||
*
|
||||
* @param request is the trade request to check
|
||||
* @return true if the maker's signature is valid for the trade request
|
||||
*/
|
||||
public static boolean isMakerSignatureValid(InitTradeRequest request, String signature, PubKeyRing makerPubKeyRing) {
|
||||
|
||||
// re-create trade request with signed fields
|
||||
InitTradeRequest signedRequest = new InitTradeRequest(
|
||||
request.getTradeId(),
|
||||
request.getSenderNodeAddress(),
|
||||
request.getPubKeyRing(),
|
||||
request.getTradeAmount(),
|
||||
request.getTradePrice(),
|
||||
request.getTradeFee(),
|
||||
request.getAccountId(),
|
||||
request.getPaymentAccountId(),
|
||||
request.getPaymentMethodId(),
|
||||
request.getUid(),
|
||||
request.getMessageVersion(),
|
||||
request.getAccountAgeWitnessSignatureOfOfferId(),
|
||||
request.getCurrentDate(),
|
||||
request.getMakerNodeAddress(),
|
||||
request.getTakerNodeAddress(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
request.getPayoutAddress(),
|
||||
null
|
||||
);
|
||||
|
||||
// get trade request as string
|
||||
String tradeRequestAsJson = JsonUtil.objectToJson(signedRequest);
|
||||
|
||||
// verify maker signature
|
||||
try {
|
||||
return Sig.verify(makerPubKeyRing.getSignaturePubKey(),
|
||||
tradeRequestAsJson,
|
||||
signature);
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the buyer signature for a PaymentSentMessage.
|
||||
*
|
||||
* @param trade - the trade to verify
|
||||
* @param message - signed payment sent message to verify
|
||||
* @return true if the buyer's signature is valid for the message
|
||||
*/
|
||||
public static void verifyPaymentSentMessage(Trade trade, PaymentSentMessage message) {
|
||||
|
||||
// remove signature from message
|
||||
byte[] signature = message.getBuyerSignature();
|
||||
message.setBuyerSignature(null);
|
||||
|
||||
// get unsigned message as json string
|
||||
String unsignedMessageAsJson = JsonUtil.objectToJson(message);
|
||||
|
||||
// replace signature
|
||||
message.setBuyerSignature(signature);
|
||||
|
||||
// verify signature
|
||||
String errMessage = "The buyer signature is invalid for the " + message.getClass().getSimpleName() + " for " + trade.getClass().getSimpleName() + " " + trade.getId();
|
||||
try {
|
||||
if (!Sig.verify(trade.getBuyer().getPubKeyRing().getSignaturePubKey(), unsignedMessageAsJson.getBytes(Charsets.UTF_8), signature)) throw new IllegalArgumentException(errMessage);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(errMessage);
|
||||
}
|
||||
|
||||
// verify trade id
|
||||
if (!trade.getId().equals(message.getTradeId())) throw new IllegalArgumentException("The " + message.getClass().getSimpleName() + " has the wrong trade id, expected " + trade.getId() + " but was " + message.getTradeId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the seller signature for a PaymentReceivedMessage.
|
||||
*
|
||||
* @param trade - the trade to verify
|
||||
* @param message - signed payment received message to verify
|
||||
* @return true if the seller's signature is valid for the message
|
||||
*/
|
||||
public static void verifyPaymentReceivedMessage(Trade trade, PaymentReceivedMessage message) {
|
||||
|
||||
// remove signature from message
|
||||
byte[] signature = message.getSellerSignature();
|
||||
message.setSellerSignature(null);
|
||||
|
||||
// get unsigned message as json string
|
||||
String unsignedMessageAsJson = JsonUtil.objectToJson(message);
|
||||
|
||||
// replace signature
|
||||
message.setSellerSignature(signature);
|
||||
|
||||
// verify signature
|
||||
String errMessage = "The seller signature is invalid for the " + message.getClass().getSimpleName() + " for " + trade.getClass().getSimpleName() + " " + trade.getId();
|
||||
try {
|
||||
if (!Sig.verify(trade.getSeller().getPubKeyRing().getSignaturePubKey(), unsignedMessageAsJson.getBytes(Charsets.UTF_8), signature)) throw new IllegalArgumentException(errMessage);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(errMessage);
|
||||
}
|
||||
|
||||
// verify trade id
|
||||
if (!trade.getId().equals(message.getTradeId())) throw new IllegalArgumentException("The " + message.getClass().getSimpleName() + " has the wrong trade id, expected " + trade.getId() + " but was " + message.getTradeId());
|
||||
|
||||
// verify buyer signature of payment sent message
|
||||
verifyPaymentSentMessage(trade, message.getPaymentSentMessage());
|
||||
}
|
||||
|
||||
public static void awaitLatch(CountDownLatch latch) {
|
||||
try {
|
||||
latch.await();
|
||||
|
@ -19,6 +19,7 @@ package haveno.core.trade.messages;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import haveno.common.proto.ProtoUtil;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.proto.CoreProtoResolver;
|
||||
import haveno.network.p2p.DirectMessage;
|
||||
import java.util.Optional;
|
||||
@ -30,7 +31,7 @@ import lombok.Value;
|
||||
@Value
|
||||
public final class DepositRequest extends TradeMessage implements DirectMessage {
|
||||
private final long currentDate;
|
||||
private final String contractSignature;
|
||||
private final byte[] contractSignature;
|
||||
private final String depositTxHex;
|
||||
private final String depositTxKey;
|
||||
@Nullable
|
||||
@ -40,7 +41,7 @@ public final class DepositRequest extends TradeMessage implements DirectMessage
|
||||
String uid,
|
||||
String messageVersion,
|
||||
long currentDate,
|
||||
String contractSignature,
|
||||
byte[] contractSignature,
|
||||
String depositTxHex,
|
||||
String depositTxKey,
|
||||
@Nullable byte[] paymentAccountKey) {
|
||||
@ -62,11 +63,11 @@ public final class DepositRequest extends TradeMessage implements DirectMessage
|
||||
protobuf.DepositRequest.Builder builder = protobuf.DepositRequest.newBuilder()
|
||||
.setTradeId(tradeId)
|
||||
.setUid(uid)
|
||||
.setContractSignature(contractSignature)
|
||||
.setDepositTxHex(depositTxHex)
|
||||
.setDepositTxKey(depositTxKey);
|
||||
builder.setCurrentDate(currentDate);
|
||||
Optional.ofNullable(paymentAccountKey).ifPresent(e -> builder.setPaymentAccountKey(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(contractSignature).ifPresent(e -> builder.setContractSignature(ByteString.copyFrom(e)));
|
||||
|
||||
return getNetworkEnvelopeBuilder().setDepositRequest(builder).build();
|
||||
}
|
||||
@ -78,7 +79,7 @@ public final class DepositRequest extends TradeMessage implements DirectMessage
|
||||
proto.getUid(),
|
||||
messageVersion,
|
||||
proto.getCurrentDate(),
|
||||
proto.getContractSignature(),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getContractSignature()),
|
||||
proto.getDepositTxHex(),
|
||||
proto.getDepositTxKey(),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getPaymentAccountKey()));
|
||||
@ -88,7 +89,7 @@ public final class DepositRequest extends TradeMessage implements DirectMessage
|
||||
public String toString() {
|
||||
return "DepositRequest {" +
|
||||
",\n currentDate=" + currentDate +
|
||||
",\n contractSignature=" + contractSignature +
|
||||
",\n contractSignature=" + Utilities.bytesAsHexString(contractSignature) +
|
||||
",\n depositTxHex='" + depositTxHex +
|
||||
",\n depositTxKey='" + depositTxKey +
|
||||
",\n paymentAccountKey='" + paymentAccountKey +
|
||||
|
@ -62,7 +62,7 @@ public final class InitTradeRequest extends TradeMessage implements DirectMessag
|
||||
@Nullable
|
||||
private final String payoutAddress;
|
||||
@Nullable
|
||||
private final String makerSignature;
|
||||
private final byte[] makerSignature;
|
||||
|
||||
public InitTradeRequest(String tradeId,
|
||||
NodeAddress senderNodeAddress,
|
||||
@ -84,7 +84,7 @@ public final class InitTradeRequest extends TradeMessage implements DirectMessag
|
||||
@Nullable String reserveTxHex,
|
||||
@Nullable String reserveTxKey,
|
||||
@Nullable String payoutAddress,
|
||||
@Nullable String makerSignature) {
|
||||
@Nullable byte[] makerSignature) {
|
||||
super(messageVersion, tradeId, uid);
|
||||
this.senderNodeAddress = senderNodeAddress;
|
||||
this.pubKeyRing = pubKeyRing;
|
||||
@ -133,7 +133,7 @@ public final class InitTradeRequest extends TradeMessage implements DirectMessag
|
||||
Optional.ofNullable(reserveTxKey).ifPresent(e -> builder.setReserveTxKey(reserveTxKey));
|
||||
Optional.ofNullable(payoutAddress).ifPresent(e -> builder.setPayoutAddress(payoutAddress));
|
||||
Optional.ofNullable(accountAgeWitnessSignatureOfOfferId).ifPresent(e -> builder.setAccountAgeWitnessSignatureOfOfferId(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(makerSignature).ifPresent(e -> builder.setMakerSignature(makerSignature));
|
||||
Optional.ofNullable(makerSignature).ifPresent(e -> builder.setMakerSignature(ByteString.copyFrom(e)));
|
||||
builder.setCurrentDate(currentDate);
|
||||
|
||||
return getNetworkEnvelopeBuilder().setInitTradeRequest(builder).build();
|
||||
@ -162,7 +162,7 @@ public final class InitTradeRequest extends TradeMessage implements DirectMessag
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxHex()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getReserveTxKey()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getPayoutAddress()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getMakerSignature()));
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getMakerSignature()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -183,7 +183,7 @@ public final class InitTradeRequest extends TradeMessage implements DirectMessag
|
||||
",\n reserveTxHex=" + reserveTxHex +
|
||||
",\n reserveTxKey=" + reserveTxKey +
|
||||
",\n payoutAddress=" + payoutAddress +
|
||||
",\n makerSignature=" + makerSignature +
|
||||
",\n makerSignature=" + Utilities.byteArrayToInteger(makerSignature) +
|
||||
"\n} " + super.toString();
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,10 @@
|
||||
package haveno.core.trade.messages;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.proto.ProtoUtil;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.proto.CoreProtoResolver;
|
||||
import haveno.network.p2p.DirectMessage;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -33,7 +32,7 @@ import lombok.Value;
|
||||
public final class SignContractResponse extends TradeMessage implements DirectMessage {
|
||||
private final long currentDate;
|
||||
private final String contractAsJson;
|
||||
private final String contractSignature;
|
||||
private final byte[] contractSignature;
|
||||
private final byte[] encryptedPaymentAccountPayload;
|
||||
|
||||
public SignContractResponse(String tradeId,
|
||||
@ -41,7 +40,7 @@ public final class SignContractResponse extends TradeMessage implements DirectMe
|
||||
String messageVersion,
|
||||
long currentDate,
|
||||
String contractAsJson,
|
||||
String contractSignature,
|
||||
byte[] contractSignature,
|
||||
@Nullable byte[] encryptedPaymentAccountPayload) {
|
||||
super(messageVersion, tradeId, uid);
|
||||
this.currentDate = currentDate;
|
||||
@ -62,7 +61,7 @@ public final class SignContractResponse extends TradeMessage implements DirectMe
|
||||
.setUid(uid);
|
||||
|
||||
Optional.ofNullable(contractAsJson).ifPresent(e -> builder.setContractAsJson(contractAsJson));
|
||||
Optional.ofNullable(contractSignature).ifPresent(e -> builder.setContractSignature(contractSignature));
|
||||
Optional.ofNullable(contractSignature).ifPresent(e -> builder.setContractSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(encryptedPaymentAccountPayload).ifPresent(e -> builder.setEncryptedPaymentAccountPayload(ByteString.copyFrom(e)));
|
||||
|
||||
builder.setCurrentDate(currentDate);
|
||||
@ -78,7 +77,7 @@ public final class SignContractResponse extends TradeMessage implements DirectMe
|
||||
messageVersion,
|
||||
proto.getCurrentDate(),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getContractAsJson()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getContractSignature()),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getContractSignature()),
|
||||
proto.getEncryptedPaymentAccountPayload().toByteArray());
|
||||
}
|
||||
|
||||
@ -87,7 +86,7 @@ public final class SignContractResponse extends TradeMessage implements DirectMe
|
||||
return "SignContractResponse {" +
|
||||
",\n currentDate=" + currentDate +
|
||||
",\n contractAsJson='" + contractAsJson +
|
||||
",\n contractSignature='" + contractSignature +
|
||||
",\n contractSignature='" + Utilities.bytesAsHexString(contractSignature) +
|
||||
"\n} " + super.toString();
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ public class ProcessModel implements Model, PersistablePayload {
|
||||
transient private TradeMessage tradeMessage;
|
||||
@Getter
|
||||
@Setter
|
||||
private String makerSignature;
|
||||
private byte[] makerSignature;
|
||||
@Nullable
|
||||
@Getter
|
||||
@Setter
|
||||
@ -220,7 +220,8 @@ public class ProcessModel implements Model, PersistablePayload {
|
||||
Optional.ofNullable(takeOfferFeeTxId).ifPresent(builder::setTakeOfferFeeTxId);
|
||||
Optional.ofNullable(payoutTxSignature).ifPresent(e -> builder.setPayoutTxSignature(ByteString.copyFrom(payoutTxSignature)));
|
||||
Optional.ofNullable(tempTradePeerNodeAddress).ifPresent(e -> builder.setTempTradePeerNodeAddress(tempTradePeerNodeAddress.toProtoMessage()));
|
||||
Optional.ofNullable(makerSignature).ifPresent(e -> builder.setMakerSignature(makerSignature));
|
||||
Optional.ofNullable(mediatedPayoutTxSignature).ifPresent(e -> builder.setMediatedPayoutTxSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(makerSignature).ifPresent(e -> builder.setMakerSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(multisigAddress).ifPresent(e -> builder.setMultisigAddress(multisigAddress));
|
||||
Optional.ofNullable(paymentSentMessage).ifPresent(e -> builder.setPaymentSentMessage(paymentSentMessage.toProtoNetworkEnvelope().getPaymentSentMessage()));
|
||||
Optional.ofNullable(paymentReceivedMessage).ifPresent(e -> builder.setPaymentReceivedMessage(paymentReceivedMessage.toProtoNetworkEnvelope().getPaymentReceivedMessage()));
|
||||
@ -245,7 +246,7 @@ public class ProcessModel implements Model, PersistablePayload {
|
||||
processModel.setPayoutTxSignature(ProtoUtil.byteArrayOrNullFromProto(proto.getPayoutTxSignature()));
|
||||
processModel.setTempTradePeerNodeAddress(proto.hasTempTradePeerNodeAddress() ? NodeAddress.fromProto(proto.getTempTradePeerNodeAddress()) : null);
|
||||
processModel.setMediatedPayoutTxSignature(ProtoUtil.byteArrayOrNullFromProto(proto.getMediatedPayoutTxSignature()));
|
||||
processModel.setMakerSignature(proto.getMakerSignature());
|
||||
processModel.setMakerSignature(ProtoUtil.byteArrayOrNullFromProto(proto.getMakerSignature()));
|
||||
processModel.setMultisigAddress(ProtoUtil.stringOrNullFromProto(proto.getMultisigAddress()));
|
||||
|
||||
String paymentSentMessageStateString = ProtoUtil.stringOrNullFromProto(proto.getPaymentSentMessageState());
|
||||
|
@ -79,7 +79,7 @@ public final class TradePeer implements PersistablePayload {
|
||||
@Nullable
|
||||
private String contractAsJson;
|
||||
@Nullable
|
||||
private String contractSignature;
|
||||
private byte[] contractSignature;
|
||||
|
||||
// added in v 0.6
|
||||
@Nullable
|
||||
@ -146,7 +146,7 @@ public final class TradePeer implements PersistablePayload {
|
||||
Optional.ofNullable(paymentAccountPayload).ifPresent(e -> builder.setPaymentAccountPayload((protobuf.PaymentAccountPayload) e.toProtoMessage()));
|
||||
Optional.ofNullable(payoutAddressString).ifPresent(builder::setPayoutAddressString);
|
||||
Optional.ofNullable(contractAsJson).ifPresent(builder::setContractAsJson);
|
||||
Optional.ofNullable(contractSignature).ifPresent(builder::setContractSignature);
|
||||
Optional.ofNullable(contractSignature).ifPresent(e -> builder.setContractSignature(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(pubKeyRing).ifPresent(e -> builder.setPubKeyRing(e.toProtoMessage()));
|
||||
Optional.ofNullable(accountAgeWitnessNonce).ifPresent(e -> builder.setAccountAgeWitnessNonce(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(accountAgeWitnessSignature).ifPresent(e -> builder.setAccountAgeWitnessSignature(ByteString.copyFrom(e)));
|
||||
@ -185,7 +185,7 @@ public final class TradePeer implements PersistablePayload {
|
||||
tradePeer.setPaymentAccountPayload(proto.hasPaymentAccountPayload() ? coreProtoResolver.fromProto(proto.getPaymentAccountPayload()) : null);
|
||||
tradePeer.setPayoutAddressString(ProtoUtil.stringOrNullFromProto(proto.getPayoutAddressString()));
|
||||
tradePeer.setContractAsJson(ProtoUtil.stringOrNullFromProto(proto.getContractAsJson()));
|
||||
tradePeer.setContractSignature(ProtoUtil.stringOrNullFromProto(proto.getContractSignature()));
|
||||
tradePeer.setContractSignature(ProtoUtil.byteArrayOrNullFromProto(proto.getContractSignature()));
|
||||
tradePeer.setPubKeyRing(proto.hasPubKeyRing() ? PubKeyRing.fromProto(proto.getPubKeyRing()) : null);
|
||||
tradePeer.setAccountAgeWitnessNonce(ProtoUtil.byteArrayOrNullFromProto(proto.getAccountAgeWitnessNonce()));
|
||||
tradePeer.setAccountAgeWitnessSignature(ProtoUtil.byteArrayOrNullFromProto(proto.getAccountAgeWitnessSignature()));
|
||||
|
@ -24,6 +24,7 @@ import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.offer.Offer;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.Trade;
|
||||
import haveno.core.trade.messages.DepositRequest;
|
||||
import haveno.core.trade.messages.DepositResponse;
|
||||
@ -58,7 +59,7 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
||||
// get contract and signature
|
||||
String contractAsJson = trade.getContractAsJson();
|
||||
DepositRequest request = (DepositRequest) processModel.getTradeMessage(); // TODO (woodser): verify response
|
||||
String signature = request.getContractSignature();
|
||||
byte[] signature = request.getContractSignature();
|
||||
|
||||
// get trader info
|
||||
TradePeer trader = trade.getTradePeer(processModel.getTempTradePeerNodeAddress());
|
||||
@ -66,7 +67,9 @@ public class ArbitratorProcessDepositRequest extends TradeTask {
|
||||
PubKeyRing peerPubKeyRing = trader.getPubKeyRing();
|
||||
|
||||
// verify signature
|
||||
if (!Sig.verify(peerPubKeyRing.getSignaturePubKey(), contractAsJson, signature)) throw new RuntimeException("Peer's contract signature is invalid");
|
||||
if (!HavenoUtils.isSignatureValid(peerPubKeyRing, contractAsJson, signature)) {
|
||||
throw new RuntimeException("Peer's contract signature is invalid");
|
||||
}
|
||||
|
||||
// set peer's signature
|
||||
trader.setContractSignature(signature);
|
||||
|
@ -17,10 +17,8 @@
|
||||
|
||||
package haveno.core.trade.protocol.tasks;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import haveno.common.Timer;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.network.MessageState;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
@ -94,7 +92,7 @@ public abstract class BuyerSendPaymentSentMessage extends SendMailboxMessageTask
|
||||
// sign message
|
||||
try {
|
||||
String messageAsJson = JsonUtil.objectToJson(message);
|
||||
byte[] sig = Sig.sign(processModel.getP2PService().getKeyRing().getSignatureKeyPair().getPrivate(), messageAsJson.getBytes(Charsets.UTF_8));
|
||||
byte[] sig = HavenoUtils.sign(processModel.getP2PService().getKeyRing(), messageAsJson);
|
||||
message.setBuyerSignature(sig);
|
||||
processModel.setPaymentSentMessage(message);
|
||||
trade.requestPersistence();
|
||||
|
@ -22,11 +22,10 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import haveno.common.app.Version;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.trade.ArbitratorTrade;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.MakerTrade;
|
||||
import haveno.core.trade.Trade;
|
||||
import haveno.core.trade.Trade.State;
|
||||
@ -90,7 +89,7 @@ public class MaybeSendSignContractRequest extends TradeTask {
|
||||
// maker signs deposit hash nonce to avoid challenge protocol
|
||||
byte[] sig = null;
|
||||
if (trade instanceof MakerTrade) {
|
||||
sig = Sig.sign(processModel.getP2PService().getKeyRing().getSignatureKeyPair().getPrivate(), depositTx.getHash().getBytes(Charsets.UTF_8));
|
||||
sig = HavenoUtils.sign(processModel.getP2PService().getKeyRing(), depositTx.getHash());
|
||||
}
|
||||
|
||||
// create request for peer and arbitrator to sign contract
|
||||
|
@ -30,10 +30,10 @@ import haveno.common.crypto.Encryption;
|
||||
import haveno.common.crypto.Hash;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.crypto.ScryptUtil;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.trade.ArbitratorTrade;
|
||||
import haveno.core.trade.Contract;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.Trade;
|
||||
import haveno.core.trade.Trade.State;
|
||||
import haveno.core.trade.messages.SignContractRequest;
|
||||
@ -85,7 +85,7 @@ public class ProcessSignContractRequest extends TradeTask {
|
||||
// create and sign contract
|
||||
Contract contract = trade.createContract();
|
||||
String contractAsJson = JsonUtil.objectToJson(contract);
|
||||
String signature = Sig.sign(processModel.getKeyRing().getSignatureKeyPair().getPrivate(), contractAsJson);
|
||||
byte[] signature = HavenoUtils.sign(processModel.getKeyRing(), contractAsJson);
|
||||
|
||||
// save contract and signature
|
||||
trade.setContract(contract);
|
||||
|
@ -20,8 +20,8 @@ package haveno.core.trade.protocol.tasks;
|
||||
|
||||
import haveno.common.app.Version;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.Trade;
|
||||
import haveno.core.trade.messages.DepositRequest;
|
||||
import haveno.core.trade.messages.SignContractResponse;
|
||||
@ -63,8 +63,8 @@ public class ProcessSignContractResponse extends TradeTask {
|
||||
|
||||
// verify signature
|
||||
// TODO (woodser): transfer contract for convenient comparison?
|
||||
String signature = response.getContractSignature();
|
||||
if (!Sig.verify(peerPubKeyRing.getSignaturePubKey(), contractAsJson, signature)) throw new RuntimeException("Peer's contract signature is invalid");
|
||||
byte[] signature = response.getContractSignature();
|
||||
if (!HavenoUtils.isSignatureValid(peerPubKeyRing, contractAsJson, signature)) throw new RuntimeException("Peer's contract signature is invalid");
|
||||
|
||||
// set peer's signature
|
||||
peer.setContractSignature(signature);
|
||||
|
@ -22,9 +22,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import haveno.common.crypto.PubKeyRing;
|
||||
import haveno.common.crypto.Sig;
|
||||
import haveno.common.taskrunner.TaskRunner;
|
||||
import haveno.core.account.sign.SignedWitness;
|
||||
import haveno.core.account.witness.AccountAgeWitnessService;
|
||||
@ -92,7 +90,7 @@ public abstract class SellerSendPaymentReceivedMessage extends SendMailboxMessag
|
||||
// sign message
|
||||
try {
|
||||
String messageAsJson = JsonUtil.objectToJson(message);
|
||||
byte[] sig = Sig.sign(processModel.getP2PService().getKeyRing().getSignatureKeyPair().getPrivate(), messageAsJson.getBytes(Charsets.UTF_8));
|
||||
byte[] sig = HavenoUtils.sign(processModel.getP2PService().getKeyRing(), messageAsJson);
|
||||
message.setSellerSignature(sig);
|
||||
processModel.setPaymentReceivedMessage(message);
|
||||
trade.requestPersistence();
|
||||
|
@ -18,6 +18,7 @@
|
||||
package haveno.desktop.main.support.dispute.agent;
|
||||
|
||||
import haveno.common.UserThread;
|
||||
import haveno.common.util.Utilities;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.offer.OpenOfferManager;
|
||||
import haveno.core.offer.SignedOffer;
|
||||
@ -379,7 +380,7 @@ public class SignedOfferView extends ActivatableView<VBox, Void> {
|
||||
public void updateItem(final SignedOffer item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty)
|
||||
setText(item.getArbitratorSignature());
|
||||
setText(Utilities.bytesAsHexString(item.getArbitratorSignature()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ message OfferAvailabilityResponse {
|
||||
AvailabilityResult availability_result = 2;
|
||||
repeated int32 supported_capabilities = 3;
|
||||
string uid = 4;
|
||||
string maker_signature = 5;
|
||||
bytes maker_signature = 5;
|
||||
}
|
||||
|
||||
message RefreshOfferMessage {
|
||||
@ -233,7 +233,7 @@ message InitTradeRequest {
|
||||
string reserve_tx_hex = 17;
|
||||
string reserve_tx_key = 18;
|
||||
string payout_address = 19;
|
||||
string maker_signature = 20;
|
||||
bytes maker_signature = 20;
|
||||
}
|
||||
|
||||
message InitMultisigRequest {
|
||||
@ -261,7 +261,7 @@ message SignContractResponse {
|
||||
string uid = 2;
|
||||
int64 current_date = 3;
|
||||
string contract_as_json = 4;
|
||||
string contract_signature = 5;
|
||||
bytes contract_signature = 5;
|
||||
bytes encrypted_payment_account_payload = 6;
|
||||
}
|
||||
|
||||
@ -269,7 +269,7 @@ message DepositRequest {
|
||||
string trade_id = 1;
|
||||
string uid = 2;
|
||||
int64 current_date = 3;
|
||||
string contract_signature = 4;
|
||||
bytes contract_signature = 4;
|
||||
string deposit_tx_hex = 5;
|
||||
string deposit_tx_key = 6;
|
||||
bytes payment_account_key = 7;
|
||||
@ -636,7 +636,7 @@ message OfferPayload {
|
||||
int32 protocol_version = 34;
|
||||
|
||||
NodeAddress arbitrator_signer = 1001;
|
||||
string arbitrator_signature = 1002;
|
||||
bytes arbitrator_signature = 1002;
|
||||
repeated string reserve_tx_key_images = 1003;
|
||||
}
|
||||
|
||||
@ -696,8 +696,8 @@ message Dispute {
|
||||
string deposit_tx_id = 14;
|
||||
string payout_tx_id = 15;
|
||||
string contract_as_json = 16;
|
||||
string maker_contract_signature = 17;
|
||||
string taker_contract_signature = 18;
|
||||
bytes maker_contract_signature = 17;
|
||||
bytes taker_contract_signature = 18;
|
||||
PaymentAccountPayload maker_payment_account_payload = 19;
|
||||
PaymentAccountPayload taker_payment_account_payload = 20;
|
||||
PubKeyRing agent_pub_key_ring = 21;
|
||||
@ -1356,7 +1356,7 @@ message SignedOffer {
|
||||
string reserve_tx_hex = 7;
|
||||
repeated string reserve_tx_key_images = 8;
|
||||
uint64 reserve_tx_miner_fee = 9;
|
||||
string arbitrator_signature = 10;
|
||||
bytes arbitrator_signature = 10;
|
||||
}
|
||||
|
||||
message OpenOffer {
|
||||
@ -1531,7 +1531,7 @@ message ProcessModel {
|
||||
int64 funds_needed_for_trade = 7;
|
||||
string payment_sent_message_state = 8;
|
||||
bool deposits_confirmed_messages_delivered = 9;
|
||||
string maker_signature = 10;
|
||||
bytes maker_signature = 10;
|
||||
TradePeer maker = 11;
|
||||
TradePeer taker = 12;
|
||||
TradePeer arbitrator = 13;
|
||||
@ -1557,7 +1557,7 @@ message TradePeer {
|
||||
PaymentAccountPayload payment_account_payload = 9;
|
||||
string payout_address_string = 10;
|
||||
string contract_as_json = 11;
|
||||
string contract_signature = 12;
|
||||
bytes contract_signature = 12;
|
||||
bytes account_age_witness_nonce = 18;
|
||||
bytes account_age_witness_signature = 19;
|
||||
AccountAgeWitness account_age_witness = 20;
|
||||
|
Loading…
Reference in New Issue
Block a user