mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Remove PGP keys from the KeyRing
The PGP support was envisioned in the KeyRing but never fully implemented. This removes the (essentially) dead code. The protobuf message compatibility is implemented with `reserved`.
This commit is contained in:
parent
d4079cb161
commit
82e9672e91
@ -20,18 +20,12 @@ package bisq.common.crypto;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
|
||||
import java.security.KeyPair;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Slf4j
|
||||
@ -41,33 +35,18 @@ public final class KeyRing {
|
||||
private final KeyPair encryptionKeyPair;
|
||||
private final PubKeyRing pubKeyRing;
|
||||
|
||||
// We generate by default a PGP keypair but the user can set his own if he prefers.
|
||||
// Not impl. yet but prepared in data structure
|
||||
@Nullable
|
||||
@Setter
|
||||
// TODO remove Nullable once impl.
|
||||
private PGPKeyPair pgpKeyPair;
|
||||
|
||||
@Inject
|
||||
public KeyRing(KeyStorage keyStorage) {
|
||||
if (keyStorage.allKeyFilesExist()) {
|
||||
signatureKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_SIGNATURE);
|
||||
encryptionKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_ENCRYPTION);
|
||||
|
||||
// TODO not impl
|
||||
pgpKeyPair = keyStorage.loadPgpKeyPair(KeyStorage.KeyEntry.PGP);
|
||||
} else {
|
||||
// First time we create key pairs
|
||||
signatureKeyPair = Sig.generateKeyPair();
|
||||
encryptionKeyPair = Encryption.generateKeyPair();
|
||||
|
||||
// TODO not impl
|
||||
pgpKeyPair = PGP.generateKeyPair();
|
||||
keyStorage.saveKeyRing(this);
|
||||
}
|
||||
// TODO remove Nullable once impl.
|
||||
final PGPPublicKey pgpPublicKey = pgpKeyPair != null ? pgpKeyPair.getPublicKey() : null;
|
||||
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic(), pgpPublicKey);
|
||||
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic());
|
||||
}
|
||||
|
||||
// Don't print keys for security reasons
|
||||
|
@ -24,8 +24,6 @@ import com.google.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -54,8 +52,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
// TODO: use a password protection for key storage
|
||||
@Singleton
|
||||
public class KeyStorage {
|
||||
@ -65,9 +61,7 @@ public class KeyStorage {
|
||||
|
||||
public enum KeyEntry {
|
||||
MSG_SIGNATURE("sig", Sig.KEY_ALGO),
|
||||
MSG_ENCRYPTION("enc", Encryption.ASYM_KEY_ALGO),
|
||||
// TODO not impl
|
||||
PGP("pgp", null);
|
||||
MSG_ENCRYPTION("enc", Encryption.ASYM_KEY_ALGO);
|
||||
|
||||
private final String fileName;
|
||||
private final String algorithm;
|
||||
@ -111,14 +105,6 @@ public class KeyStorage {
|
||||
return new File(storageDir + "/" + keyEntry.getFileName() + ".key").exists();
|
||||
}
|
||||
|
||||
// TODO not impl
|
||||
@SuppressWarnings({"SameParameterValue", "SameReturnValue", "UnusedParameters"})
|
||||
@Nullable
|
||||
public PGPKeyPair loadPgpKeyPair(KeyEntry keyEntry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public KeyPair loadKeyPair(KeyEntry keyEntry) {
|
||||
FileUtil.rollingBackup(storageDir, keyEntry.getFileName() + ".key", 20);
|
||||
// long now = System.currentTimeMillis();
|
||||
|
@ -1,134 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.common.crypto;
|
||||
|
||||
import bisq.common.util.Hex;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import org.bouncycastle.bcpg.BCPGKey;
|
||||
import org.bouncycastle.bcpg.RSAPublicBCPGKey;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPUtil;
|
||||
import org.bouncycastle.openpgp.jcajce.JcaPGPPublicKeyRingCollection;
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@SuppressWarnings("UnusedAssignment")
|
||||
@Slf4j
|
||||
public class PGP {
|
||||
|
||||
// TODO not tested yet, remove Nullable once impl.
|
||||
// PEM encoding
|
||||
@Nullable
|
||||
public static PGPPublicKey getPubKeyFromPem(@Nullable String pem) {
|
||||
if (pem != null) {
|
||||
InputStream inputStream = new ByteArrayInputStream(pem.getBytes(Charsets.UTF_8));
|
||||
try {
|
||||
inputStream = PGPUtil.getDecoderStream(inputStream);
|
||||
try {
|
||||
JcaPGPPublicKeyRingCollection ringCollection = new JcaPGPPublicKeyRingCollection(inputStream);
|
||||
Iterator<PGPPublicKeyRing> keyRingsIterator = ringCollection.getKeyRings();
|
||||
while (keyRingsIterator.hasNext()) {
|
||||
PGPPublicKeyRing pgpPublicKeyRing = keyRingsIterator.next();
|
||||
Iterator<PGPPublicKey> pubKeysIterator = pgpPublicKeyRing.getPublicKeys();
|
||||
while (pubKeysIterator.hasNext()) {
|
||||
final PGPPublicKey pgpPublicKey = pubKeysIterator.next();
|
||||
if ((pgpPublicKey).isEncryptionKey()) {
|
||||
log.debug(pgpPublicKey.getClass().getName()
|
||||
+ " KeyID: " + Long.toHexString(pgpPublicKey.getKeyID())
|
||||
+ " type: " + pgpPublicKey.getAlgorithm()
|
||||
+ " fingerprint: " + Hex.encode(pgpPublicKey.getFingerprint()));
|
||||
|
||||
BCPGKey bcKey = pgpPublicKey.getPublicKeyPacket().getKey();
|
||||
log.debug(bcKey.getClass().getName());
|
||||
if (bcKey instanceof RSAPublicBCPGKey) {
|
||||
RSAPublicBCPGKey bcRSA = (RSAPublicBCPGKey) bcKey;
|
||||
RSAPublicKeySpec specRSA = new RSAPublicKeySpec(bcRSA.getModulus(), bcRSA.getPublicExponent());
|
||||
PublicKey jceKey = KeyFactory.getInstance("RSA").generatePublic(specRSA);
|
||||
// if you want to use the key in JCE, use jceKey
|
||||
// if you want to write "X.509" (SPKI) DER format to a file:
|
||||
//Files.write(new File(pubKeyAsString).toPath(), jceKey.getEncoded());
|
||||
// if you want to write in PEM, bouncycastle can do that
|
||||
// or you can just do base64 and add BEGIN/END lines
|
||||
// return pubKeyAsString; // assume only one key; if need to handle multiple keys
|
||||
// or select other than the first, specify more clearly
|
||||
}
|
||||
|
||||
return pgpPublicKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (PGPException | InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
log.error("Error creating publicKey from pem. pem={}, error={}", pem, e);
|
||||
e.printStackTrace();
|
||||
throw new KeyConversionException(e);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Error creating publicKey from pem. pem={}, error={}", pem, e);
|
||||
e.printStackTrace();
|
||||
throw new KeyConversionException(e);
|
||||
} finally {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.warn("Error creating publicKey from pem. pem=null");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO not impl, remove Nullable once impl.
|
||||
// PEM encoding
|
||||
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
|
||||
@NotNull
|
||||
public static String getPEMFromPubKey(@Nullable PGPPublicKey pgpPubKey) {
|
||||
// We use empty string as we must not have null in proto file
|
||||
return "";
|
||||
}
|
||||
|
||||
// TODO not impl, remove Nullable once impl.
|
||||
@SuppressWarnings("SameReturnValue")
|
||||
@Nullable
|
||||
public static PGPKeyPair generateKeyPair() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -25,16 +25,12 @@ import com.google.protobuf.ByteString;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Same as KeyRing but with public keys only.
|
||||
* Used to send public keys over the wire to other peer.
|
||||
@ -45,22 +41,15 @@ import javax.annotation.Nullable;
|
||||
public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJson {
|
||||
private final byte[] signaturePubKeyBytes;
|
||||
private final byte[] encryptionPubKeyBytes;
|
||||
@Nullable
|
||||
private final String pgpPubKeyAsPem;
|
||||
|
||||
private transient PublicKey signaturePubKey;
|
||||
private transient PublicKey encryptionPubKey;
|
||||
@Nullable
|
||||
private transient PGPPublicKey pgpPubKey;
|
||||
|
||||
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey, @Nullable PGPPublicKey pgpPubKey) {
|
||||
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey) {
|
||||
this.signaturePubKeyBytes = Sig.getPublicKeyBytes(signaturePubKey);
|
||||
this.encryptionPubKeyBytes = Encryption.getPublicKeyBytes(encryptionPubKey);
|
||||
this.pgpPubKeyAsPem = PGP.getPEMFromPubKey(pgpPubKey);
|
||||
|
||||
this.signaturePubKey = signaturePubKey;
|
||||
this.encryptionPubKey = encryptionPubKey;
|
||||
this.pgpPubKey = pgpPubKey;
|
||||
}
|
||||
|
||||
|
||||
@ -69,15 +58,11 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@VisibleForTesting
|
||||
public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes, @Nullable String pgpPubKeyAsPem) {
|
||||
public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes) {
|
||||
this.signaturePubKeyBytes = signaturePubKeyBytes;
|
||||
this.encryptionPubKeyBytes = encryptionPubKeyBytes;
|
||||
this.pgpPubKeyAsPem = pgpPubKeyAsPem;
|
||||
|
||||
signaturePubKey = Sig.getPublicKeyFromBytes(signaturePubKeyBytes);
|
||||
encryptionPubKey = Encryption.getPublicKeyFromBytes(encryptionPubKeyBytes);
|
||||
if (pgpPubKeyAsPem != null)
|
||||
pgpPubKey = PGP.getPubKeyFromPem(pgpPubKeyAsPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,14 +70,13 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
|
||||
return protobuf.PubKeyRing.newBuilder()
|
||||
.setSignaturePubKeyBytes(ByteString.copyFrom(signaturePubKeyBytes))
|
||||
.setEncryptionPubKeyBytes(ByteString.copyFrom(encryptionPubKeyBytes))
|
||||
.setPgpPubKeyAsPem(pgpPubKeyAsPem)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static PubKeyRing fromProto(protobuf.PubKeyRing proto) {
|
||||
return new PubKeyRing(proto.getSignaturePubKeyBytes().toByteArray(),
|
||||
proto.getEncryptionPubKeyBytes().toByteArray(),
|
||||
proto.getPgpPubKeyAsPem());
|
||||
return new PubKeyRing(
|
||||
proto.getSignaturePubKeyBytes().toByteArray(),
|
||||
proto.getEncryptionPubKeyBytes().toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,7 +84,6 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
|
||||
return "PubKeyRing{" +
|
||||
"signaturePubKeyHex=" + Utilities.bytesAsHexString(signaturePubKeyBytes) +
|
||||
", encryptionPubKeyHex=" + Utilities.bytesAsHexString(encryptionPubKeyBytes) +
|
||||
", pgpPubKeyAsString=" + pgpPubKeyAsPem +
|
||||
'}';
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ message Peer {
|
||||
message PubKeyRing {
|
||||
bytes signature_pub_key_bytes = 1;
|
||||
bytes encryption_pub_key_bytes = 2;
|
||||
string pgp_pub_key_as_pem = 3;
|
||||
reserved 3; // WAS: string pgp_pub_key_as_pem = 3;
|
||||
}
|
||||
|
||||
message SealedAndSigned {
|
||||
|
@ -44,7 +44,7 @@ public class ArbitratorTest {
|
||||
return new Arbitrator(new NodeAddress("host", 1000),
|
||||
getBytes(100),
|
||||
"btcaddress",
|
||||
new PubKeyRing(getBytes(100), getBytes(100), "key"),
|
||||
new PubKeyRing(getBytes(100), getBytes(100)),
|
||||
Lists.newArrayList(),
|
||||
new Date().getTime(),
|
||||
getBytes(100),
|
||||
@ -56,4 +56,3 @@ public class ArbitratorTest {
|
||||
return RandomUtils.nextBytes(count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class MediatorTest {
|
||||
|
||||
public static Mediator getMediatorMock() {
|
||||
return new Mediator(new NodeAddress("host", 1000),
|
||||
new PubKeyRing(getBytes(100), getBytes(100), "key"),
|
||||
new PubKeyRing(getBytes(100), getBytes(100)),
|
||||
Lists.newArrayList(),
|
||||
new Date().getTime(),
|
||||
getBytes(100),
|
||||
@ -51,6 +51,4 @@ public class MediatorTest {
|
||||
"info",
|
||||
null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user