mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 02:09:38 +02:00
Compare commits
3 commits
f2cbde43be
...
0d807cb6b8
Author | SHA1 | Date | |
---|---|---|---|
0d807cb6b8 | |||
9b0a3cd4c7 | |||
0ee31b232a |
5 changed files with 26 additions and 12 deletions
|
@ -45,7 +45,7 @@ class KeyRingBuilder : KeyRingBuilderInterface<KeyRingBuilder> {
|
|||
}
|
||||
|
||||
override fun addUserId(userId: CharSequence): KeyRingBuilder = apply {
|
||||
userIds[userId.toString().trim()] = null
|
||||
userIds[userId.toString()] = null
|
||||
}
|
||||
|
||||
override fun addUserId(userId: ByteArray): KeyRingBuilder =
|
||||
|
|
|
@ -478,7 +478,7 @@ class SecretKeyRingEditor(
|
|||
val prevBinding =
|
||||
inspectKeyRing(secretKeyRing).getCurrentSubkeyBindingSignature(keyId)
|
||||
?: throw NoSuchElementException(
|
||||
"Previous subkey binding signaure for ${keyId.openPgpKeyId()} MUST NOT be null.")
|
||||
"Previous subkey binding signature for ${keyId.openPgpKeyId()} MUST NOT be null.")
|
||||
val bindingSig = reissueSubkeyBindingSignature(subkey, expiration, protector, prevBinding)
|
||||
secretKeyRing = injectCertification(secretKeyRing, subkey, bindingSig)
|
||||
}
|
||||
|
@ -569,9 +569,10 @@ class SecretKeyRingEditor(
|
|||
}
|
||||
|
||||
private fun sanitizeUserId(userId: CharSequence): CharSequence =
|
||||
// TODO: Further research how to sanitize user IDs.
|
||||
// e.g. what about newlines?
|
||||
userId.toString().trim()
|
||||
// I'm not sure, what kind of sanitization is needed.
|
||||
// Newlines are allowed, they just need to be escaped when emitted in an ASCII armor header
|
||||
// Trailing/Leading whitespace is also fine.
|
||||
userId.toString()
|
||||
|
||||
private fun callbackFromRevocationAttributes(attributes: RevocationAttributes?) =
|
||||
object : RevocationSignatureSubpackets.Callback {
|
||||
|
|
|
@ -247,7 +247,8 @@ class ArmorUtils {
|
|||
.add(OpenPgpFingerprint.of(publicKey).prettyPrint())
|
||||
// Primary / First User ID
|
||||
(primary ?: first)?.let {
|
||||
headerMap.getOrPut(HEADER_COMMENT) { mutableSetOf() }.add(it)
|
||||
headerMap.getOrPut(HEADER_COMMENT) { mutableSetOf() }
|
||||
.add(it.replace("\n", "\\n").replace("\r", "\\r"))
|
||||
}
|
||||
// X-1 further identities
|
||||
when (userIds.size) {
|
||||
|
|
|
@ -11,14 +11,9 @@ import org.bouncycastle.util.Arrays
|
|||
*
|
||||
* @param chars may be null for empty passwords.
|
||||
*/
|
||||
class Passphrase(chars: CharArray?) {
|
||||
class Passphrase(private val chars: CharArray?) {
|
||||
private val lock = Any()
|
||||
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
|
||||
|
@ -67,6 +62,13 @@ class Passphrase(chars: CharArray?) {
|
|||
|
||||
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 {
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,4 +100,14 @@ public class GenerateKeyTest {
|
|||
assertThrows(SOPGPException.UnsupportedProfile.class, () ->
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue