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

Further refactoring of KeyRingBuilder

This commit is contained in:
Paul Schaub 2020-01-12 16:37:24 +01:00
parent 81c3a471a7
commit 8a2051904a
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 77 additions and 19 deletions

View file

@ -51,7 +51,15 @@ public enum KeyFlag {
return flags;
}
public static int toBitmask(KeyFlag... flags) {
int mask = 0;
for (KeyFlag f : flags) {
mask |= f.getFlag();
}
return mask;
}
public static boolean hasKeyFlag(int mask, KeyFlag flag) {
return (mask & flag.getFlag()) == 0;
return (mask & flag.getFlag()) == flag.getFlag();
}
}

View file

@ -75,7 +75,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
*/
public PGPKeyRing simpleRsaKeyRing(@Nonnull String userId, @Nonnull RsaLength length)
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
return withMasterKey(
return this
.withMasterKey(
KeySpec.getBuilder(RSA_GENERAL.withLength(length))
.withDefaultKeyFlags()
.withDefaultAlgorithms())
@ -98,7 +99,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
*/
public PGPKeyRing simpleEcKeyRing(@Nonnull String userId)
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
return withSubKey(
return this
.withSubKey(
KeySpec.getBuilder(ECDH.fromCurve(EllipticCurve._P256))
.withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
.withDefaultAlgorithms())
@ -119,16 +121,21 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
@Override
public WithPrimaryUserId withMasterKey(@Nonnull KeySpec spec) {
if (canCertifyOthers(spec)) {
throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER");
}
verifyMasterKeyCanCertify(spec);
KeyRingBuilder.this.keySpecs.add(0, spec);
return new WithPrimaryUserIdImpl();
}
private void verifyMasterKeyCanCertify(KeySpec spec) {
if (!canCertifyOthers(spec)) {
throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER");
}
}
private boolean canCertifyOthers(KeySpec keySpec) {
return KeyFlag.hasKeyFlag(keySpec.getSubpackets().getKeyFlags(), KeyFlag.CERTIFY_OTHER);
int flags = keySpec.getSubpackets().getKeyFlags();
return KeyFlag.hasKeyFlag(flags, KeyFlag.CERTIFY_OTHER);
}
class WithPrimaryUserIdImpl implements WithPrimaryUserId {
@ -189,14 +196,18 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
return new PGPKeyRing(publicKeys, secretKeys);
}
private PGPKeyRingGenerator buildRingGenerator(PGPKeyPair certKey, PGPContentSignerBuilder signer, PGPSignatureSubpacketVector hashedSubPackets) throws PGPException {
private PGPKeyRingGenerator buildRingGenerator(PGPKeyPair certKey,
PGPContentSignerBuilder signer,
PGPSignatureSubpacketVector hashedSubPackets)
throws PGPException {
return new PGPKeyRingGenerator(
PGPSignature.POSITIVE_CERTIFICATION, certKey,
userId, digestCalculator,
hashedSubPackets, null, signer, secretKeyEncryptor);
PGPSignature.POSITIVE_CERTIFICATION, certKey,
userId, digestCalculator,
hashedSubPackets, null, signer, secretKeyEncryptor);
}
private void addSubKeys(PGPKeyRingGenerator ringGenerator) throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException {
private void addSubKeys(PGPKeyRingGenerator ringGenerator)
throws NoSuchAlgorithmException, PGPException, InvalidAlgorithmParameterException {
for (KeySpec subKeySpec : keySpecs) {
PGPKeyPair subKey = generateKeyPair(subKeySpec);
if (subKeySpec.isInheritedSubPackets()) {
@ -209,8 +220,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
private PGPContentSignerBuilder buildContentSigner(PGPKeyPair certKey) {
return new JcaPGPContentSignerBuilder(
certKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId())
.setProvider(ProviderFactory.getProvider());
certKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId())
.setProvider(ProviderFactory.getProvider());
}
private PBESecretKeyEncryptor buildSecretKeyEncryptor() {

View file

@ -38,11 +38,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
@Override
public WithDetailedConfiguration withKeyFlags(@Nonnull KeyFlag... flags) {
int val = 0;
for (KeyFlag f : flags) {
val |= f.getFlag();
}
this.hashedSubPackets.setKeyFlags(false, val);
this.hashedSubPackets.setKeyFlags(false, KeyFlag.toBitmask(flags));
return new WithDetailedConfigurationImpl();
}

View file

@ -0,0 +1,43 @@
/*
* Copyright 2020 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.key;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import java.util.Arrays;
import org.junit.Test;
import org.pgpainless.algorithm.KeyFlag;
public class KeyFlagTest {
@Test
public void hasKeyFlagTest() {
int mask = KeyFlag.toBitmask(KeyFlag.AUTHENTICATION, KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA);
assertEquals(0x23, mask);
assertEquals(Arrays.asList(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA, KeyFlag.AUTHENTICATION),
KeyFlag.fromBitmask(mask));
assertTrue(KeyFlag.hasKeyFlag(mask, KeyFlag.CERTIFY_OTHER));
assertTrue(KeyFlag.hasKeyFlag(mask, KeyFlag.AUTHENTICATION));
assertTrue(KeyFlag.hasKeyFlag(mask, KeyFlag.SIGN_DATA));
assertFalse(KeyFlag.hasKeyFlag(mask, KeyFlag.ENCRYPT_STORAGE));
assertFalse(KeyFlag.hasKeyFlag(mask, KeyFlag.SHARED));
}
}