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

pgpainless / pgpainless / #1074

20 Jan 2026 11:18PM UTC coverage: 85.293% (+0.09%) from 85.206%
#1074

push

github

vanitasvitae
Bump sop-java to 15.0.0

6774 of 7942 relevant lines covered (85.29%)

0.85 hits per line

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

78.05
/pgpainless-sop/src/main/kotlin/org/pgpainless/sop/UpdateKeyImpl.kt
1
// SPDX-FileCopyrightText: 2025 Paul Schaub <info@pgpainless.org>
2
//
3
// SPDX-License-Identifier: Apache-2.0
4

5
package org.pgpainless.sop
6

7
import java.io.InputStream
8
import java.io.OutputStream
9
import java.util.*
10
import org.bouncycastle.bcpg.KeyIdentifier
11
import org.bouncycastle.openpgp.PGPSecretKeyRing
12
import org.bouncycastle.openpgp.api.OpenPGPCertificate
13
import org.pgpainless.PGPainless
14
import org.pgpainless.key.modification.secretkeyring.OpenPGPKeyUpdater
15
import org.pgpainless.util.OpenPGPCertificateUtil
16
import sop.Ready
17
import sop.operation.UpdateKey
18

19
class UpdateKeyImpl(private val api: PGPainless) : UpdateKey {
1✔
20

21
    private var armor = true
1✔
22
    private var addCapabilities = true
1✔
23
    private var signingOnly = false
24
    private var revokeDeprecatedKeys = false
25
    private val protector: MatchMakingSecretKeyRingProtector = MatchMakingSecretKeyRingProtector()
1✔
26

27
    private val mergeCerts: MutableMap<KeyIdentifier, OpenPGPCertificate> = mutableMapOf()
1✔
28

29
    override fun key(key: InputStream): Ready {
30
        return object : Ready() {
1✔
31
            override fun writeTo(outputStream: OutputStream) {
32
                var keyList =
1✔
33
                    api.readKey().parseKeys(key).map {
1✔
34
                        // Merge keys
35
                        if (mergeCerts[it.keyIdentifier] == null) {
1✔
36
                            it
1✔
37
                        } else {
38
                            val updatedCert: OpenPGPCertificate =
1✔
39
                                api.mergeCertificate(
1✔
40
                                    it.toCertificate(), mergeCerts[it.keyIdentifier]!!)
1✔
41
                            api.toKey(
1✔
42
                                PGPSecretKeyRing.replacePublicKeys(
1✔
43
                                    it.pgpSecretKeyRing, updatedCert.pgpPublicKeyRing))
1✔
44
                        }
45
                    }
46

47
                // Update keys
48
                keyList =
1✔
49
                    keyList.map {
1✔
50
                        OpenPGPKeyUpdater(it, protector, api)
1✔
51
                            .replaceRejectedAlgorithmPreferencesAndFeatures(addCapabilities)
1✔
52
                            .replaceWeakSubkeys(revokeDeprecatedKeys, signingOnly)
1✔
53
                            .finish()
1✔
54
                    }
55

56
                if (armor) {
1✔
57
                    OpenPGPCertificateUtil.armor(keyList, outputStream)
1✔
58
                } else {
59
                    OpenPGPCertificateUtil.encode(keyList, outputStream)
×
60
                }
61
            }
1✔
62
        }
63
    }
64

65
    override fun mergeCerts(certs: InputStream): UpdateKey = apply {
1✔
66
        val certList = api.readKey().parseCertificates(certs)
1✔
67
        for (cert in certList) {
1✔
68
            if (mergeCerts[cert.keyIdentifier] == null) {
1✔
69
                mergeCerts[cert.keyIdentifier] = cert
1✔
70
            } else {
71
                val existing = mergeCerts[cert.keyIdentifier]!!
×
72
                mergeCerts[cert.keyIdentifier] = api.mergeCertificate(existing, cert)
×
73
            }
74
        }
75
    }
1✔
76

77
    override fun noAddedCapabilities(): UpdateKey = apply { addCapabilities = false }
×
78

79
    override fun noArmor(): UpdateKey = apply { armor = false }
×
80

81
    override fun revokeDeprecatedKeys(): UpdateKey = apply { revokeDeprecatedKeys = true }
×
82

83
    override fun signingOnly(): UpdateKey = apply { signingOnly = true }
1✔
84

85
    override fun withKeyPassword(password: ByteArray): UpdateKey = apply {
×
86
        PasswordHelper.addPassphrasePlusRemoveWhitespace(password, protector)
×
87
    }
×
88
}
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