mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-26 21:07:58 +01:00
Annotate fromId(code) methods with Nullable and add Nonnull requireFromId(code) methods
This commit is contained in:
parent
16b0d0730e
commit
e8b03834cb
24 changed files with 278 additions and 42 deletions
|
@ -5,10 +5,14 @@
|
|||
package org.pgpainless.algorithm;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Enumeration of possible compression algorithms.
|
||||
*
|
||||
|
@ -37,10 +41,28 @@ public enum CompressionAlgorithm {
|
|||
* @param id id
|
||||
* @return compression algorithm
|
||||
*/
|
||||
@Nullable
|
||||
public static CompressionAlgorithm fromId(int id) {
|
||||
return MAP.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link CompressionAlgorithm} value that corresponds to the provided numerical id.
|
||||
* If an invalid id is provided, thrown an {@link NoSuchElementException}.
|
||||
*
|
||||
* @param id id
|
||||
* @return compression algorithm
|
||||
* @throws NoSuchElementException in case of an unmapped id
|
||||
*/
|
||||
@Nonnull
|
||||
public static CompressionAlgorithm requireFromId(int id) {
|
||||
CompressionAlgorithm algorithm = fromId(id);
|
||||
if (algorithm == null) {
|
||||
throw new NoSuchElementException("No CompressionAlgorithm found for id " + id);
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
private final int algorithmId;
|
||||
|
||||
CompressionAlgorithm(int id) {
|
||||
|
|
|
@ -7,10 +7,14 @@ package org.pgpainless.algorithm;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bouncycastle.bcpg.sig.Features;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An enumeration of features that may be set in the {@link Features} subpacket.
|
||||
*
|
||||
|
@ -60,16 +64,46 @@ public enum Feature {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link Feature} encoded by the given id.
|
||||
* If the id does not match any known features, return null.
|
||||
*
|
||||
* @param id feature id
|
||||
* @return feature
|
||||
*/
|
||||
@Nullable
|
||||
public static Feature fromId(byte id) {
|
||||
return MAP.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link Feature} encoded by the given id.
|
||||
* If the id does not match any known features, throw an {@link NoSuchElementException}.
|
||||
*
|
||||
* @param id feature id
|
||||
* @return feature
|
||||
* @throws NoSuchElementException if an unmatched feature id is encountered
|
||||
*/
|
||||
@Nonnull
|
||||
public static Feature requireFromId(byte id) {
|
||||
Feature feature = fromId(id);
|
||||
if (feature == null) {
|
||||
throw new NoSuchElementException("Unknown feature id encountered: " + id);
|
||||
}
|
||||
return feature;
|
||||
}
|
||||
|
||||
private final byte featureId;
|
||||
|
||||
Feature(byte featureId) {
|
||||
this.featureId = featureId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the feature.
|
||||
*
|
||||
* @return feature id
|
||||
*/
|
||||
public byte getFeatureId() {
|
||||
return featureId;
|
||||
}
|
||||
|
@ -80,6 +114,7 @@ public enum Feature {
|
|||
* @param bitmask bitmask
|
||||
* @return list of key flags encoded by the bitmask
|
||||
*/
|
||||
@Nonnull
|
||||
public static List<Feature> fromBitmask(int bitmask) {
|
||||
List<Feature> features = new ArrayList<>();
|
||||
for (Feature f : Feature.values()) {
|
||||
|
|
|
@ -6,9 +6,13 @@ package org.pgpainless.algorithm;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.bouncycastle.bcpg.HashAlgorithmTags;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An enumeration of different hashing algorithms.
|
||||
*
|
||||
|
@ -42,10 +46,28 @@ public enum HashAlgorithm {
|
|||
* @param id numeric id
|
||||
* @return enum value
|
||||
*/
|
||||
@Nullable
|
||||
public static HashAlgorithm fromId(int id) {
|
||||
return ID_MAP.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link HashAlgorithm} value that corresponds to the provided algorithm id.
|
||||
* If an invalid algorithm id was provided, throw a {@link NoSuchElementException}.
|
||||
*
|
||||
* @param id algorithm id
|
||||
* @return enum value
|
||||
* @throws NoSuchElementException in case of an unknown algorithm id
|
||||
*/
|
||||
@Nonnull
|
||||
public static HashAlgorithm requireFromId(int id) {
|
||||
HashAlgorithm algorithm = fromId(id);
|
||||
if (algorithm == null) {
|
||||
throw new NoSuchElementException("No HashAlgorithm found for id " + id);
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link HashAlgorithm} value that corresponds to the provided name.
|
||||
* If an invalid algorithm name was provided, null is returned.
|
||||
|
@ -56,6 +78,7 @@ public enum HashAlgorithm {
|
|||
* @param name text name
|
||||
* @return enum value
|
||||
*/
|
||||
@Nullable
|
||||
public static HashAlgorithm fromName(String name) {
|
||||
return NAME_MAP.get(name);
|
||||
}
|
||||
|
|
|
@ -5,10 +5,14 @@
|
|||
package org.pgpainless.algorithm;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Enumeration of public key algorithms as defined in RFC4880.
|
||||
*
|
||||
|
@ -96,12 +100,30 @@ public enum PublicKeyAlgorithm {
|
|||
* If an invalid id is provided, null is returned.
|
||||
*
|
||||
* @param id numeric algorithm id
|
||||
* @return algorithm
|
||||
* @return algorithm or null
|
||||
*/
|
||||
@Nullable
|
||||
public static PublicKeyAlgorithm fromId(int id) {
|
||||
return MAP.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link PublicKeyAlgorithm} that corresponds to the provided algorithm id.
|
||||
* If an invalid id is provided, throw a {@link NoSuchElementException}.
|
||||
*
|
||||
* @param id numeric algorithm id
|
||||
* @return algorithm
|
||||
* @throws NoSuchElementException in case of an unmatched algorithm id
|
||||
*/
|
||||
@Nonnull
|
||||
public static PublicKeyAlgorithm requireFromId(int id) {
|
||||
PublicKeyAlgorithm algorithm = fromId(id);
|
||||
if (algorithm == null) {
|
||||
throw new NoSuchElementException("No PublicKeyAlgorithm found for id " + id);
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
private final int algorithmId;
|
||||
private final boolean signingCapable;
|
||||
private final boolean encryptionCapable;
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
package org.pgpainless.algorithm;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.bouncycastle.bcpg.SignatureSubpacketTags.ATTESTED_CERTIFICATIONS;
|
||||
import static org.bouncycastle.bcpg.SignatureSubpacketTags.CREATION_TIME;
|
||||
import static org.bouncycastle.bcpg.SignatureSubpacketTags.EMBEDDED_SIGNATURE;
|
||||
|
@ -36,6 +39,7 @@ import static org.bouncycastle.bcpg.SignatureSubpacketTags.TRUST_SIG;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
|
@ -412,14 +416,28 @@ public enum SignatureSubpacket {
|
|||
|
||||
/**
|
||||
* Return the {@link SignatureSubpacket} that corresponds to the provided id.
|
||||
* If an unmatched code is presented, return null.
|
||||
*
|
||||
* @param code id
|
||||
* @return signature subpacket
|
||||
*/
|
||||
@Nullable
|
||||
public static SignatureSubpacket fromCode(int code) {
|
||||
SignatureSubpacket tag = MAP.get(code);
|
||||
return MAP.get(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link SignatureSubpacket} that corresponds to the provided code.
|
||||
*
|
||||
* @param code code
|
||||
* @return signature subpacket
|
||||
* @throws NoSuchElementException in case of an unmatched subpacket tag
|
||||
*/
|
||||
@Nonnull
|
||||
public static SignatureSubpacket requireFromCode(int code) {
|
||||
SignatureSubpacket tag = fromCode(code);
|
||||
if (tag == null) {
|
||||
throw new IllegalArgumentException("No SignatureSubpacket tag found with code " + code);
|
||||
throw new NoSuchElementException("No SignatureSubpacket tag found with code " + code);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
@ -433,7 +451,11 @@ public enum SignatureSubpacket {
|
|||
public static List<SignatureSubpacket> fromCodes(int[] codes) {
|
||||
List<SignatureSubpacket> tags = new ArrayList<>();
|
||||
for (int code : codes) {
|
||||
tags.add(fromCode(code));
|
||||
try {
|
||||
tags.add(requireFromCode(code));
|
||||
} catch (NoSuchElementException e) {
|
||||
// skip
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ package org.pgpainless.algorithm;
|
|||
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
@ -167,7 +168,9 @@ public enum SignatureType {
|
|||
*
|
||||
* @param code numeric id
|
||||
* @return signature type enum
|
||||
* @throws IllegalArgumentException in case of an unmatched signature type code
|
||||
*/
|
||||
@Nonnull
|
||||
public static SignatureType valueOf(int code) {
|
||||
SignatureType type = map.get(code);
|
||||
if (type != null) {
|
||||
|
|
|
@ -5,10 +5,14 @@
|
|||
package org.pgpainless.algorithm;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPLiteralData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Enumeration of possible encoding formats of the content of the literal data packet.
|
||||
*
|
||||
|
@ -78,11 +82,31 @@ public enum StreamEncoding {
|
|||
|
||||
/**
|
||||
* Return the {@link StreamEncoding} corresponding to the provided code identifier.
|
||||
* If no matching encoding is found, return null.
|
||||
*
|
||||
* @param code identifier
|
||||
* @return encoding enum
|
||||
*/
|
||||
@Nullable
|
||||
public static StreamEncoding fromCode(int code) {
|
||||
return MAP.get((char) code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link StreamEncoding} corresponding to the provided code identifier.
|
||||
* If no matching encoding is found, throw a {@link NoSuchElementException}.
|
||||
*
|
||||
* @param code identifier
|
||||
* @return encoding enum
|
||||
*
|
||||
* @throws NoSuchElementException in case of an unmatched identifier
|
||||
*/
|
||||
@Nonnull
|
||||
public static StreamEncoding requireFromCode(int code) {
|
||||
StreamEncoding encoding = fromCode(code);
|
||||
if (encoding == null) {
|
||||
throw new NoSuchElementException("No StreamEncoding found for code " + code);
|
||||
}
|
||||
return encoding;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,14 @@
|
|||
package org.pgpainless.algorithm;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Enumeration of possible symmetric encryption algorithms.
|
||||
*
|
||||
|
@ -106,10 +110,29 @@ public enum SymmetricKeyAlgorithm {
|
|||
* @param id numeric algorithm id
|
||||
* @return symmetric key algorithm enum
|
||||
*/
|
||||
@Nullable
|
||||
public static SymmetricKeyAlgorithm fromId(int id) {
|
||||
return MAP.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link SymmetricKeyAlgorithm} enum that corresponds to the provided numeric id.
|
||||
* If an invalid id is provided, throw a {@link NoSuchElementException}.
|
||||
*
|
||||
* @param id numeric algorithm id
|
||||
* @return symmetric key algorithm enum
|
||||
*
|
||||
* @throws NoSuchElementException if an unmatched id is provided
|
||||
*/
|
||||
@Nonnull
|
||||
public static SymmetricKeyAlgorithm requireFromId(int id) {
|
||||
SymmetricKeyAlgorithm algorithm = fromId(id);
|
||||
if (algorithm == null) {
|
||||
throw new NoSuchElementException("No SymmetricKeyAlgorithm found for id " + id);
|
||||
}
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
private final int algorithmId;
|
||||
|
||||
SymmetricKeyAlgorithm(int algorithmId) {
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.HashSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -310,9 +311,13 @@ public final class DecryptionStreamFactory {
|
|||
|
||||
private InputStream processPGPCompressedData(PGPCompressedData pgpCompressedData, int depth)
|
||||
throws PGPException, IOException {
|
||||
CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.fromId(pgpCompressedData.getAlgorithm());
|
||||
LOGGER.debug("Depth {}: Encountered PGPCompressedData: {}", depth, compressionAlgorithm);
|
||||
resultBuilder.setCompressionAlgorithm(compressionAlgorithm);
|
||||
try {
|
||||
CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.requireFromId(pgpCompressedData.getAlgorithm());
|
||||
LOGGER.debug("Depth {}: Encountered PGPCompressedData: {}", depth, compressionAlgorithm);
|
||||
resultBuilder.setCompressionAlgorithm(compressionAlgorithm);
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new PGPException("Unknown compression algorithm encountered.", e);
|
||||
}
|
||||
|
||||
InputStream inflatedDataStream = pgpCompressedData.getDataStream();
|
||||
InputStream decodedDataStream = PGPUtil.getDecoderStream(inflatedDataStream);
|
||||
|
@ -340,7 +345,7 @@ public final class DecryptionStreamFactory {
|
|||
|
||||
resultBuilder.setFileName(pgpLiteralData.getFileName())
|
||||
.setModificationDate(pgpLiteralData.getModificationTime())
|
||||
.setFileEncoding(StreamEncoding.fromCode(pgpLiteralData.getFormat()));
|
||||
.setFileEncoding(StreamEncoding.requireFromCode(pgpLiteralData.getFormat()));
|
||||
|
||||
if (onePassSignatureChecks.isEmpty() && onePassSignaturesWithMissingCert.isEmpty()) {
|
||||
LOGGER.debug("No OnePassSignatures found -> We are done");
|
||||
|
|
|
@ -320,7 +320,7 @@ public final class SigningOptions {
|
|||
throws PGPException {
|
||||
SubkeyIdentifier signingKeyIdentifier = new SubkeyIdentifier(secretKey, signingSubkey.getKeyID());
|
||||
PGPSecretKey signingSecretKey = secretKey.getSecretKey(signingSubkey.getKeyID());
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.fromId(signingSecretKey.getPublicKey().getAlgorithm());
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.requireFromId(signingSecretKey.getPublicKey().getAlgorithm());
|
||||
int bitStrength = secretKey.getPublicKey().getBitStrength();
|
||||
if (!PGPainless.getPolicy().getPublicKeyAlgorithmPolicy().isAcceptable(publicKeyAlgorithm, bitStrength)) {
|
||||
throw new IllegalArgumentException("Public key algorithm policy violation: " +
|
||||
|
|
|
@ -58,7 +58,7 @@ public class BcImplementationFactory extends ImplementationFactory {
|
|||
int keyEncryptionAlgorithm = secretKey.getKeyEncryptionAlgorithm();
|
||||
|
||||
if (secretKey.getS2K() == null) {
|
||||
return getPBESecretKeyEncryptor(SymmetricKeyAlgorithm.fromId(keyEncryptionAlgorithm), passphrase);
|
||||
return getPBESecretKeyEncryptor(SymmetricKeyAlgorithm.requireFromId(keyEncryptionAlgorithm), passphrase);
|
||||
}
|
||||
|
||||
int hashAlgorithm = secretKey.getS2K().getHashAlgorithm();
|
||||
|
|
|
@ -65,7 +65,7 @@ public class KeyInfo {
|
|||
}
|
||||
|
||||
public static String getCurveName(PGPPublicKey publicKey) {
|
||||
PublicKeyAlgorithm algorithm = PublicKeyAlgorithm.fromId(publicKey.getAlgorithm());
|
||||
PublicKeyAlgorithm algorithm = PublicKeyAlgorithm.requireFromId(publicKey.getAlgorithm());
|
||||
ECPublicBCPGKey key;
|
||||
switch (algorithm) {
|
||||
case ECDSA: {
|
||||
|
|
|
@ -567,8 +567,9 @@ public class KeyRingInfo {
|
|||
*
|
||||
* @return public key algorithm
|
||||
*/
|
||||
@Nonnull
|
||||
public PublicKeyAlgorithm getAlgorithm() {
|
||||
return PublicKeyAlgorithm.fromId(getPublicKey().getAlgorithm());
|
||||
return PublicKeyAlgorithm.requireFromId(getPublicKey().getAlgorithm());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -272,11 +272,11 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
|||
KeyFlag... additionalKeyFlags)
|
||||
throws PGPException, IOException, NoSuchAlgorithmException {
|
||||
KeyFlag[] flags = concat(keyFlag, additionalKeyFlags);
|
||||
PublicKeyAlgorithm subkeyAlgorithm = PublicKeyAlgorithm.fromId(subkey.getPublicKey().getAlgorithm());
|
||||
PublicKeyAlgorithm subkeyAlgorithm = PublicKeyAlgorithm.requireFromId(subkey.getPublicKey().getAlgorithm());
|
||||
SignatureSubpacketsUtil.assureKeyCanCarryFlags(subkeyAlgorithm);
|
||||
|
||||
// check key against public key algorithm policy
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.fromId(subkey.getPublicKey().getAlgorithm());
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.requireFromId(subkey.getPublicKey().getAlgorithm());
|
||||
int bitStrength = subkey.getPublicKey().getBitStrength();
|
||||
if (!PGPainless.getPolicy().getPublicKeyAlgorithmPolicy().isAcceptable(publicKeyAlgorithm, bitStrength)) {
|
||||
throw new IllegalArgumentException("Public key algorithm policy violation: " +
|
||||
|
@ -285,7 +285,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
|||
|
||||
PGPSecretKey primaryKey = secretKeyRing.getSecretKey();
|
||||
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeyRing);
|
||||
PublicKeyAlgorithm signingKeyAlgorithm = PublicKeyAlgorithm.fromId(primaryKey.getPublicKey().getAlgorithm());
|
||||
PublicKeyAlgorithm signingKeyAlgorithm = PublicKeyAlgorithm.requireFromId(primaryKey.getPublicKey().getAlgorithm());
|
||||
HashAlgorithm hashAlgorithm = HashAlgorithmNegotiator
|
||||
.negotiateSignatureHashAlgorithm(PGPainless.getPolicy())
|
||||
.negotiateHashAlgorithm(info.getPreferredHashAlgorithms());
|
||||
|
|
|
@ -42,7 +42,10 @@ public final class OpenPgpKeyAttributeUtil {
|
|||
continue;
|
||||
}
|
||||
for (int h : hashAlgos) {
|
||||
hashAlgorithms.add(HashAlgorithm.fromId(h));
|
||||
HashAlgorithm algorithm = HashAlgorithm.fromId(h);
|
||||
if (algorithm != null) {
|
||||
hashAlgorithms.add(algorithm);
|
||||
}
|
||||
}
|
||||
// Exit the loop after the first key signature with hash algorithms.
|
||||
break;
|
||||
|
|
|
@ -42,7 +42,7 @@ public class PublicKeyParameterValidationUtil {
|
|||
|
||||
public static void verifyPublicKeyParameterIntegrity(PGPPrivateKey privateKey, PGPPublicKey publicKey)
|
||||
throws KeyIntegrityException {
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.fromId(publicKey.getAlgorithm());
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.requireFromId(publicKey.getAlgorithm());
|
||||
boolean valid = true;
|
||||
|
||||
// Algorithm specific validations
|
||||
|
@ -97,7 +97,7 @@ public class PublicKeyParameterValidationUtil {
|
|||
*/
|
||||
private static boolean verifyCanSign(PGPPrivateKey privateKey, PGPPublicKey publicKey) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.fromId(publicKey.getAlgorithm());
|
||||
PublicKeyAlgorithm publicKeyAlgorithm = PublicKeyAlgorithm.requireFromId(publicKey.getAlgorithm());
|
||||
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
|
||||
ImplementationFactory.getInstance().getPGPContentSignerBuilder(publicKeyAlgorithm, HashAlgorithm.SHA256)
|
||||
);
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Collections;
|
|||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
@ -232,8 +233,13 @@ public final class Policy {
|
|||
* @return true if algorithm is acceptable, false otherwise
|
||||
*/
|
||||
public boolean isAcceptable(int algorithmId) {
|
||||
SymmetricKeyAlgorithm algorithm = SymmetricKeyAlgorithm.fromId(algorithmId);
|
||||
return isAcceptable(algorithm);
|
||||
try {
|
||||
SymmetricKeyAlgorithm algorithm = SymmetricKeyAlgorithm.requireFromId(algorithmId);
|
||||
return isAcceptable(algorithm);
|
||||
} catch (NoSuchElementException e) {
|
||||
// Unknown algorithm is not acceptable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,8 +335,13 @@ public final class Policy {
|
|||
* @return true if the hash algorithm is acceptable, false otherwise
|
||||
*/
|
||||
public boolean isAcceptable(int algorithmId) {
|
||||
HashAlgorithm algorithm = HashAlgorithm.fromId(algorithmId);
|
||||
return isAcceptable(algorithm);
|
||||
try {
|
||||
HashAlgorithm algorithm = HashAlgorithm.requireFromId(algorithmId);
|
||||
return isAcceptable(algorithm);
|
||||
} catch (NoSuchElementException e) {
|
||||
// Unknown algorithm is not acceptable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -382,7 +393,13 @@ public final class Policy {
|
|||
}
|
||||
|
||||
public boolean isAcceptable(int compressionAlgorithmTag) {
|
||||
return isAcceptable(CompressionAlgorithm.fromId(compressionAlgorithmTag));
|
||||
try {
|
||||
CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.requireFromId(compressionAlgorithmTag);
|
||||
return isAcceptable(compressionAlgorithm);
|
||||
} catch (NoSuchElementException e) {
|
||||
// Unknown algorithm is not acceptable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAcceptable(CompressionAlgorithm compressionAlgorithm) {
|
||||
|
@ -408,7 +425,13 @@ public final class Policy {
|
|||
}
|
||||
|
||||
public boolean isAcceptable(int algorithmId, int bitStrength) {
|
||||
return isAcceptable(PublicKeyAlgorithm.fromId(algorithmId), bitStrength);
|
||||
try {
|
||||
PublicKeyAlgorithm algorithm = PublicKeyAlgorithm.requireFromId(algorithmId);
|
||||
return isAcceptable(algorithm, bitStrength);
|
||||
} catch (NoSuchElementException e) {
|
||||
// Unknown algorithm is not acceptable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAcceptable(PublicKeyAlgorithm algorithm, int bitStrength) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Date;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bouncycastle.bcpg.sig.KeyFlags;
|
||||
|
@ -92,7 +93,7 @@ public abstract class SignatureValidator {
|
|||
return new SignatureValidator() {
|
||||
@Override
|
||||
public void verify(PGPSignature signature) throws SignatureValidationException {
|
||||
if (!PublicKeyAlgorithm.fromId(signature.getKeyAlgorithm()).isSigningCapable()) {
|
||||
if (!PublicKeyAlgorithm.requireFromId(signature.getKeyAlgorithm()).isSigningCapable()) {
|
||||
// subkey is not signing capable -> No need to process embedded sigs
|
||||
return;
|
||||
}
|
||||
|
@ -168,7 +169,7 @@ public abstract class SignatureValidator {
|
|||
return new SignatureValidator() {
|
||||
@Override
|
||||
public void verify(PGPSignature signature) throws SignatureValidationException {
|
||||
PublicKeyAlgorithm algorithm = PublicKeyAlgorithm.fromId(signingKey.getAlgorithm());
|
||||
PublicKeyAlgorithm algorithm = PublicKeyAlgorithm.requireFromId(signingKey.getAlgorithm());
|
||||
int bitStrength = signingKey.getBitStrength();
|
||||
if (bitStrength == -1) {
|
||||
throw new SignatureValidationException("Cannot determine bit strength of signing key.");
|
||||
|
@ -191,11 +192,14 @@ public abstract class SignatureValidator {
|
|||
return new SignatureValidator() {
|
||||
@Override
|
||||
public void verify(PGPSignature signature) throws SignatureValidationException {
|
||||
HashAlgorithm hashAlgorithm = HashAlgorithm.fromId(signature.getHashAlgorithm());
|
||||
Policy.HashAlgorithmPolicy hashAlgorithmPolicy = getHashAlgorithmPolicyForSignature(signature, policy);
|
||||
|
||||
if (!hashAlgorithmPolicy.isAcceptable(signature.getHashAlgorithm())) {
|
||||
throw new SignatureValidationException("Signature uses unacceptable hash algorithm " + hashAlgorithm);
|
||||
try {
|
||||
HashAlgorithm hashAlgorithm = HashAlgorithm.requireFromId(signature.getHashAlgorithm());
|
||||
Policy.HashAlgorithmPolicy hashAlgorithmPolicy = getHashAlgorithmPolicyForSignature(signature, policy);
|
||||
if (!hashAlgorithmPolicy.isAcceptable(signature.getHashAlgorithm())) {
|
||||
throw new SignatureValidationException("Signature uses unacceptable hash algorithm " + hashAlgorithm);
|
||||
}
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new SignatureValidationException("Signature uses unknown hash algorithm " + signature.getHashAlgorithm());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -255,8 +259,8 @@ public abstract class SignatureValidator {
|
|||
PGPSignatureSubpacketVector hashedSubpackets = signature.getHashedSubPackets();
|
||||
for (int criticalTag : hashedSubpackets.getCriticalTags()) {
|
||||
try {
|
||||
SignatureSubpacket.fromCode(criticalTag);
|
||||
} catch (IllegalArgumentException e) {
|
||||
SignatureSubpacket.requireFromCode(criticalTag);
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new SignatureValidationException("Signature contains unknown critical subpacket of type " + Long.toHexString(criticalTag));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class SignatureSubpacketsHelper {
|
|||
|
||||
public static SignatureSubpackets applyFrom(PGPSignatureSubpacketVector vector, SignatureSubpackets subpackets) {
|
||||
for (SignatureSubpacket subpacket : vector.toArray()) {
|
||||
org.pgpainless.algorithm.SignatureSubpacket type = org.pgpainless.algorithm.SignatureSubpacket.fromCode(subpacket.getType());
|
||||
org.pgpainless.algorithm.SignatureSubpacket type = org.pgpainless.algorithm.SignatureSubpacket.requireFromCode(subpacket.getType());
|
||||
switch (type) {
|
||||
case signatureCreationTime:
|
||||
case issuerKeyId:
|
||||
|
@ -102,8 +102,8 @@ public class SignatureSubpacketsHelper {
|
|||
case signatureTarget:
|
||||
SignatureTarget target = (SignatureTarget) subpacket;
|
||||
subpackets.setSignatureTarget(target.isCritical(),
|
||||
PublicKeyAlgorithm.fromId(target.getPublicKeyAlgorithm()),
|
||||
HashAlgorithm.fromId(target.getHashAlgorithm()),
|
||||
PublicKeyAlgorithm.requireFromId(target.getPublicKeyAlgorithm()),
|
||||
HashAlgorithm.requireFromId(target.getHashAlgorithm()),
|
||||
target.getHashData());
|
||||
break;
|
||||
case embeddedSignature:
|
||||
|
|
|
@ -257,7 +257,10 @@ public final class SignatureSubpacketsUtil {
|
|||
PreferredAlgorithms preferences = getPreferredSymmetricAlgorithms(signature);
|
||||
if (preferences != null) {
|
||||
for (int code : preferences.getPreferences()) {
|
||||
algorithms.add(SymmetricKeyAlgorithm.fromId(code));
|
||||
SymmetricKeyAlgorithm algorithm = SymmetricKeyAlgorithm.fromId(code);
|
||||
if (algorithm != null) {
|
||||
algorithms.add(algorithm);
|
||||
}
|
||||
}
|
||||
}
|
||||
return algorithms;
|
||||
|
@ -286,7 +289,10 @@ public final class SignatureSubpacketsUtil {
|
|||
PreferredAlgorithms preferences = getPreferredHashAlgorithms(signature);
|
||||
if (preferences != null) {
|
||||
for (int code : preferences.getPreferences()) {
|
||||
algorithms.add(HashAlgorithm.fromId(code));
|
||||
HashAlgorithm algorithm = HashAlgorithm.fromId(code);
|
||||
if (algorithm != null) {
|
||||
algorithms.add(algorithm);
|
||||
}
|
||||
}
|
||||
}
|
||||
return algorithms;
|
||||
|
@ -315,7 +321,10 @@ public final class SignatureSubpacketsUtil {
|
|||
PreferredAlgorithms preferences = getPreferredCompressionAlgorithms(signature);
|
||||
if (preferences != null) {
|
||||
for (int code : preferences.getPreferences()) {
|
||||
algorithms.add(CompressionAlgorithm.fromId(code));
|
||||
CompressionAlgorithm algorithm = CompressionAlgorithm.fromId(code);
|
||||
if (algorithm != null) {
|
||||
algorithms.add(algorithm);
|
||||
}
|
||||
}
|
||||
}
|
||||
return algorithms;
|
||||
|
|
|
@ -24,7 +24,7 @@ public class SessionKey {
|
|||
* @param sessionKey BC session key
|
||||
*/
|
||||
public SessionKey(@Nonnull PGPSessionKey sessionKey) {
|
||||
this(SymmetricKeyAlgorithm.fromId(sessionKey.getAlgorithm()), sessionKey.getKey());
|
||||
this(SymmetricKeyAlgorithm.requireFromId(sessionKey.getAlgorithm()), sessionKey.getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,20 +6,37 @@ package org.pgpainless.algorithm;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class FeatureTest {
|
||||
|
||||
@Test
|
||||
public void testAll() {
|
||||
for (Feature feature : Feature.values()) {
|
||||
assertEquals(feature, Feature.fromId(feature.getFeatureId()));
|
||||
assertEquals(feature, Feature.requireFromId(feature.getFeatureId()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModificationDetection() {
|
||||
Feature modificationDetection = Feature.MODIFICATION_DETECTION;
|
||||
assertEquals(0x01, modificationDetection.getFeatureId());
|
||||
assertEquals(modificationDetection, Feature.fromId((byte) 0x01));
|
||||
assertEquals(modificationDetection, Feature.requireFromId((byte) 0x01));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromInvalidIdIsNull() {
|
||||
assertNull(Feature.fromId((byte) 0x99));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequireFromInvalidThrows() {
|
||||
assertThrows(NoSuchElementException.class, () -> Feature.requireFromId((byte) 0x99));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ public class SignatureStructureTest {
|
|||
|
||||
@Test
|
||||
public void testGetHashAlgorithm() {
|
||||
assertEquals(HashAlgorithm.SHA256, HashAlgorithm.fromId(signature.getHashAlgorithm()));
|
||||
assertEquals(HashAlgorithm.SHA256, HashAlgorithm.requireFromId(signature.getHashAlgorithm()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -70,7 +70,7 @@ public class DecryptImpl implements Decrypt {
|
|||
public DecryptImpl withSessionKey(SessionKey sessionKey) throws SOPGPException.UnsupportedOption {
|
||||
consumerOptions.setSessionKey(
|
||||
new org.pgpainless.util.SessionKey(
|
||||
SymmetricKeyAlgorithm.fromId(sessionKey.getAlgorithm()),
|
||||
SymmetricKeyAlgorithm.requireFromId(sessionKey.getAlgorithm()),
|
||||
sessionKey.getKey()));
|
||||
return this;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue