• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pgpainless / pgpainless / #1050

20 Mar 2025 05:18PM UTC coverage: 86.822% (-2.3%) from 89.121%
#1050

push

github

vanitasvitae
Perform coveralls task after jacocoRootReport

6575 of 7573 relevant lines covered (86.82%)

0.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.86
/pgpainless-core/src/main/java/org/pgpainless/key/util/OpenPgpKeyAttributeUtil.java
1
// SPDX-FileCopyrightText: 2020 Paul Schaub <vanitasvitae@fsfe.org>
2
//
3
// SPDX-License-Identifier: Apache-2.0
4

5
package org.pgpainless.key.util;
6

7
import java.util.ArrayList;
8
import java.util.Collections;
9
import java.util.Date;
10
import java.util.Iterator;
11
import java.util.LinkedHashSet;
12
import java.util.List;
13
import java.util.Set;
14

15
import org.bouncycastle.openpgp.PGPPublicKey;
16
import org.bouncycastle.openpgp.PGPSignature;
17
import org.pgpainless.algorithm.HashAlgorithm;
18
import org.pgpainless.algorithm.SignatureType;
19

20
public final class OpenPgpKeyAttributeUtil {
21

22
    private OpenPgpKeyAttributeUtil() {
23

24
    }
25

26
    public static List<HashAlgorithm> getPreferredHashAlgorithms(PGPPublicKey publicKey) {
27
        List<HashAlgorithm> hashAlgorithms = new ArrayList<>();
1✔
28
        Iterator<?> keySignatures = publicKey.getSignatures();
1✔
29
        while (keySignatures.hasNext()) {
1✔
30
            PGPSignature signature = (PGPSignature) keySignatures.next();
1✔
31

32
            if (signature.getKeyID() != publicKey.getKeyID()) {
1✔
33
                // Signature from a foreign key. Skip.
34
                continue;
×
35
            }
36

37
            SignatureType signatureType = SignatureType.fromCode(signature.getSignatureType());
1✔
38
            if (signatureType == null) {
1✔
39
                // unknown signature type
40
                continue;
×
41
            }
42
            if (signatureType == SignatureType.POSITIVE_CERTIFICATION
1✔
43
                    || signatureType == SignatureType.GENERIC_CERTIFICATION) {
44
                int[] hashAlgos = signature.getHashedSubPackets().getPreferredHashAlgorithms();
1✔
45
                if (hashAlgos == null) {
1✔
46
                    continue;
1✔
47
                }
48
                for (int h : hashAlgos) {
1✔
49
                    HashAlgorithm algorithm = HashAlgorithm.fromId(h);
1✔
50
                    if (algorithm != null) {
1✔
51
                        hashAlgorithms.add(algorithm);
1✔
52
                    }
53
                }
54
                // Exit the loop after the first key signature with hash algorithms.
55
                break;
1✔
56
            }
57
        }
1✔
58
        return hashAlgorithms;
1✔
59
    }
60

61
    /**
62
     * Return the hash algorithm that was used in the latest self signature.
63
     *
64
     * @param publicKey public key
65
     * @return list of hash algorithm
66
     */
67
    public static List<HashAlgorithm> guessPreferredHashAlgorithms(PGPPublicKey publicKey) {
68
        HashAlgorithm hashAlgorithm = null;
1✔
69
        Date lastCreationDate = null;
1✔
70

71
        Iterator<?> keySignatures = publicKey.getSignatures();
1✔
72
        while (keySignatures.hasNext()) {
1✔
73
            PGPSignature signature = (PGPSignature) keySignatures.next();
1✔
74
            if (signature.getKeyID() != publicKey.getKeyID()) {
1✔
75
                continue;
×
76
            }
77

78
            SignatureType signatureType = SignatureType.fromCode(signature.getSignatureType());
1✔
79
            if (signatureType == null || signatureType != SignatureType.POSITIVE_CERTIFICATION
1✔
80
                    && signatureType != SignatureType.GENERIC_CERTIFICATION) {
81
                continue;
1✔
82
            }
83

84
            Date creationDate = signature.getCreationTime();
1✔
85
            if (lastCreationDate == null || lastCreationDate.before(creationDate)) {
1✔
86
                lastCreationDate = creationDate;
1✔
87
                hashAlgorithm = HashAlgorithm.fromId(signature.getHashAlgorithm());
1✔
88
            }
89
        }
1✔
90

91
        if (hashAlgorithm == null) {
1✔
92
            return Collections.emptyList();
1✔
93
        }
94
        return Collections.singletonList(hashAlgorithm);
1✔
95
    }
96

97
    /**
98
     * Try to extract hash algorithm preferences from self signatures.
99
     * If no self-signature containing hash algorithm preferences is found,
100
     * try to derive a hash algorithm preference by inspecting the hash algorithm used by existing
101
     * self-signatures.
102
     *
103
     * @param publicKey key
104
     * @return hash algorithm preferences (might be empty!)
105
     */
106
    public static Set<HashAlgorithm> getOrGuessPreferredHashAlgorithms(PGPPublicKey publicKey) {
107
        List<HashAlgorithm> preferredHashAlgorithms = OpenPgpKeyAttributeUtil.getPreferredHashAlgorithms(publicKey);
1✔
108
        if (preferredHashAlgorithms.isEmpty()) {
1✔
109
            preferredHashAlgorithms = OpenPgpKeyAttributeUtil.guessPreferredHashAlgorithms(publicKey);
1✔
110
        }
111
        return new LinkedHashSet<>(preferredHashAlgorithms);
1✔
112
    }
113
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc