1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-26 22:32:07 +01:00

Add HashAlgorithmPolicy and SymmetricKeyAlgorithmPolicy

This commit is contained in:
Paul Schaub 2021-02-19 19:51:44 +01:00
parent c75a192513
commit ce5f8990ef
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
6 changed files with 207 additions and 60 deletions

View file

@ -32,6 +32,7 @@ import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.key.modification.secretkeyring.SecretKeyRingEditor;
import org.pgpainless.key.modification.secretkeyring.SecretKeyRingEditorInterface;
import org.pgpainless.key.parsing.KeyRingReader;
import org.pgpainless.policy.Policy;
import org.pgpainless.symmetric_encryption.SymmetricEncryptorDecryptor;
import org.pgpainless.util.Passphrase;

View file

@ -1,56 +0,0 @@
/*
* Copyright 2021 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pgpainless;
import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
public final class Policy {
private static Policy INSTANCE;
private HashAlgorithm signatureHashAlgorithm = HashAlgorithm.SHA512;
private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.AES_256;
private Policy() {
}
public static Policy getInstance() {
if (INSTANCE == null) {
INSTANCE = new Policy();
}
return INSTANCE;
}
public void setDefaultSignatureHashAlgorithm(HashAlgorithm hashAlgorithm) {
if (hashAlgorithm == null) {
throw new IllegalArgumentException("HashAlgorithm cannot be null.");
}
this.signatureHashAlgorithm = hashAlgorithm;
}
public HashAlgorithm getDefaultSignatureHashAlgorithm() {
return signatureHashAlgorithm;
}
public void setDefaultKeyEncryptionAlgorithm(SymmetricKeyAlgorithm symmetricKeyAlgorithm) {
this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
}
public SymmetricKeyAlgorithm getDefaultSymmetricKeyAlgorithm() {
return symmetricKeyAlgorithm;
}
}

View file

@ -50,6 +50,7 @@ import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.type.KeyType;
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
@ -420,16 +421,19 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
}
private PGPContentSignerBuilder buildContentSigner(PGPKeyPair certKey) {
HashAlgorithm hashAlgorithm = PGPainless.getPolicy().getSignatureHashAlgorithmPolicy().defaultHashAlgorithm();
return ImplementationFactory.getInstance().getPGPContentSignerBuilder(
certKey.getPublicKey().getAlgorithm(),
PGPainless.getPolicy().getDefaultSignatureHashAlgorithm().getAlgorithmId());
hashAlgorithm.getAlgorithmId());
}
private PBESecretKeyEncryptor buildSecretKeyEncryptor() {
SymmetricKeyAlgorithm keyEncryptionAlgorithm = PGPainless.getPolicy().getSymmetricKeyAlgorithmPolicy()
.getDefaultSymmetricKeyAlgorithm();
PBESecretKeyEncryptor encryptor = passphrase == null || passphrase.isEmpty() ?
null : // unencrypted key pair, otherwise AES-256 encrypted
ImplementationFactory.getInstance().getPBESecretKeyEncryptor(
PGPainless.getPolicy().getDefaultSymmetricKeyAlgorithm(), digestCalculator, passphrase);
keyEncryptionAlgorithm, digestCalculator, passphrase);
return encryptor;
}

View file

@ -58,7 +58,7 @@ public class SignatureUtils {
private static HashAlgorithm negotiateHashAlgorithm(List<HashAlgorithm> preferredHashAlgorithms) {
if (preferredHashAlgorithms.isEmpty()) {
return PGPainless.getPolicy().getDefaultSignatureHashAlgorithm();
return PGPainless.getPolicy().getSignatureHashAlgorithmPolicy().defaultHashAlgorithm();
}
return preferredHashAlgorithms.get(0);
}
@ -100,9 +100,10 @@ public class SignatureUtils {
case CASUAL_CERTIFICATION:
case POSITIVE_CERTIFICATION:
case DIRECT_KEY:
return isSelfSignatureValid(signature, issuer);
case KEY_REVOCATION:
case CERTIFICATION_REVOCATION:
return isSelfSignatureValid(signature, issuer);
return isRevocationSignatureValid(signature, issuer);
case SUBKEY_BINDING:
case PRIMARYKEY_BINDING:
case SUBKEY_REVOCATION:
@ -117,6 +118,23 @@ public class SignatureUtils {
}
public static boolean isSelfSignatureValid(PGPSignature signature, PGPPublicKey publicKey) throws PGPException {
if (!PGPainless.getPolicy().getSignatureHashAlgorithmPolicy().isAcceptable(signature.getHashAlgorithm())) {
return false;
}
for (Iterator<String> it = publicKey.getUserIDs(); it.hasNext(); ) {
String userId = it.next();
boolean valid = isSelfSignatureOnUserIdValid(signature, userId, publicKey);
if (valid) {
return true;
}
}
return false;
}
public static boolean isRevocationSignatureValid(PGPSignature signature, PGPPublicKey publicKey) throws PGPException {
if (!PGPainless.getPolicy().getRevocationSignatureHashAlgorithmPolicy().isAcceptable(signature.getHashAlgorithm())) {
return false;
}
for (Iterator<String> it = publicKey.getUserIDs(); it.hasNext(); ) {
String userId = it.next();
boolean valid = isSelfSignatureOnUserIdValid(signature, userId, publicKey);

View file

@ -0,0 +1,161 @@
/*
* Copyright 2021 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pgpainless.policy;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
public final class Policy {
private static Policy INSTANCE;
private HashAlgorithmPolicy signatureHashAlgorithmPolicy =
HashAlgorithmPolicy.defaultSignatureAlgorithmPolicy();
private HashAlgorithmPolicy revocationSignatureHashAlgorithmPolicy =
HashAlgorithmPolicy.defaultRevocationSignatureHashAlgorithmPolicy();
private SymmetricKeyAlgorithmPolicy symmetricKeyAlgorithmPolicy =
SymmetricKeyAlgorithmPolicy.defaultSymmetricKeyAlgorithmPolicy();
private Policy() {
}
public static Policy getInstance() {
if (INSTANCE == null) {
INSTANCE = new Policy();
}
return INSTANCE;
}
public HashAlgorithmPolicy getSignatureHashAlgorithmPolicy() {
return signatureHashAlgorithmPolicy;
}
public void setSignatureHashAlgorithmPolicy(HashAlgorithmPolicy policy) {
if (policy == null) {
throw new NullPointerException("Policy cannot be null.");
}
this.signatureHashAlgorithmPolicy = policy;
}
public HashAlgorithmPolicy getRevocationSignatureHashAlgorithmPolicy() {
return revocationSignatureHashAlgorithmPolicy;
}
public void setRevocationSignatureHashAlgorithmPolicy(HashAlgorithmPolicy policy) {
if (policy == null) {
throw new NullPointerException("Policy cannot be null.");
}
this.revocationSignatureHashAlgorithmPolicy = policy;
}
public SymmetricKeyAlgorithmPolicy getSymmetricKeyAlgorithmPolicy() {
return symmetricKeyAlgorithmPolicy;
}
public void setSymmetricKeyAlgorithmPolicy(SymmetricKeyAlgorithmPolicy policy) {
if (policy == null) {
throw new NullPointerException("Policy cannot be null.");
}
this.symmetricKeyAlgorithmPolicy = policy;
}
public static final class SymmetricKeyAlgorithmPolicy {
private final SymmetricKeyAlgorithm defaultSymmetricKeyAlgorithm;
private final List<SymmetricKeyAlgorithm> acceptableSymmetricKeyAlgorithms;
public SymmetricKeyAlgorithmPolicy(SymmetricKeyAlgorithm defaultSymmetricKeyAlgorithm, List<SymmetricKeyAlgorithm> acceptableSymmetricKeyAlgorithms) {
this.defaultSymmetricKeyAlgorithm = defaultSymmetricKeyAlgorithm;
this.acceptableSymmetricKeyAlgorithms = Collections.unmodifiableList(acceptableSymmetricKeyAlgorithms);
}
public SymmetricKeyAlgorithm getDefaultSymmetricKeyAlgorithm() {
return defaultSymmetricKeyAlgorithm;
}
public boolean isAcceptable(SymmetricKeyAlgorithm algorithm) {
return acceptableSymmetricKeyAlgorithms.contains(algorithm);
}
public boolean isAcceptable(int algorithmId) {
SymmetricKeyAlgorithm algorithm = SymmetricKeyAlgorithm.fromId(algorithmId);
return isAcceptable(algorithm);
}
public static SymmetricKeyAlgorithmPolicy defaultSymmetricKeyAlgorithmPolicy() {
return new SymmetricKeyAlgorithmPolicy(SymmetricKeyAlgorithm.AES_256, Arrays.asList(
SymmetricKeyAlgorithm.IDEA,
SymmetricKeyAlgorithm.CAST5,
SymmetricKeyAlgorithm.BLOWFISH,
SymmetricKeyAlgorithm.AES_128,
SymmetricKeyAlgorithm.AES_192,
SymmetricKeyAlgorithm.AES_256,
SymmetricKeyAlgorithm.TWOFISH,
SymmetricKeyAlgorithm.CAMELLIA_128,
SymmetricKeyAlgorithm.CAMELLIA_192,
SymmetricKeyAlgorithm.CAMELLIA_256
));
}
}
public static final class HashAlgorithmPolicy {
private final HashAlgorithm defaultHashAlgorithm;
private final List<HashAlgorithm> acceptableHashAlgorithms;
public HashAlgorithmPolicy(HashAlgorithm defaultHashAlgorithm, List<HashAlgorithm> acceptableHashAlgorithms) {
this.defaultHashAlgorithm = defaultHashAlgorithm;
this.acceptableHashAlgorithms = Collections.unmodifiableList(acceptableHashAlgorithms);
}
public HashAlgorithm defaultHashAlgorithm() {
return defaultHashAlgorithm;
}
public boolean isAcceptable(HashAlgorithm hashAlgorithm) {
return acceptableHashAlgorithms.contains(hashAlgorithm);
}
public boolean isAcceptable(int algorithmId) {
HashAlgorithm algorithm = HashAlgorithm.fromId(algorithmId);
return isAcceptable(algorithm);
}
public static HashAlgorithmPolicy defaultSignatureAlgorithmPolicy() {
return new HashAlgorithmPolicy(HashAlgorithm.SHA512, Arrays.asList(
HashAlgorithm.SHA224,
HashAlgorithm.SHA256,
HashAlgorithm.SHA384,
HashAlgorithm.SHA512
));
}
public static HashAlgorithmPolicy defaultRevocationSignatureHashAlgorithmPolicy() {
return new HashAlgorithmPolicy(HashAlgorithm.SHA512, Arrays.asList(
HashAlgorithm.RIPEMD160,
HashAlgorithm.SHA1,
HashAlgorithm.SHA224,
HashAlgorithm.SHA256,
HashAlgorithm.SHA384,
HashAlgorithm.SHA512
));
}
}
}

View file

@ -0,0 +1,19 @@
/*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Policy regarding used algorithms.
*/
package org.pgpainless.policy;