1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-10 10:49:39 +02:00

Compare commits

..

No commits in common. "main" and "1.7.6" have entirely different histories.
main ... 1.7.6

14 changed files with 128 additions and 51 deletions

View file

@ -36,7 +36,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
language: [ 'java-kotlin' ] language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support # Learn more about CodeQL language support at https://git.io/codeql-language-support
@ -46,7 +46,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -57,7 +57,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v3 uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
@ -71,4 +71,4 @@ jobs:
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@v2

View file

@ -5,10 +5,6 @@ SPDX-License-Identifier: CC0-1.0
# PGPainless Changelog # PGPainless Changelog
## 1.7.7-SNAPSHOT
- Bump `bcpg-jdk8on` to `1.81`
- Bump `bcprov-jdk18on` to `1.81`
## 1.7.6 ## 1.7.6
- Fix `RevocationSignatureBuilder` properly calculating third-party signatures of type `KeyRevocation` (delegation revocations) - Fix `RevocationSignatureBuilder` properly calculating third-party signatures of type `KeyRevocation` (delegation revocations)
- Enable support for native images - Enable support for native images

View file

@ -93,12 +93,6 @@ precedence = "aggregate"
SPDX-FileCopyrightText = "2022 Paul Schaub <info@pgpainless.org>, 2017 Steve Smith" SPDX-FileCopyrightText = "2022 Paul Schaub <info@pgpainless.org>, 2017 Steve Smith"
SPDX-License-Identifier = "CC-BY-SA-3.0" SPDX-License-Identifier = "CC-BY-SA-3.0"
[[annotations]]
path = "pgpainless-cli/src/main/resources/META-INF/native-image/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2025 Paul Schaub <info@pgpainless.org>"
SPDX-License-Identifier = "Apache-2.0"
[[annotations]] [[annotations]]
path = "pgpainless-cli/rewriteManPages.sh" path = "pgpainless-cli/rewriteManPages.sh"
precedence = "aggregate" precedence = "aggregate"

View file

@ -43,7 +43,7 @@ allprojects {
// checkstyle // checkstyle
checkstyle { checkstyle {
toolVersion = '10.25.0' toolVersion = '10.12.1'
} }
spotless { spotless {

View file

@ -5,7 +5,7 @@
plugins { plugins {
id 'application' id 'application'
id 'org.graalvm.buildtools.native' version '0.10.6' id 'org.graalvm.buildtools.native' version '0.10.6'
id 'com.gradleup.shadow' version '8.3.6' id 'com.github.johnrengelman.shadow' version '8.1.1'
} }
graalvmNative { graalvmNative {

View file

@ -1,7 +1,16 @@
[ [
{
"name":"[B"
},
{ {
"name":"[Ljava.lang.Object;" "name":"[Ljava.lang.Object;"
}, },
{
"name":"[Ljava.lang.String;"
},
{
"name":"[Lsun.security.pkcs.SignerInfo;"
},
{ {
"name":"ch.qos.logback.classic.encoder.PatternLayoutEncoder", "name":"ch.qos.logback.classic.encoder.PatternLayoutEncoder",
"queryAllPublicMethods":true, "queryAllPublicMethods":true,
@ -61,6 +70,9 @@
{ {
"name":"java.lang.RuntimePermission" "name":"java.lang.RuntimePermission"
}, },
{
"name":"java.lang.String"
},
{ {
"name":"java.lang.System", "name":"java.lang.System",
"methods":[{"name":"console","parameterTypes":[] }] "methods":[{"name":"console","parameterTypes":[] }]
@ -89,6 +101,9 @@
"name":"java.nio.file.Paths", "name":"java.nio.file.Paths",
"methods":[{"name":"get","parameterTypes":["java.lang.String","java.lang.String[]"] }] "methods":[{"name":"get","parameterTypes":["java.lang.String","java.lang.String[]"] }]
}, },
{
"name":"java.security.AlgorithmParametersSpi"
},
{ {
"name":"java.security.AllPermission" "name":"java.security.AllPermission"
}, },
@ -104,6 +119,21 @@
{ {
"name":"java.security.cert.PKIXRevocationChecker" "name":"java.security.cert.PKIXRevocationChecker"
}, },
{
"name":"java.security.interfaces.DSAPrivateKey"
},
{
"name":"java.security.interfaces.DSAPublicKey"
},
{
"name":"java.security.interfaces.RSAPrivateKey"
},
{
"name":"java.security.interfaces.RSAPublicKey"
},
{
"name":"java.security.spec.DSAParameterSpec"
},
{ {
"name":"java.sql.Connection" "name":"java.sql.Connection"
}, },
@ -178,6 +208,9 @@
"name":"java.time.ZonedDateTime", "name":"java.time.ZonedDateTime",
"methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }]
}, },
{
"name":"java.util.Date"
},
{ {
"name":"java.util.HashSet" "name":"java.util.HashSet"
}, },
@ -212,6 +245,11 @@
{ {
"name":"java.util.concurrent.locks.ReentrantLock$Sync" "name":"java.util.concurrent.locks.ReentrantLock$Sync"
}, },
{
"name":"javax.security.auth.x500.X500Principal",
"fields":[{"name":"thisX500Name"}],
"methods":[{"name":"<init>","parameterTypes":["sun.security.x509.X500Name"] }]
},
{ {
"name":"javax.smartcardio.CardPermission" "name":"javax.smartcardio.CardPermission"
}, },
@ -295,10 +333,6 @@
"name":"org.bouncycastle.jcajce.provider.asymmetric.NTRU$Mappings", "name":"org.bouncycastle.jcajce.provider.asymmetric.NTRU$Mappings",
"methods":[{"name":"<init>","parameterTypes":[] }] "methods":[{"name":"<init>","parameterTypes":[] }]
}, },
{
"name":"org.bouncycastle.jcajce.provider.asymmetric.NoSig$Mappings",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{ {
"name":"org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings", "name":"org.bouncycastle.jcajce.provider.asymmetric.RSA$Mappings",
"methods":[{"name":"<init>","parameterTypes":[] }] "methods":[{"name":"<init>","parameterTypes":[] }]
@ -880,6 +914,18 @@
"queryAllDeclaredMethods":true, "queryAllDeclaredMethods":true,
"methods":[{"name":"<init>","parameterTypes":[] }] "methods":[{"name":"<init>","parameterTypes":[] }]
}, },
{
"name":"sun.security.provider.DSA$SHA256withDSA",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.provider.DSAKeyFactory",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.provider.DSAParameters",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{ {
"name":"sun.security.provider.NativePRNG", "name":"sun.security.provider.NativePRNG",
"methods":[{"name":"<init>","parameterTypes":[] }, {"name":"<init>","parameterTypes":["java.security.SecureRandomParameters"] }] "methods":[{"name":"<init>","parameterTypes":[] }, {"name":"<init>","parameterTypes":["java.security.SecureRandomParameters"] }]
@ -887,5 +933,59 @@
{ {
"name":"sun.security.provider.SHA", "name":"sun.security.provider.SHA",
"methods":[{"name":"<init>","parameterTypes":[] }] "methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.provider.SHA2$SHA256",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.provider.X509Factory",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.rsa.RSAKeyFactory$Legacy",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.rsa.RSASignature$SHA256withRSA",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.util.ObjectIdentifier"
},
{
"name":"sun.security.x509.AuthorityInfoAccessExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
},
{
"name":"sun.security.x509.AuthorityKeyIdentifierExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
},
{
"name":"sun.security.x509.BasicConstraintsExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
},
{
"name":"sun.security.x509.CRLDistributionPointsExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
},
{
"name":"sun.security.x509.CertificateExtensions"
},
{
"name":"sun.security.x509.CertificatePoliciesExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
},
{
"name":"sun.security.x509.ExtendedKeyUsageExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
},
{
"name":"sun.security.x509.KeyUsageExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
},
{
"name":"sun.security.x509.SubjectKeyIdentifierExtension",
"methods":[{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Object"] }]
} }
] ]

View file

@ -40,6 +40,8 @@
"pattern":"\\Qsop-java-version.properties\\E" "pattern":"\\Qsop-java-version.properties\\E"
}, { }, {
"pattern":"java.base:\\Qsun/text/resources/LineBreakIteratorData\\E" "pattern":"java.base:\\Qsun/text/resources/LineBreakIteratorData\\E"
}, {
"pattern":"java.base:\\Qsun/text/resources/nfkc.icu\\E"
}]}, }]},
"bundles":[{ "bundles":[{
"name":"msg_armor", "name":"msg_armor",

View file

@ -45,7 +45,7 @@ class KeyRingBuilder : KeyRingBuilderInterface<KeyRingBuilder> {
} }
override fun addUserId(userId: CharSequence): KeyRingBuilder = apply { override fun addUserId(userId: CharSequence): KeyRingBuilder = apply {
userIds[userId.toString()] = null userIds[userId.toString().trim()] = null
} }
override fun addUserId(userId: ByteArray): KeyRingBuilder = override fun addUserId(userId: ByteArray): KeyRingBuilder =

View file

@ -478,7 +478,7 @@ class SecretKeyRingEditor(
val prevBinding = val prevBinding =
inspectKeyRing(secretKeyRing).getCurrentSubkeyBindingSignature(keyId) inspectKeyRing(secretKeyRing).getCurrentSubkeyBindingSignature(keyId)
?: throw NoSuchElementException( ?: throw NoSuchElementException(
"Previous subkey binding signature for ${keyId.openPgpKeyId()} MUST NOT be null.") "Previous subkey binding signaure for ${keyId.openPgpKeyId()} MUST NOT be null.")
val bindingSig = reissueSubkeyBindingSignature(subkey, expiration, protector, prevBinding) val bindingSig = reissueSubkeyBindingSignature(subkey, expiration, protector, prevBinding)
secretKeyRing = injectCertification(secretKeyRing, subkey, bindingSig) secretKeyRing = injectCertification(secretKeyRing, subkey, bindingSig)
} }
@ -569,10 +569,9 @@ class SecretKeyRingEditor(
} }
private fun sanitizeUserId(userId: CharSequence): CharSequence = private fun sanitizeUserId(userId: CharSequence): CharSequence =
// I'm not sure, what kind of sanitization is needed. // TODO: Further research how to sanitize user IDs.
// Newlines are allowed, they just need to be escaped when emitted in an ASCII armor header // e.g. what about newlines?
// Trailing/Leading whitespace is also fine. userId.toString().trim()
userId.toString()
private fun callbackFromRevocationAttributes(attributes: RevocationAttributes?) = private fun callbackFromRevocationAttributes(attributes: RevocationAttributes?) =
object : RevocationSignatureSubpackets.Callback { object : RevocationSignatureSubpackets.Callback {

View file

@ -247,9 +247,7 @@ class ArmorUtils {
.add(OpenPgpFingerprint.of(publicKey).prettyPrint()) .add(OpenPgpFingerprint.of(publicKey).prettyPrint())
// Primary / First User ID // Primary / First User ID
(primary ?: first)?.let { (primary ?: first)?.let {
headerMap headerMap.getOrPut(HEADER_COMMENT) { mutableSetOf() }.add(it)
.getOrPut(HEADER_COMMENT) { mutableSetOf() }
.add(it.replace("\n", "\\n").replace("\r", "\\r"))
} }
// X-1 further identities // X-1 further identities
when (userIds.size) { when (userIds.size) {

View file

@ -11,9 +11,14 @@ import org.bouncycastle.util.Arrays
* *
* @param chars may be null for empty passwords. * @param chars may be null for empty passwords.
*/ */
class Passphrase(private val chars: CharArray?) { class Passphrase(chars: CharArray?) {
private val lock = Any() private val lock = Any()
private var valid = true private var valid = true
private val chars: CharArray?
init {
this.chars = trimWhitespace(chars)
}
/** /**
* Return a copy of the underlying char array. A return value of null represents an empty * Return a copy of the underlying char array. A return value of null represents an empty
@ -62,13 +67,6 @@ class Passphrase(private val chars: CharArray?) {
override fun hashCode(): Int = getChars()?.let { String(it) }.hashCode() override fun hashCode(): Int = getChars()?.let { String(it) }.hashCode()
/**
* Return a copy of this [Passphrase], but with whitespace characters trimmed off.
*
* @return copy with trimmed whitespace
*/
fun withTrimmedWhitespace(): Passphrase = Passphrase(trimWhitespace(chars))
companion object { companion object {
/** /**

View file

@ -67,7 +67,7 @@ byte[] encrypted = sop.encrypt()
// Decrypt a message // Decrypt a message
ByteArrayAndResult<DecryptionResult> messageAndVerifications = sop.decrypt() ByteArrayAndResult<DecryptionResult> messageAndVerifications = sop.decrypt()
.verifyWithCert(cert) .verifyWith(cert)
.withKey(key) .withKey(key)
.ciphertext(encrypted) .ciphertext(encrypted)
.toByteArrayAndResult(); .toByteArrayAndResult();

View file

@ -100,14 +100,4 @@ public class GenerateKeyTest {
assertThrows(SOPGPException.UnsupportedProfile.class, () -> assertThrows(SOPGPException.UnsupportedProfile.class, () ->
sop.generateKey().profile("invalid")); sop.generateKey().profile("invalid"));
} }
@Test
public void generateKeyWithNewlinesInUserId() throws IOException {
byte[] keyBytes = sop.generateKey()
.userId("Foo\n\nBar")
.generate()
.getBytes();
assertTrue(new String(keyBytes).contains("Foo\\n\\nBar"));
}
} }

View file

@ -4,10 +4,10 @@
allprojects { allprojects {
ext { ext {
shortVersion = '1.7.7' shortVersion = '1.7.6'
isSnapshot = true isSnapshot = false
javaSourceCompatibility = 11 javaSourceCompatibility = 11
bouncyCastleVersion = '1.81' bouncyCastleVersion = '1.80'
bouncyPgVersion = bouncyCastleVersion bouncyPgVersion = bouncyCastleVersion
junitVersion = '5.8.2' junitVersion = '5.8.2'
logbackVersion = '1.5.13' logbackVersion = '1.5.13'