Fix PubKeyRing

This commit is contained in:
Manfred Karrer 2017-05-11 19:22:26 +02:00
parent a7b7cbbbca
commit 46bbecff3c
3 changed files with 109 additions and 97 deletions

View File

@ -18,5 +18,5 @@ public class DevEnv {
// If set to true we ignore several UI behavior like confirmation popups as well dummy accounts are created and
// offers are filled with default values. Intended to make dev testing faster.
@SuppressWarnings("PointlessBooleanExpression")
public static final boolean DEV_MODE = STRESS_TEST_MODE || false;
public static final boolean DEV_MODE = STRESS_TEST_MODE || true;
}

View File

@ -19,10 +19,8 @@ package io.bisq.common.crypto;
import com.google.protobuf.ByteString;
import io.bisq.common.Payload;
import io.bisq.common.app.Version;
import io.bisq.generated.protobuffer.PB;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
@ -31,7 +29,6 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@ -46,70 +43,36 @@ import java.security.spec.X509EncodedKeySpec;
@Slf4j
@EqualsAndHashCode
public final class PubKeyRing implements Payload {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
// Payload
private final byte[] signaturePubKeyBytes;
private final byte[] encryptionPubKeyBytes;
private String pgpPubKeyAsPem;
// Domain
@Getter
transient private PublicKey signaturePubKey;
@Getter
transient private PublicKey encryptionPubKey;
@Getter
@Nullable
// TODO remove Nullable once impl.
transient private PGPPublicKey pgpPubKey;
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey, @Nullable PGPPublicKey pgpPubKey) {
this(new X509EncodedKeySpec(signaturePubKey.getEncoded()).getEncoded(),
new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded(),
PGP.getPEMFromPubKey(pgpPubKey));
this.signaturePubKey = signaturePubKey;
this.encryptionPubKey = encryptionPubKey;
this.pgpPubKey = pgpPubKey;
this.signaturePubKeyBytes = new X509EncodedKeySpec(signaturePubKey.getEncoded()).getEncoded();
this.encryptionPubKeyBytes = new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded();
//TODO not impl yet
pgpPubKeyAsPem = PGP.getPEMFromPubKey(pgpPubKey);
}
///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////
public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes, @NotNull String pgpPubKeyAsPem) {
this.signaturePubKeyBytes = signaturePubKeyBytes;
this.encryptionPubKeyBytes = encryptionPubKeyBytes;
this.pgpPubKeyAsPem = pgpPubKeyAsPem;
init();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
in.defaultReadObject();
init();
} catch (Throwable t) {
log.warn("Cannot be deserialized." + t.getMessage());
}
}
private void init() {
try {
signaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO, "BC")
.generatePublic(new X509EncodedKeySpec(signaturePubKeyBytes));
encryptionPubKey = KeyFactory.getInstance(Encryption.ASYM_KEY_ALGO, "BC")
.generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes));
try {
this.pgpPubKey = PGP.getPubKeyFromPEM(pgpPubKeyAsPem);
} catch (IOException | PGPException e) {
log.error(e.toString());
e.printStackTrace();
throw new RuntimeException(e);
}
} catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchProviderException e) {
e.printStackTrace();
log.error(e.getMessage() + toString());
}
}
@Override
@ -127,6 +90,50 @@ public final class PubKeyRing implements Payload {
pubKeyRing.getPgpPubKeyAsPem());
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public PublicKey getSignaturePubKey() {
if (signaturePubKey == null) {
try {
signaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO, "BC")
.generatePublic(new X509EncodedKeySpec(signaturePubKeyBytes));
} catch (InvalidKeySpecException | NoSuchProviderException | NoSuchAlgorithmException e) {
log.error("Key cannot be created. error={}, signaturePubKeyBytes.length={}", e.getMessage(), signaturePubKeyBytes.length);
e.printStackTrace();
throw new RuntimeException(e);
}
}
return signaturePubKey;
}
public PublicKey getEncryptionPubKey() {
if (encryptionPubKey == null) {
try {
encryptionPubKey = KeyFactory.getInstance(Encryption.ASYM_KEY_ALGO, "BC").generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes));
} catch (InvalidKeySpecException | NoSuchProviderException | NoSuchAlgorithmException e) {
log.error("Key cannot be created. error={}, encryptionPubKeyBytes.length={}", e.getMessage(), encryptionPubKeyBytes.length);
e.printStackTrace();
throw new RuntimeException(e);
}
}
return encryptionPubKey;
}
public PGPPublicKey getPgpPubKey() {
if (pgpPubKey == null)
try {
pgpPubKey = PGP.getPubKeyFromPEM(pgpPubKeyAsPem);
} catch (NoSuchAlgorithmException | PGPException | IOException | InvalidKeySpecException e) {
log.error("Key cannot be created. error={}, pgpPubKeyAsPem={}", e.getMessage(), pgpPubKeyAsPem);
e.printStackTrace();
//throw new RuntimeException(e);
}
return pgpPubKey;
}
// Hex
@Override
public String toString() {

View File

@ -1,6 +1,5 @@
package io.bisq.core.trade.statistics;
import io.bisq.common.app.Version;
import io.bisq.common.crypto.PubKeyRing;
import io.bisq.common.locale.CurrencyUtil;
import io.bisq.common.monetary.Altcoin;
@ -32,8 +31,6 @@ import java.util.concurrent.TimeUnit;
@Slf4j
@Immutable
public final class TradeStatistics implements LazyProcessedStoragePayload, /*CapabilityRequiringPayload,*/ PersistedStoragePayload {
@JsonExclude
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
@JsonExclude
public static final long TTL = TimeUnit.DAYS.toMillis(30);
@ -87,8 +84,12 @@ public final class TradeStatistics implements LazyProcessedStoragePayload, /*Cap
null);
}
// Called from PB
public TradeStatistics(OfferPayload.Direction direction,
///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////
private TradeStatistics(OfferPayload.Direction direction,
String baseCurrency,
String counterCurrency,
String offerPaymentMethod,
@ -122,6 +123,54 @@ public final class TradeStatistics implements LazyProcessedStoragePayload, /*Cap
this.extraDataMap = extraDataMap;
}
@Override
public PB.StoragePayload toProto() {
final PB.TradeStatistics.Builder builder = PB.TradeStatistics.newBuilder()
.setBaseCurrency(baseCurrency)
.setCounterCurrency(counterCurrency)
.setDirection(PB.OfferPayload.Direction.valueOf(direction.name()))
.setTradePrice(tradePrice)
.setTradeAmount(tradeAmount)
.setTradeDate(tradeDate)
.setPaymentMethodId(paymentMethodId)
.setOfferDate(offerDate)
.setUseMarketBasedPrice(useMarketBasedPrice)
.setMarketPriceMargin(marketPriceMargin)
.setOfferAmount(offerAmount)
.setOfferMinAmount(offerMinAmount)
.setOfferId(offerId)
.setDepositTxId(depositTxId)
.setPubKeyRing(pubKeyRing.toProto());
Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraDataMap);
return PB.StoragePayload.newBuilder().setTradeStatistics(builder).build();
}
public static TradeStatistics fromProto(PB.TradeStatistics tradeStatistics) {
return new TradeStatistics(
OfferPayload.Direction.fromProto(tradeStatistics.getDirection()),
tradeStatistics.getBaseCurrency(),
tradeStatistics.getCounterCurrency(),
tradeStatistics.getPaymentMethodId(),
tradeStatistics.getOfferDate(),
tradeStatistics.getUseMarketBasedPrice(),
tradeStatistics.getMarketPriceMargin(),
tradeStatistics.getOfferAmount(),
tradeStatistics.getOfferMinAmount(),
tradeStatistics.getOfferId(),
tradeStatistics.getTradePrice(),
tradeStatistics.getTradeAmount(),
tradeStatistics.getTradeDate(),
tradeStatistics.getDepositTxId(),
PubKeyRing.fromProto(tradeStatistics.getPubKeyRing()),
CollectionUtils.isEmpty(tradeStatistics.getExtraDataMapMap()) ?
null : tradeStatistics.getExtraDataMapMap());
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@Override
public long getTTL() {
return TTL;
@ -163,50 +212,6 @@ public final class TradeStatistics implements LazyProcessedStoragePayload, /*Cap
return new Volume(new ExchangeRate((Fiat) getTradePrice().getMonetary()).coinToFiat(getTradeAmount()));
}
@Override
public PB.StoragePayload toProto() {
final PB.TradeStatistics.Builder builder = PB.TradeStatistics.newBuilder()
.setBaseCurrency(baseCurrency)
.setCounterCurrency(counterCurrency)
.setDirection(PB.OfferPayload.Direction.valueOf(direction.name()))
.setTradePrice(tradePrice)
.setTradeAmount(tradeAmount)
.setTradeDate(tradeDate)
.setPaymentMethodId(paymentMethodId)
.setOfferDate(offerDate)
.setUseMarketBasedPrice(useMarketBasedPrice)
.setMarketPriceMargin(marketPriceMargin)
.setOfferAmount(offerAmount)
.setOfferMinAmount(offerMinAmount)
.setOfferId(offerId)
.setDepositTxId(depositTxId)
.setPubKeyRing(pubKeyRing.toProto());
Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraDataMap);
return PB.StoragePayload.newBuilder().setTradeStatistics(builder).build();
}
public static TradeStatistics fromProto(PB.TradeStatistics tradeStatistics) {
return new TradeStatistics(OfferPayload.Direction.fromProto(tradeStatistics.getDirection()),
tradeStatistics.getBaseCurrency(),
tradeStatistics.getCounterCurrency(),
tradeStatistics.getPaymentMethodId(),
tradeStatistics.getOfferDate(),
tradeStatistics.getUseMarketBasedPrice(),
tradeStatistics.getMarketPriceMargin(),
tradeStatistics.getOfferAmount(),
tradeStatistics.getOfferMinAmount(),
tradeStatistics.getOfferId(),
tradeStatistics.getTradePrice(),
tradeStatistics.getTradeAmount(),
tradeStatistics.getTradeDate(),
tradeStatistics.getDepositTxId(),
new PubKeyRing(tradeStatistics.getPubKeyRing().getSignaturePubKeyBytes().toByteArray(),
tradeStatistics.getPubKeyRing().getEncryptionPubKeyBytes().toByteArray(),
tradeStatistics.getPubKeyRing().getPgpPubKeyAsPem()),
CollectionUtils.isEmpty(tradeStatistics.getExtraDataMapMap()) ?
null : tradeStatistics.getExtraDataMapMap());
}
// We don't include the pubKeyRing as both traders might publish it if the maker uses an old
// version and update later (taker publishes first, then later maker)
// We also don't include the trade date as that is set locally and different for maker and taker