mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-30 08:12:06 +01:00
Fix signature creation using keys without preferred algorithms
This commit is contained in:
parent
831dbb3c5d
commit
74c0c8a32e
4 changed files with 245 additions and 2 deletions
|
@ -16,6 +16,8 @@
|
||||||
package org.pgpainless.key.util;
|
package org.pgpainless.key.util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -42,6 +44,9 @@ public class OpenPgpKeyAttributeUtil {
|
||||||
if (signatureType == SignatureType.POSITIVE_CERTIFICATION
|
if (signatureType == SignatureType.POSITIVE_CERTIFICATION
|
||||||
|| signatureType == SignatureType.GENERIC_CERTIFICATION) {
|
|| signatureType == SignatureType.GENERIC_CERTIFICATION) {
|
||||||
int[] hashAlgos = signature.getHashedSubPackets().getPreferredHashAlgorithms();
|
int[] hashAlgos = signature.getHashedSubPackets().getPreferredHashAlgorithms();
|
||||||
|
if (hashAlgos == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int h : hashAlgos) {
|
for (int h : hashAlgos) {
|
||||||
hashAlgorithms.add(HashAlgorithm.fromId(h));
|
hashAlgorithms.add(HashAlgorithm.fromId(h));
|
||||||
}
|
}
|
||||||
|
@ -53,4 +58,40 @@ public class OpenPgpKeyAttributeUtil {
|
||||||
}
|
}
|
||||||
return hashAlgorithms;
|
return hashAlgorithms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the hash algorithm that was used in the latest self signature.
|
||||||
|
*
|
||||||
|
* @param publicKey public key
|
||||||
|
* @return list of hash algorithm
|
||||||
|
*/
|
||||||
|
public static List<HashAlgorithm> guessPreferredHashAlgorithms(PGPPublicKey publicKey) {
|
||||||
|
HashAlgorithm hashAlgorithm = null;
|
||||||
|
Date lastCreationDate = null;
|
||||||
|
|
||||||
|
Iterator<?> keySignatures = publicKey.getSignatures();
|
||||||
|
while (keySignatures.hasNext()) {
|
||||||
|
PGPSignature signature = (PGPSignature) keySignatures.next();
|
||||||
|
if (signature.getKeyID() != publicKey.getKeyID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SignatureType signatureType = SignatureType.valueOf(signature.getSignatureType());
|
||||||
|
if (signatureType != SignatureType.POSITIVE_CERTIFICATION
|
||||||
|
&& signatureType != SignatureType.GENERIC_CERTIFICATION) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Date creationDate = signature.getCreationTime();
|
||||||
|
if (lastCreationDate == null || lastCreationDate.before(creationDate)) {
|
||||||
|
lastCreationDate = creationDate;
|
||||||
|
hashAlgorithm = HashAlgorithm.fromId(signature.getHashAlgorithm());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hashAlgorithm == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return Collections.singletonList(hashAlgorithm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,14 +37,18 @@ public class SignatureUtils {
|
||||||
|
|
||||||
private static BcPGPContentSignerBuilder getPgpContentSignerBuilderForKey(PGPPublicKey publicKey) {
|
private static BcPGPContentSignerBuilder getPgpContentSignerBuilderForKey(PGPPublicKey publicKey) {
|
||||||
List<HashAlgorithm> preferredHashAlgorithms = OpenPgpKeyAttributeUtil.getPreferredHashAlgorithms(publicKey);
|
List<HashAlgorithm> preferredHashAlgorithms = OpenPgpKeyAttributeUtil.getPreferredHashAlgorithms(publicKey);
|
||||||
|
if (preferredHashAlgorithms.isEmpty()) {
|
||||||
|
preferredHashAlgorithms = OpenPgpKeyAttributeUtil.guessPreferredHashAlgorithms(publicKey);
|
||||||
|
}
|
||||||
HashAlgorithm hashAlgorithm = negotiateHashAlgorithm(preferredHashAlgorithms);
|
HashAlgorithm hashAlgorithm = negotiateHashAlgorithm(preferredHashAlgorithms);
|
||||||
|
|
||||||
return new BcPGPContentSignerBuilder(publicKey.getAlgorithm(), hashAlgorithm.getAlgorithmId());
|
return new BcPGPContentSignerBuilder(publicKey.getAlgorithm(), hashAlgorithm.getAlgorithmId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HashAlgorithm negotiateHashAlgorithm(List<HashAlgorithm> preferredHashAlgorithms) {
|
private static HashAlgorithm negotiateHashAlgorithm(List<HashAlgorithm> preferredHashAlgorithms) {
|
||||||
// TODO: Match our list of supported hash algorithms against the list, to determine the best suitable algo.
|
if (preferredHashAlgorithms.isEmpty()) {
|
||||||
// For now we just take the first algorithm in the list and hope that BC has support for it.
|
return HashAlgorithm.SHA512;
|
||||||
|
}
|
||||||
return preferredHashAlgorithms.get(0);
|
return preferredHashAlgorithms.get(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* 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.key.modification;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
import org.pgpainless.key.info.KeyRingInfo;
|
||||||
|
import org.pgpainless.key.modification.secretkeyring.SecretKeyRingEditorInterface;
|
||||||
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.UnprotectedKeysProtector;
|
||||||
|
|
||||||
|
public class RevokeKeyWithoutPreferredAlgorithmsOnPrimaryKey {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This key has a primary key which does not carry a signature with preferred algorithms.
|
||||||
|
* We therefore have to guess a suitable algorithm to create a new signature with the new expiration date.
|
||||||
|
*/
|
||||||
|
private static final String KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||||
|
"Version: FlowCrypt Email Encryption 8.0.1\n" +
|
||||||
|
"Comment: Seamlessly send and receive encrypted email\n" +
|
||||||
|
"\n" +
|
||||||
|
"xcLYBGAIUhoBCADEnk3EACyTc/GVkwMI5MHls6oIlJT42qB2Wh6PF7FXpnS7\n" +
|
||||||
|
"0hBqZLSC0N+UxCROf/EUxYq7wUpwVp63Pd4hVyn1ppf1XOJztluGiXDPkVR6\n" +
|
||||||
|
"fQMMYXeIXnnJMcIBZLYYKUe+wMGMIz8oYzbU8dJHE8TCbsRukHtk5aFMTu1I\n" +
|
||||||
|
"+MCgq2jU/WVUYMJHILMF/e0hKix1lZBDyhg2g47xhdRvJgmHX81CKjOC4Jt/\n" +
|
||||||
|
"vz26jW276+koIqUK318EPBgYObsjEr7UcAKbOuUDbExZKdcgBCPswwcLaM7+\n" +
|
||||||
|
"kLBpvREYugyXlj2WT7laQB2iHc3aBpeYbPJ3Fn2UyXSICQaOAaM+b0+3ABEB\n" +
|
||||||
|
"AAEAB/44AlRqyhXopzWhgzBxHyEw+v4r1Y+eWEEvlbpwzrIBIvTL8Com9KsL\n" +
|
||||||
|
"PM8EBN/G0OFvJlq/427+E17BGkmlu7vDM4LELYKArejiqVJOfrrO7b+pjjZL\n" +
|
||||||
|
"zYXpz1fRp8vLlC7Q4v3/mqbKLYEYJg7dmn8JWB5y1IuiEVvibfVgPSQ6YDnu\n" +
|
||||||
|
"ZAbqxjxjrDa5d8pwFAuh+zkDrU5CY9Eoyuzi+Y2+K4XTchC/BZbEm+oClUiu\n" +
|
||||||
|
"KHxgyrby8BobLvhxr/duH6eUpDX8Czcw71ceWlBn+2fkh4JgnozKL/qED+I6\n" +
|
||||||
|
"URRE+GAEbaMT3f14HxyJvDcfZjwKEHhvSOPuzGCBI9dPtcepBADallzOOiQ+\n" +
|
||||||
|
"2+dy02Do766rr42KlRVa+WG2MTOqsCeA0wh/Hx8e7ufRVOfKczBZzDO9P2C6\n" +
|
||||||
|
"mEXIr87GxNsSD4MhzP9k9JNAIQXMb/bYGzB2o+sGPM1GeDpQsjaM2Cv1VrHt\n" +
|
||||||
|
"9XgP3uAUkllxpPgRP5Wjto7UXDu788V6Jf5yYgJ2dQQA5kVY14NeWo5/cKKH\n" +
|
||||||
|
"PfrYTMnw/7SECHTYaIhtZpAM040snjf/YYSfdIeVhoY+0wdbjKlLX8p4K0kZ\n" +
|
||||||
|
"cWdweLJ9EHic1I150D3Ql9RyNuS99Ti52bl2uSAukgOY6jdSgG2giy9Hl0BC\n" +
|
||||||
|
"Yls4J1/z+q0SjbrVDEUqKi2pgtBqTZ9ZH/sEAOFllvNtcEi47+hVd1ue8GfD\n" +
|
||||||
|
"uMHK7wj0dP6yQcS7DjooNLojlAQkrDWiIhR4ccvnr89e3k90HIfBP4dIJmfe\n" +
|
||||||
|
"Ey2GG9fCDts1QHdKErceQjorx68DvoYIKCMZwCeBJdXLdi8FVwBlNpyEgKsl\n" +
|
||||||
|
"FaynAXcbc+YJGHz0peLvIUiN7UyUP9vNFnRlc3Qta2V5QGZsb3djcnlwdC5j\n" +
|
||||||
|
"b23CwGIEEwEKAAwFAmAIUhoFiQAAC7cACgkQ9FHRAKrO1DL30Af+P9R+651n\n" +
|
||||||
|
"TTh40QUij44jnbZy/sBPWDGCCepLB+dAk+v7itd/vDT+CApnpewL7gFR7JoA\n" +
|
||||||
|
"cW+kV/8I8U2bAJwwakae36eTd+CGFPP4QHAHl/i6UBuC25Xr1UPUV6OQej+P\n" +
|
||||||
|
"1HGXPQN34oP5LyNQE3jAwkYKcBQan5LZ+7UzRCy0VHoHzY1bL24CYJpEmUrC\n" +
|
||||||
|
"un31P4McG921WfeFLfzqMyoDty/j1bt8BmGp/BFBSnvZJzHofRdRC3AfWncx\n" +
|
||||||
|
"lUQc9mth/DqQhipbu4FuRLQLNM0l1XcPjCcOaSdOylHQUMWhXhSdGM3/r74L\n" +
|
||||||
|
"kfYX60rotxuHuenXnt1QQxsbg+eIQ/DSpc0ZdGVzdC1zZWNvbmRAZmxvd2Ny\n" +
|
||||||
|
"eXB0LmNvbcLAYgQTAQoADAUCYAhSGgWJAAALtwAKCRD0UdEAqs7UMjxkB/4p\n" +
|
||||||
|
"cqeul3RrjpxkDwCsFdT9fwwE65PfzlImPDKI8T4DUeKOBthc/v6F+zAqpmgi\n" +
|
||||||
|
"nqSFZRD48dzFQHXA5NU+P9fVf0JQP/P5tiGZv9xsGVpteAH+t/7OYNboafbB\n" +
|
||||||
|
"h1HDx+A+M44J9O6xDdI+qiRKjgo4SmWBMxKS64Bde35lkesulujefWKpOw5j\n" +
|
||||||
|
"2Xg3vrt8mE+TDJpWJQ1fgt16mqgIkeqAQW5A6lMxr7KEesXmPou98ZLBEJjX\n" +
|
||||||
|
"uzS0Yodjk5BnanooOk6FytXh1XTHuXW4vzc2gveKODF2YjMi+KxGi6yk1tIy\n" +
|
||||||
|
"UjgkaoCVDnjvU2eChr3Ij3TinBhyDHHSRW1kMULjx8LYBGAIUhoBCADN0iMq\n" +
|
||||||
|
"+ZYNVW4vRJSvYEs9bFBS1tcyZfBtkbQ08kMexpoxLwW1l1cyil+cSewU0WpL\n" +
|
||||||
|
"XSFOcJYaNfKiA0u4lMh5e2+H7eNvX3qpmoifmWO2lhmBopo3I5F02Kb+MS17\n" +
|
||||||
|
"95LtN7GHZQ9F1BGzG13FIUTCZiQwmJBKay4qTd7/GIr7U6x7JUkAqbcPvbmP\n" +
|
||||||
|
"hM5ePLP1sTPyGtY7wgixCKKeifFHvQ79zMcErgiWuuS1LyMwv7awLPjVQtkO\n" +
|
||||||
|
"rBOKb3zoMtFJrXfnXYajXpNgYsQ+ZcDvjdi8h83RahbQmSUinCR7VVi57kvK\n" +
|
||||||
|
"mIaZSSnlOuqCaPjvXQRdUYAdgyIMNz4eA53lABEBAAEAB/4orHyZL0oVN/sG\n" +
|
||||||
|
"mcu1TbcIvCkyebT8x3LoQElHxlF32UEa86Mx8+a+POSwntYp9gmGu7CLjwnG\n" +
|
||||||
|
"w77/f928rCBjC37qspsFxS1ZK4oQ2i//ovGG8hJ+T4fc+ryjkqXdr/sH6H/r\n" +
|
||||||
|
"lQ/b2ZEm30NcY9rx/Nvtg5TONBijMRDewiOjD1cERLLBke6ohKv4teKxUEdE\n" +
|
||||||
|
"WYQnY2fEdaYxC4NzVgjKY2/F0MJrunJwZanI1lIuJF9avXTJTSt2qBWtmoSx\n" +
|
||||||
|
"my0cyWGzSq+qw9Aa4uG4CDFLb3ZibmeB2lZVUzam+GRbBGAezeKpqt2w7OlM\n" +
|
||||||
|
"aIfNqIRpP9vjGhDXlbe+CBk3hfY5BADcjj7GxHlEc+1QqOi/TSVPcqVzlyUK\n" +
|
||||||
|
"QZ5o4yC2WslQoQgBs0lG1m01QbJ7dQIY3iZ32PF/vK8I1/zqPykCFdRiL+dN\n" +
|
||||||
|
"Fq2a89BmqVbenZbuyOmQX8b2pYa+yOH+dT3FSV88fFa8gOJhnvB+qZJlc0yA\n" +
|
||||||
|
"OOe0868HeKTosuOaO09KKQQA7uWyPaj5myzfmHTMHOtJ5O6PT86gj5QYut2c\n" +
|
||||||
|
"fAJV81c1BEC5RUbmTojS5lo4l+zXCRBe9UxYt2KtrBW1l0SkJVfNIBLaRWMF\n" +
|
||||||
|
"KAWBMFye0lEBiMxMp5arXdkgAew/7hfrYmIXM70Y9Gat4KaDmMmB3LDmBoyl\n" +
|
||||||
|
"mbSQ/XdvI+fH5V0EAO1EtvBWUx56Ax0oyVMuNZxUanwdMedjfPyKkwLq9I2+\n" +
|
||||||
|
"/O0bx1V30EfmRvhy+EJTx+uCEgY9Pv81f28z676XOUdLoEyKAzAb9PWWgiCr\n" +
|
||||||
|
"VbmAsFdu5qE87d88c0p6/dmx/DKPTpFkkEZl2We7OVSQOaECrXHYqudsE5ZI\n" +
|
||||||
|
"LdetYlBhTQ3CwHkEGAEKACMCGwwFFgIDAQAECwkIBwUVCgkICwIeAQUCYAhS\n" +
|
||||||
|
"GgWJAAALtwAKCRD0UdEAqs7UMnmFB/9WD8+esxTjjVh/P+Rzhc0VQGt1o5TH\n" +
|
||||||
|
"bBVw8O2gA+mC78nqz26LfhGudVVZHWq7u3lIFuO/O6Ctp5BEqXFWRT+ikNHg\n" +
|
||||||
|
"zXAjQc0DxACt63xqaVXduvA4FDlmJnbrOnkH5MJUo4pcAfSTELDQWLuMIQsD\n" +
|
||||||
|
"ogYChjA3PG4bLEP0kz2NJuF5bHz/MNpexTaLoxNfA08MjkJCEhOArKQZj3kW\n" +
|
||||||
|
"OgbD1QvNflR5YA7I2pEkCCOLqjkWAOgowfb+ipUb55eZ2/4hM1S1kbrRXN80\n" +
|
||||||
|
"6GN3Hs+/BxvHo+JufAuSelNoln3zuX+GzAQaeZgkcN+RXcFiFOBEMNUmlGRl\n" +
|
||||||
|
"zqyz7qFrSCvY\n" +
|
||||||
|
"=3Zyp\n" +
|
||||||
|
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChangingExpirationTimeWithKeyWithoutPrefAlgos() throws IOException, PGPException {
|
||||||
|
Date expirationDate = new Date();
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
||||||
|
List<OpenPgpV4Fingerprint> fingerprintList = new ArrayList<>();
|
||||||
|
for (PGPSecretKey secretKey : secretKeys) {
|
||||||
|
fingerprintList.add(new OpenPgpV4Fingerprint(secretKey));
|
||||||
|
}
|
||||||
|
SecretKeyRingProtector protector = new UnprotectedKeysProtector();
|
||||||
|
|
||||||
|
SecretKeyRingEditorInterface modify = PGPainless.modifyKeyRing(secretKeys)
|
||||||
|
.setExpirationDate(expirationDate, protector);
|
||||||
|
for (int i = 1; i < fingerprintList.size(); i++) {
|
||||||
|
modify.setExpirationDate(fingerprintList.get(i), expirationDate, protector);
|
||||||
|
}
|
||||||
|
secretKeys = modify.done();
|
||||||
|
|
||||||
|
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
|
||||||
|
assertEquals(expirationDate.getTime(), info.getExpirationDate().getTime(), 1000);
|
||||||
|
for (OpenPgpV4Fingerprint fingerprint : fingerprintList) {
|
||||||
|
assertEquals(expirationDate.getTime(), info.getExpirationDate(fingerprint).getTime(), 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
|
import org.pgpainless.key.generation.KeySpec;
|
||||||
|
import org.pgpainless.key.generation.type.KeyType;
|
||||||
|
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
||||||
|
import org.pgpainless.key.util.OpenPgpKeyAttributeUtil;
|
||||||
|
|
||||||
|
public class GuessPreferredHashAlgorithmTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, PGPException, IOException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
|
.withMasterKey(KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||||
|
.withKeyFlags(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
||||||
|
.withDetailedConfiguration()
|
||||||
|
// Do not specify preferred algorithms
|
||||||
|
.withPreferredSymmetricAlgorithms(new SymmetricKeyAlgorithm[] {})
|
||||||
|
.withPreferredHashAlgorithms(new HashAlgorithm[] {})
|
||||||
|
.withPreferredCompressionAlgorithms(new CompressionAlgorithm[] {})
|
||||||
|
|
||||||
|
.done())
|
||||||
|
.withPrimaryUserId("test@test.test")
|
||||||
|
.withoutPassphrase()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
PGPPublicKey publicKey = secretKeys.getPublicKey();
|
||||||
|
assertEquals(Collections.emptyList(),
|
||||||
|
OpenPgpKeyAttributeUtil.getPreferredHashAlgorithms(publicKey));
|
||||||
|
assertEquals(Collections.singletonList(HashAlgorithm.SHA512),
|
||||||
|
OpenPgpKeyAttributeUtil.guessPreferredHashAlgorithms(publicKey));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue