Skip to content

Commit

Permalink
support new key structure for public key rings, fixes #33, second bug
Browse files Browse the repository at this point in the history
  • Loading branch information
abika committed Jul 14, 2015
1 parent 64d1614 commit 18e0a14
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 14 deletions.
8 changes: 7 additions & 1 deletion src/main/java/org/kontalk/crypto/Coder.java
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,13 @@ private static DecryptionResult decryptAndVerify(InputStream encryptedStream,
result.errors.add(Error.INVALID_SIGNATURE_DATA);
} else {
ops = signatureList.get(0);
ops.init(new BcPGPContentVerifierBuilderProvider(), senderSigningKey);
try {
ops.init(new BcPGPContentVerifierBuilderProvider(), senderSigningKey);
} catch (ClassCastException e) {
LOGGER.warning("legacy signature not supported");
result.errors.add(Error.INVALID_SIGNATURE_DATA);
ops = null;
}
}
object = pgpFact.nextObject(); // nullable
} else {
Expand Down
26 changes: 21 additions & 5 deletions src/main/java/org/kontalk/crypto/PGPUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyFlags;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
Expand Down Expand Up @@ -116,25 +117,35 @@ public static Optional<PGPCoderKey> readPublicKey(byte[] publicKeyring) {
}
PGPPublicKey encryptKey = null;
PGPPublicKey signKey = null;
// for legacy keyring
PGPPublicKey authKey = null;
String uid = null;
String fp = null;
PGPPublicKeyRing keyRing = (PGPPublicKeyRing) keyRingIter.next();
Iterator<?> keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext()) {
PGPPublicKey key = (PGPPublicKey) keyIter.next();
if (key.isMasterKey()) {
signKey = key;
authKey = key;
fp = EncodingUtils.bytesToHex(key.getFingerprint());
Iterator<?> uidIt = key.getUserIDs();
if (uidIt.hasNext())
uid = (String) uidIt.next();
}
if (!key.isMasterKey() && key.isEncryptionKey()) {
} else if (isSigningKey(key)) {
signKey = key;
} else if (key.isEncryptionKey()) {
encryptKey = key;
}
}

// legacy: auth key is actually signing key
if (signKey == null && authKey != null) {
LOGGER.info("loading legacy public key, uid: "+uid);
signKey = authKey;
}

if (encryptKey == null || signKey == null || uid == null || fp == null) {
LOGGER.warning("can't find public keys in key ring");
LOGGER.warning("can't find public keys in key ring, uid: "+uid);
return Optional.empty();
}
return Optional.of(new PGPCoderKey(encryptKey, signKey, uid, fp));
Expand All @@ -154,7 +165,7 @@ static PrivateKey convertPrivateKey(PGPPrivateKey key) throws PGPException {
return sKeyConverter.getPrivateKey(key);
}

static int getKeyFlags(PGPPublicKey key) {
private static int getKeyFlags(PGPPublicKey key) {
@SuppressWarnings("unchecked")
Iterator<PGPSignature> sigs = key.getSignatures();
while (sigs.hasNext()) {
Expand All @@ -167,6 +178,11 @@ static int getKeyFlags(PGPPublicKey key) {
return 0;
}

static boolean isSigningKey(PGPPublicKey key) {
int keyFlags = PGPUtils.getKeyFlags(key);
return (keyFlags & PGPKeyFlags.CAN_SIGN) == PGPKeyFlags.CAN_SIGN;
}

static PGPKeyPair decrypt(PGPSecretKey secretKey, PBESecretKeyDecryptor dec) throws KonException {
try {
return new PGPKeyPair(secretKey.getPublicKey(), secretKey.extractPrivateKey(dec));
Expand Down
12 changes: 4 additions & 8 deletions src/main/java/org/kontalk/crypto/PersonalKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import java.util.Iterator;
import java.util.logging.Logger;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyFlags;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
Expand Down Expand Up @@ -120,14 +119,11 @@ public static PersonalKey load(byte[] privateKeyData,
if (key.isMasterKey()) {
// master key: authentication / legacy: signing
authKey = key;
}
else {
} else if (PGPUtils.isSigningKey(key.getPublicKey())) {
// sub keys: encryption and signing / legacy: only encryption
int keyFlags = PGPUtils.getKeyFlags(key.getPublicKey());
if ((keyFlags & PGPKeyFlags.CAN_SIGN) == PGPKeyFlags.CAN_SIGN)
signKey = key;
else
encrKey = key;
signKey = key;
} else if (key.getPublicKey().isEncryptionKey()) {
encrKey = key;
}
}
// legacy: auth key is actually signing key
Expand Down

0 comments on commit 18e0a14

Please sign in to comment.