mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 10:19:39 +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 {
|
override fun addUserId(userId: CharSequence): KeyRingBuilder = apply {
|
||||||
userIds[userId.toString().trim()] = null
|
userIds[userId.toString()] = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addUserId(userId: ByteArray): KeyRingBuilder =
|
override fun addUserId(userId: ByteArray): KeyRingBuilder =
|
||||||
|
|
|
@ -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 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)
|
val bindingSig = reissueSubkeyBindingSignature(subkey, expiration, protector, prevBinding)
|
||||||
secretKeyRing = injectCertification(secretKeyRing, subkey, bindingSig)
|
secretKeyRing = injectCertification(secretKeyRing, subkey, bindingSig)
|
||||||
}
|
}
|
||||||
|
@ -569,9 +569,10 @@ class SecretKeyRingEditor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sanitizeUserId(userId: CharSequence): CharSequence =
|
private fun sanitizeUserId(userId: CharSequence): CharSequence =
|
||||||
// TODO: Further research how to sanitize user IDs.
|
// I'm not sure, what kind of sanitization is needed.
|
||||||
// e.g. what about newlines?
|
// Newlines are allowed, they just need to be escaped when emitted in an ASCII armor header
|
||||||
userId.toString().trim()
|
// Trailing/Leading whitespace is also fine.
|
||||||
|
userId.toString()
|
||||||
|
|
||||||
private fun callbackFromRevocationAttributes(attributes: RevocationAttributes?) =
|
private fun callbackFromRevocationAttributes(attributes: RevocationAttributes?) =
|
||||||
object : RevocationSignatureSubpackets.Callback {
|
object : RevocationSignatureSubpackets.Callback {
|
||||||
|
|
|
@ -247,7 +247,8 @@ 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.getOrPut(HEADER_COMMENT) { mutableSetOf() }.add(it)
|
headerMap.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) {
|
||||||
|
|
|
@ -11,14 +11,9 @@ import org.bouncycastle.util.Arrays
|
||||||
*
|
*
|
||||||
* @param chars may be null for empty passwords.
|
* @param chars may be null for empty passwords.
|
||||||
*/
|
*/
|
||||||
class Passphrase(chars: CharArray?) {
|
class Passphrase(private val 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
|
||||||
|
@ -67,6 +62,13 @@ class Passphrase(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 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -100,4 +100,14 @@ 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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue