mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-26 14:22:05 +01:00
Further refactoring of KeyRingBuilder
This commit is contained in:
parent
81c3a471a7
commit
8a2051904a
4 changed files with 77 additions and 19 deletions
|
@ -51,7 +51,15 @@ public enum KeyFlag {
|
||||||
return flags;
|
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) {
|
public static boolean hasKeyFlag(int mask, KeyFlag flag) {
|
||||||
return (mask & flag.getFlag()) == 0;
|
return (mask & flag.getFlag()) == flag.getFlag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
*/
|
*/
|
||||||
public PGPKeyRing simpleRsaKeyRing(@Nonnull String userId, @Nonnull RsaLength length)
|
public PGPKeyRing simpleRsaKeyRing(@Nonnull String userId, @Nonnull RsaLength length)
|
||||||
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||||
return withMasterKey(
|
return this
|
||||||
|
.withMasterKey(
|
||||||
KeySpec.getBuilder(RSA_GENERAL.withLength(length))
|
KeySpec.getBuilder(RSA_GENERAL.withLength(length))
|
||||||
.withDefaultKeyFlags()
|
.withDefaultKeyFlags()
|
||||||
.withDefaultAlgorithms())
|
.withDefaultAlgorithms())
|
||||||
|
@ -98,7 +99,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
*/
|
*/
|
||||||
public PGPKeyRing simpleEcKeyRing(@Nonnull String userId)
|
public PGPKeyRing simpleEcKeyRing(@Nonnull String userId)
|
||||||
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
throws PGPException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||||
return withSubKey(
|
return this
|
||||||
|
.withSubKey(
|
||||||
KeySpec.getBuilder(ECDH.fromCurve(EllipticCurve._P256))
|
KeySpec.getBuilder(ECDH.fromCurve(EllipticCurve._P256))
|
||||||
.withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
|
.withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
|
||||||
.withDefaultAlgorithms())
|
.withDefaultAlgorithms())
|
||||||
|
@ -119,16 +121,21 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WithPrimaryUserId withMasterKey(@Nonnull KeySpec spec) {
|
public WithPrimaryUserId withMasterKey(@Nonnull KeySpec spec) {
|
||||||
if (canCertifyOthers(spec)) {
|
verifyMasterKeyCanCertify(spec);
|
||||||
throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER");
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyRingBuilder.this.keySpecs.add(0, spec);
|
KeyRingBuilder.this.keySpecs.add(0, spec);
|
||||||
return new WithPrimaryUserIdImpl();
|
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) {
|
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 {
|
class WithPrimaryUserIdImpl implements WithPrimaryUserId {
|
||||||
|
@ -189,14 +196,18 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
return new PGPKeyRing(publicKeys, secretKeys);
|
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(
|
return new PGPKeyRingGenerator(
|
||||||
PGPSignature.POSITIVE_CERTIFICATION, certKey,
|
PGPSignature.POSITIVE_CERTIFICATION, certKey,
|
||||||
userId, digestCalculator,
|
userId, digestCalculator,
|
||||||
hashedSubPackets, null, signer, secretKeyEncryptor);
|
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) {
|
for (KeySpec subKeySpec : keySpecs) {
|
||||||
PGPKeyPair subKey = generateKeyPair(subKeySpec);
|
PGPKeyPair subKey = generateKeyPair(subKeySpec);
|
||||||
if (subKeySpec.isInheritedSubPackets()) {
|
if (subKeySpec.isInheritedSubPackets()) {
|
||||||
|
@ -209,8 +220,8 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
|
|
||||||
private PGPContentSignerBuilder buildContentSigner(PGPKeyPair certKey) {
|
private PGPContentSignerBuilder buildContentSigner(PGPKeyPair certKey) {
|
||||||
return new JcaPGPContentSignerBuilder(
|
return new JcaPGPContentSignerBuilder(
|
||||||
certKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId())
|
certKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId())
|
||||||
.setProvider(ProviderFactory.getProvider());
|
.setProvider(ProviderFactory.getProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
private PBESecretKeyEncryptor buildSecretKeyEncryptor() {
|
private PBESecretKeyEncryptor buildSecretKeyEncryptor() {
|
||||||
|
|
|
@ -38,11 +38,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WithDetailedConfiguration withKeyFlags(@Nonnull KeyFlag... flags) {
|
public WithDetailedConfiguration withKeyFlags(@Nonnull KeyFlag... flags) {
|
||||||
int val = 0;
|
this.hashedSubPackets.setKeyFlags(false, KeyFlag.toBitmask(flags));
|
||||||
for (KeyFlag f : flags) {
|
|
||||||
val |= f.getFlag();
|
|
||||||
}
|
|
||||||
this.hashedSubPackets.setKeyFlags(false, val);
|
|
||||||
return new WithDetailedConfigurationImpl();
|
return new WithDetailedConfigurationImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue