aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/GpgIdentifier.kt48
-rw-r--r--detekt-baselines/crypto-pgpainless.xml7
2 files changed, 33 insertions, 22 deletions
diff --git a/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/GpgIdentifier.kt b/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/GpgIdentifier.kt
index 4aa4a57a..29d1fa42 100644
--- a/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/GpgIdentifier.kt
+++ b/crypto-pgpainless/src/main/kotlin/app/passwordstore/crypto/GpgIdentifier.kt
@@ -16,7 +16,7 @@ public sealed class GpgIdentifier {
/** Convert a [Long] key ID to a formatted string. */
private fun convertKeyIdToHex(keyId: Long): String {
- return convertKeyIdToHex32bit(keyId shr 32) + convertKeyIdToHex32bit(keyId)
+ return convertKeyIdToHex32bit(keyId shr HEX_32_BIT_COUNT) + convertKeyIdToHex32bit(keyId)
}
/**
@@ -24,8 +24,8 @@ public sealed class GpgIdentifier {
* to a lowercase hex ID.
*/
private fun convertKeyIdToHex32bit(keyId: Long): String {
- var hexString = java.lang.Long.toHexString(keyId and 0xffffffffL).lowercase(Locale.ENGLISH)
- while (hexString.length < 8) {
+ var hexString = java.lang.Long.toHexString(keyId and HEX_32_BITMASK).lowercase(Locale.ENGLISH)
+ while (hexString.length < HEX_32_STRING_LENGTH) {
hexString = "0$hexString"
}
return hexString
@@ -38,6 +38,13 @@ public sealed class GpgIdentifier {
}
public companion object {
+ private const val HEX_RADIX = 16
+ private const val HEX_32_BIT_COUNT = 32
+ private const val HEX_32_BITMASK = 0xffffffffL
+ private const val HEX_32_STRING_LENGTH = 8
+ private const val TRUNCATED_FINGERPRINT_LENGTH = 16
+
+ @Suppress("ReturnCount")
public fun fromString(identifier: String): GpgIdentifier? {
if (identifier.isEmpty()) return null
// Match long key IDs:
@@ -45,7 +52,7 @@ public sealed class GpgIdentifier {
val maybeLongKeyId =
identifier.removePrefix("0x").takeIf { it.matches("[a-fA-F\\d]{16}".toRegex()) }
if (maybeLongKeyId != null) {
- val keyId = maybeLongKeyId.toULong(16)
+ val keyId = maybeLongKeyId.toULong(HEX_RADIX)
return KeyId(keyId.toLong())
}
@@ -57,37 +64,48 @@ public sealed class GpgIdentifier {
// Truncating to the long key ID is not a security issue since OpenKeychain only
// accepts
// non-ambiguous key IDs.
- val keyId = maybeFingerprint.takeLast(16).toULong(16)
+ val keyId = maybeFingerprint.takeLast(TRUNCATED_FINGERPRINT_LENGTH).toULong(HEX_RADIX)
return KeyId(keyId.toLong())
}
return splitUserId(identifier)?.let { UserId(it) }
}
- private val USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$")
- private val EMAIL_PATTERN = Pattern.compile("^<?\"?([^<>\"]*@[^<>\"]*[.]?[^<>\"]*)\"?>?$")
+ private object UserIdRegex {
+ val PATTERN: Pattern = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$")
+ const val NAME = 1
+ const val EMAIL = 3
+ }
+
+ private object EmailRegex {
+ val PATTERN: Pattern = Pattern.compile("^<?\"?([^<>\"]*@[^<>\"]*[.]?[^<>\"]*)\"?>?$")
+ const val EMAIL = 1
+ }
/**
* Takes a 'Name (Comment) <Email>' user ID in any of its permutations and attempts to extract
* an email from it.
*/
+ @Suppress("NestedBlockDepth")
private fun splitUserId(userId: String): String? {
if (userId.isNotEmpty()) {
- val matcher = USER_ID_PATTERN.matcher(userId)
+ val matcher = UserIdRegex.PATTERN.matcher(userId)
if (matcher.matches()) {
- var name = if (matcher.group(1)?.isEmpty() == true) null else matcher.group(1)
- var email = matcher.group(3)
+ var name =
+ if (matcher.group(UserIdRegex.NAME)?.isEmpty() == true) null
+ else matcher.group(UserIdRegex.NAME)
+ var email = matcher.group(UserIdRegex.EMAIL)
if (email != null && name != null) {
- val emailMatcher = EMAIL_PATTERN.matcher(name)
- if (emailMatcher.matches() && email == emailMatcher.group(1)) {
- email = emailMatcher.group(1)
+ val emailMatcher = EmailRegex.PATTERN.matcher(name)
+ if (emailMatcher.matches() && email == emailMatcher.group(EmailRegex.EMAIL)) {
+ email = emailMatcher.group(EmailRegex.EMAIL)
name = null
}
}
if (email == null && name != null) {
- val emailMatcher = EMAIL_PATTERN.matcher(name)
+ val emailMatcher = EmailRegex.PATTERN.matcher(name)
if (emailMatcher.matches()) {
- email = emailMatcher.group(1)
+ email = emailMatcher.group(EmailRegex.EMAIL)
}
}
return email
diff --git a/detekt-baselines/crypto-pgpainless.xml b/detekt-baselines/crypto-pgpainless.xml
index 0276df1b..c3e6912d 100644
--- a/detekt-baselines/crypto-pgpainless.xml
+++ b/detekt-baselines/crypto-pgpainless.xml
@@ -3,12 +3,5 @@
<ManuallySuppressedIssues/>
<CurrentIssues>
<ID>ForbiddenComment:PGPKeyManager.kt$PGPKeyManager$// TODO: This is a temp hack for now and in future it should check that the GPGKeyManager can</ID>
- <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.Companion$16</ID>
- <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.Companion$3</ID>
- <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$0xffffffffL</ID>
- <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$32</ID>
- <ID>MagicNumber:GpgIdentifier.kt$GpgIdentifier.KeyId$8</ID>
- <ID>NestedBlockDepth:GpgIdentifier.kt$GpgIdentifier.Companion$private fun splitUserId(userId: String): String?</ID>
- <ID>ReturnCount:GpgIdentifier.kt$GpgIdentifier.Companion$public fun fromString(identifier: String): GpgIdentifier?</ID>
</CurrentIssues>
</SmellBaseline>