8000 High-Level API #0: Preparations for high-level OpenPGP Key Generator API by vanitasvitae · Pull Request #1926 · bcgit/bc-java · GitHub
[go: up one dir, main page]

Skip to content

High-Level API #0: Preparations for high-level OpenPGP Key Generator API #1926

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 56 additions & 3 deletions pg/src/main/java/org/bouncycastle/bcpg/KeyIdentifier.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.bouncycastle.bcpg;

import java.util.Iterator;
import java.util.List;

import org.bouncycastle.util.Arrays;
Expand All @@ -17,6 +16,11 @@ public class KeyIdentifier
private final byte[] fingerprint;
private final long keyId;

public KeyIdentifier(String hexEncoded)
{
this(Hex.decode(hexEncoded));
}

/**
* Create a new {@link KeyIdentifier} based on a keys fingerprint.
* For fingerprints matching the format of a v4, v5 or v6 key, the constructor will
Expand Down Expand Up @@ -157,6 +161,26 @@ public boolean matches(KeyIdentifier other)
}
}

public static boolean matches(List<KeyIdentifier> identifiers, KeyIdentifier identifier, boolean explicit)
{
for (KeyIdentifier candidate : identifiers)
{
if (!explicit && candidate.isWildcard())
{
return true;
}

if (candidate.getFingerprint() != null &&
Arrays.constantTimeAreEqual(candidate.getFingerprint(), identifier.getFingerprint()))
{
return true;
}

return candidate.getKeyId() == identifier.getKeyId();
}
return false;
}

/**
* Return true, if this {@link KeyIdentifier} is present in the given list of {@link KeyIdentifier} .
* This will return true if a fingerprint matches, or if a key-id matches,
Expand All @@ -167,9 +191,9 @@ public boolean matches(KeyIdentifier other)
*/
public boolean isPresentIn(List<KeyIdentifier> others)
{
for (Iterator it = others.iterator(); it.hasNext();)
for (KeyIdentifier other : others)
{
if (this.matches((KeyIdentifier)it.next()))
if (this.matches(other))
{
return true;
}
Expand All @@ -178,6 +202,35 @@ public boolean isPresentIn(List<KeyIdentifier> others)
return false;
}

@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (this == obj)
{
return true;
}
if (!(obj instanceof KeyIdentifier))
{
return false;
}
KeyIdentifier other = (KeyIdentifier) obj;
if (getFingerprint() != null && other.getFingerprint() != null)
{
return Arrays.constantTimeAreEqual(getFingerprint(), other.getFingerprint());
}
return getKeyId() == other.getKeyId();
}

@Override
public int hashCode()
{
return (int) getKeyId();
}

public String toString()
{
if (isWildcard())
Expand Down
45 changes: 22 additions & 23 deletions pg/src/main/java/org/bouncycastle/bcpg/PublicKeyUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,26 @@ public static boolean isSigningAlgorithm(int publicKeyAlgorithm)
}
}

// /**
// * Return true, if the public key algorithm that corresponds to the given ID is capable of encryption.
// *
// * @param publicKeyAlgorithm public key algorithm id
// * @return true if algorithm can encrypt
// */
// public static boolean isEncryptionAlgorithm(int publicKeyAlgorithm)
// {
// switch (publicKeyAlgorithm)
// {
// case PublicKeyAlgorithmTags.RSA_GENERAL:
// case PublicKeyAlgorithmTags.RSA_ENCRYPT:
// case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT:
// case PublicKeyAlgorithmTags.ECDH:
// case PublicKeyAlgorithmTags.ELGAMAL_GENERAL:
// case PublicKeyAlgorithmTags.DIFFIE_HELLMAN:
// case PublicKeyAlgorithmTags.X25519:
// case PublicKeyAlgorithmTags.X448:
// return true;
// default:
// return false;
// }
// }
/**
* Return true, if the public key algorithm that corresponds to the given ID is capable of encryption.
* @param publicKeyAlgorithm public key algorithm id
* @return true if algorithm can encrypt
*/
public static boolean isEncryptionAlgorithm(int publicKeyAlgorithm)
{
switch (publicKeyAlgorithm)
{
case PublicKeyAlgorithmTags.RSA_GENERAL:
case PublicKeyAlgorithmTags.RSA_ENCRYPT:
case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT:
case PublicKeyAlgorithmTags.ECDH:
case PublicKeyAlgorithmTags.ELGAMAL_GENERAL:
case PublicKeyAlgorithmTags.DIFFIE_HELLMAN:
case PublicKeyAlgorithmTags.X25519:
case PublicKeyAlgorithmTags.X448:
return true;
default:
return false;
}
}
}
685C
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public class PGPEncryptedDataGenerator
// If true, force generation of a session key, even if we only have a single password-based encryption method
// and could therefore use the S2K output as session key directly.
private boolean forceSessionKey = true;
private SessionKeyExtractionCallback sessionKeyExtractionCallback = null;

/**
* Base constructor.
Expand Down Expand Up @@ -178,6 +179,11 @@ private byte[] createSessionInfo(
return sessionInfo;
}

public void setSessionKeyExtractionCallback(SessionKeyExtractionCallback callback)
{
this.sessionKeyExtractionCallback = callback;
}

/**
* Create an OutputStream based on the configured methods.
* <p>
Expand Down Expand Up @@ -252,6 +258,11 @@ else if (directS2K)
messageKey = sessionKey;
}

if (sessionKeyExtractionCallback != null)
{
sessionKeyExtractionCallback.extractSessionKey(new PGPSessionKey(defAlgorithm, sessionKey));
}

PGPDataEncryptor dataEncryptor = dataEncryptorBuilder.build(messageKey);
digestCalc = dataEncryptor.getIntegrityCalculator();

Expand Down Expand Up @@ -579,4 +590,9 @@ public void close()
this.finish();
}
}

public interface SessionKeyExtractionCallback
{
void extractSessionKey(PGPSessionKey sessionKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ public PGPEncryptedData get(
return (PGPEncryptedData)methods.get(index);
}

public InputStreamPacket getEncryptedData()
{
return data;
}

/**
* Gets the number of encryption methods in this list.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public PGPKeyRingGenerator(
this.keySignerBuilder = keySignerBuilder;

PGPSignature certSig = (PGPSignature)originalSecretRing.getPublicKey().getSignatures().next();
List hashedVec = new ArrayList();
List<SignatureSubpacket> hashedVec = new ArrayList<SignatureSubpacket>();
PGPSignatureSubpacketVector existing = certSig.getHashedSubPackets();
for (int i = 0; i != existing.size(); i++)
{
Expand All @@ -164,7 +164,7 @@ public PGPKeyRingGenerator(
hashedVec.add(existing.packets[i]);
}
this.hashedPcks = new PGPSignatureSubpacketVector(
(SignatureSubpacket[])hashedVec.toArray(new SignatureSubpacket[hashedVec.size()]));
hashedVec.toArray(new SignatureSubpacket[0]));
this.unhashedPcks = certSig.getUnhashedSubPackets();

keys.addAll(originalSecretRing.keys);
Expand Down Expand Up @@ -323,9 +323,7 @@ public void addSubKey(
}

sGen.setUnhashedSubpackets(unhashedPcks);

List subSigs = new ArrayList();

List<PGPSignature> subSigs = new ArrayList<PGPSignature>();
subSigs.add(sGen.generateCertification(primaryKey.getPublicKey(), keyPair.getPublicKey()));

// replace the public key packet structure with a public subkey one.
Expand Down Expand Up @@ -362,14 +360,14 @@ public PGPSecretKeyRing generateSecretKeyRing()
*/
public PGPPublicKeyRing generatePublicKeyRing()
{
Iterator it = keys.iterator();
List pubKeys = new ArrayList();
Iterator<PGPSecretKey> it = keys.iterator();
List<PGPPublicKey> pubKeys = new ArrayList<PGPPublicKey>();

pubKeys.add(((PGPSecretKey)it.next()).getPublicKey());
pubKeys.add((it.next()).getPublicKey());

while (it.hasNext())
{
pubKeys.add(((PGPSecretKey)it.next()).getPublicKey());
pubKeys.add((it.next()).getPublicKey());
}

return new PGPPublicKeyRing(pubKeys);
Expand Down
33 changes: 33 additions & 0 deletions pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.bouncycastle.bcpg.TrustPacket;
import org.bouncycastle.bcpg.sig.IssuerFingerprint;
import org.bouncycastle.bcpg.sig.IssuerKeyID;
import org.bouncycastle.bcpg.sig.RevocationReason;
import org.bouncycastle.bcpg.sig.RevocationReasonTags;
import org.bouncycastle.math.ec.rfc8032.Ed25519;
import org.bouncycastle.math.ec.rfc8032.Ed448;
import org.bouncycastle.openpgp.operator.PGPContentVerifier;
Expand Down Expand Up @@ -905,6 +907,37 @@ public static boolean isCertification(int signatureType)
|| PGPSignature.POSITIVE_CERTIFICATION == signatureType;
}

public static boolean isRevocation(int signatureType)
{
return PGPSignature.KEY_REVOCATION == signatureType
|| PGPSignature.CERTIFICATION_REVOCATION == signatureType
|| PGPSignature.SUBKEY_REVOCATION == signatureType;
}

public boolean isHardRevocation()
{
if (!isRevocation(getSignatureType()))
{
return false; // no revocation
}

if (!hasSubpackets())
{
return true; // consider missing subpackets (and therefore missing reason) as hard revocation
}

// only consider reasons from the hashed packet area
RevocationReason reason = getHashedSubPackets() != null ?
getHashedSubPackets().getRevocationReason() : null;
if (reason == null)
{
return true; // missing reason packet is hard
}

return reason.getRevocationReason() == RevocationReasonTags.NO_REASON // No reason is hard
|| reason.getRevocationReason() == RevocationReasonTags.KEY_COMPROMISED; // key compromise is hard
}

/**
* Return true, if the cryptographic signature encoding of the two signatures match.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -649,9 +649,9 @@ public boolean removePacketsOfType(int subpacketType)
public boolean hasSubpacket(
int type)
{
for (int i = 0; i != packets.size(); i++)
for (SignatureSubpacket packet : packets)
{
if (((SignatureSubpacket)packets.get(i)).getType() == type)
if (packet.getType() == type)
{
return true;
}
Expand All @@ -670,17 +670,17 @@ public boolean hasSubpacket(
public SignatureSubpacket[] getSubpackets(
int type)
{
List list = new ArrayList();
List<SignatureSubpacket> list = new ArrayList<>();

for (int i = 0; i != packets.size(); i++)
for (SignatureSubpacket packet : packets)
{
if (((SignatureSubpacket)packets.get(i)).getType() == type)
if (packet.getType() == type)
{
list.add(packets.get(i));
list.add(packet);
}
}

return (SignatureSubpacket[])list.toArray(new SignatureSubpacket[]{});
return list.toArray(new SignatureSubpacket[0]);
}

public PGPSignatureSubpacketVector generate()
Expand All @@ -691,9 +691,9 @@ public PGPSignatureSubpacketVector generate()

private boolean contains(int type)
{
for (int i = 0; i < packets.size(); ++i)
for (SignatureSubpacket packet : packets)
{
if (((SignatureSubpacket)packets.get(i)).getType() == type)
if (packet.getType() == type)
{
return true;
}
Expand Down
Loading
0