aboutsummaryrefslogtreecommitdiff
path: root/openpgp-ktx/src/main/java/me/msfjarvis
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2021-03-09 14:53:11 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2021-03-18 11:40:30 +0530
commit774fda83ac276a635e3402034b1eedbd10be916f (patch)
tree57783a953fcd193d32f1e3dc8df26e07f03df328 /openpgp-ktx/src/main/java/me/msfjarvis
parentbe31ae37f443982b377d027cd613f04d0926568d (diff)
all: reformat with ktfmt
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
Diffstat (limited to 'openpgp-ktx/src/main/java/me/msfjarvis')
-rw-r--r--openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/AutocryptPeerUpdate.kt174
-rw-r--r--openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpApi.kt693
-rw-r--r--openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpServiceConnection.kt118
-rw-r--r--openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpUtils.kt165
-rw-r--r--openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/ParcelFileDescriptorUtil.kt83
5 files changed, 583 insertions, 650 deletions
diff --git a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/AutocryptPeerUpdate.kt b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/AutocryptPeerUpdate.kt
index 2f610b3e..e6a189b9 100644
--- a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/AutocryptPeerUpdate.kt
+++ b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/AutocryptPeerUpdate.kt
@@ -11,99 +11,93 @@ import java.util.Date
public class AutocryptPeerUpdate() : Parcelable {
- private var keyData: ByteArray? = null
- private var effectiveDate: Date? = null
- private lateinit var preferEncrypt: PreferEncrypt
-
- internal constructor(
- keyData: ByteArray?,
- effectiveDate: Date?,
- preferEncrypt: PreferEncrypt
- ) : this() {
- this.keyData = keyData
- this.effectiveDate = effectiveDate
- this.preferEncrypt = preferEncrypt
+ private var keyData: ByteArray? = null
+ private var effectiveDate: Date? = null
+ private lateinit var preferEncrypt: PreferEncrypt
+
+ internal constructor(keyData: ByteArray?, effectiveDate: Date?, preferEncrypt: PreferEncrypt) : this() {
+ this.keyData = keyData
+ this.effectiveDate = effectiveDate
+ this.preferEncrypt = preferEncrypt
+ }
+
+ private constructor(source: Parcel, version: Int) : this() {
+ keyData = source.createByteArray()
+ effectiveDate = if (source.readInt() != 0) Date(source.readLong()) else null
+ preferEncrypt = PreferEncrypt.values()[source.readInt()]
+ }
+
+ public fun createAutocryptPeerUpdate(keyData: ByteArray?, timestamp: Date?): AutocryptPeerUpdate {
+ return AutocryptPeerUpdate(keyData, timestamp, PreferEncrypt.NOPREFERENCE)
+ }
+
+ public fun getKeyData(): ByteArray? {
+ return keyData
+ }
+
+ public fun hasKeyData(): Boolean {
+ return keyData != null
+ }
+
+ public fun getEffectiveDate(): Date? {
+ return effectiveDate
+ }
+
+ public fun getPreferEncrypt(): PreferEncrypt? {
+ return preferEncrypt
+ }
+
+ override fun describeContents(): Int {
+ return 0
+ }
+
+ override fun writeToParcel(dest: Parcel, flags: Int) {
+ /**
+ * NOTE: When adding fields in the process of updating this API, make sure to bump
+ * [.PARCELABLE_VERSION].
+ */
+ dest.writeInt(PARCELABLE_VERSION)
+ // Inject a placeholder that will store the parcel size from this point on
+ // (not including the size itself).
+ val sizePosition = dest.dataPosition()
+ dest.writeInt(0)
+ val startPosition = dest.dataPosition()
+ // version 1
+ dest.writeByteArray(keyData)
+ if (effectiveDate != null) {
+ dest.writeInt(1)
+ dest.writeLong(effectiveDate!!.time)
+ } else {
+ dest.writeInt(0)
}
-
- private constructor(source: Parcel, version: Int) : this() {
- keyData = source.createByteArray()
- effectiveDate = if (source.readInt() != 0) Date(source.readLong()) else null
- preferEncrypt = PreferEncrypt.values()[source.readInt()]
- }
-
- public fun createAutocryptPeerUpdate(
- keyData: ByteArray?,
- timestamp: Date?
- ): AutocryptPeerUpdate {
- return AutocryptPeerUpdate(keyData, timestamp, PreferEncrypt.NOPREFERENCE)
- }
-
- public fun getKeyData(): ByteArray? {
- return keyData
- }
-
- public fun hasKeyData(): Boolean {
- return keyData != null
- }
-
- public fun getEffectiveDate(): Date? {
- return effectiveDate
- }
-
- public fun getPreferEncrypt(): PreferEncrypt? {
- return preferEncrypt
- }
-
- override fun describeContents(): Int {
- return 0
- }
-
- override fun writeToParcel(dest: Parcel, flags: Int) {
- /**
- * NOTE: When adding fields in the process of updating this API, make sure to bump
- * [.PARCELABLE_VERSION].
- */
- dest.writeInt(PARCELABLE_VERSION)
- // Inject a placeholder that will store the parcel size from this point on
- // (not including the size itself).
- val sizePosition = dest.dataPosition()
- dest.writeInt(0)
- val startPosition = dest.dataPosition()
- // version 1
- dest.writeByteArray(keyData)
- if (effectiveDate != null) {
- dest.writeInt(1)
- dest.writeLong(effectiveDate!!.time)
- } else {
- dest.writeInt(0)
- }
- dest.writeInt(preferEncrypt.ordinal)
- // Go back and write the size
- val parcelableSize = dest.dataPosition() - startPosition
- dest.setDataPosition(sizePosition)
- dest.writeInt(parcelableSize)
- dest.setDataPosition(startPosition + parcelableSize)
+ dest.writeInt(preferEncrypt.ordinal)
+ // Go back and write the size
+ val parcelableSize = dest.dataPosition() - startPosition
+ dest.setDataPosition(sizePosition)
+ dest.writeInt(parcelableSize)
+ dest.setDataPosition(startPosition + parcelableSize)
+ }
+
+ public companion object CREATOR : Creator<AutocryptPeerUpdate> {
+
+ private const val PARCELABLE_VERSION = 1
+ override fun createFromParcel(source: Parcel): AutocryptPeerUpdate? {
+ val version = source.readInt() // parcelableVersion
+ val parcelableSize = source.readInt()
+ val startPosition = source.dataPosition()
+ val vr = AutocryptPeerUpdate(source, version)
+ // skip over all fields added in future versions of this parcel
+ source.setDataPosition(startPosition + parcelableSize)
+ return vr
}
- public companion object CREATOR : Creator<AutocryptPeerUpdate> {
-
- private const val PARCELABLE_VERSION = 1
- override fun createFromParcel(source: Parcel): AutocryptPeerUpdate? {
- val version = source.readInt() // parcelableVersion
- val parcelableSize = source.readInt()
- val startPosition = source.dataPosition()
- val vr = AutocryptPeerUpdate(source, version)
- // skip over all fields added in future versions of this parcel
- source.setDataPosition(startPosition + parcelableSize)
- return vr
- }
-
- override fun newArray(size: Int): Array<AutocryptPeerUpdate?>? {
- return arrayOfNulls(size)
- }
+ override fun newArray(size: Int): Array<AutocryptPeerUpdate?>? {
+ return arrayOfNulls(size)
}
+ }
- public enum class PreferEncrypt {
- NOPREFERENCE, MUTUAL
- }
+ public enum class PreferEncrypt {
+ NOPREFERENCE,
+ MUTUAL
+ }
}
diff --git a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpApi.kt b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpApi.kt
index 5badc0c8..aa5a2f84 100644
--- a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpApi.kt
+++ b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpApi.kt
@@ -21,382 +21,335 @@ import org.openintents.openpgp.OpenPgpError
public class OpenPgpApi(private val context: Context, private val service: IOpenPgpService2) {
- private val pipeIdGen: AtomicInteger = AtomicInteger()
-
- public suspend fun executeApiAsync(
- data: Intent?,
- inputStream: InputStream?,
- outputStream: OutputStream?,
- callback: (intent: Intent?) -> Unit
- ) {
- val result = executeApi(data, inputStream, outputStream)
- withContext(Dispatchers.Main) {
- callback.invoke(result)
+ private val pipeIdGen: AtomicInteger = AtomicInteger()
+
+ public suspend fun executeApiAsync(
+ data: Intent?,
+ inputStream: InputStream?,
+ outputStream: OutputStream?,
+ callback: (intent: Intent?) -> Unit
+ ) {
+ val result = executeApi(data, inputStream, outputStream)
+ withContext(Dispatchers.Main) { callback.invoke(result) }
+ }
+
+ public fun executeApi(data: Intent?, inputStream: InputStream?, outputStream: OutputStream?): Intent? {
+ var input: ParcelFileDescriptor? = null
+ return try {
+ if (inputStream != null) {
+ input = ParcelFileDescriptorUtil.pipeFrom(inputStream)
+ }
+ executeApi(data, input, outputStream)
+ } catch (e: Exception) {
+ Log.e(TAG, "Exception in executeApi call", e)
+ val result = Intent()
+ result.putExtra(RESULT_CODE, RESULT_CODE_ERROR)
+ result.putExtra(RESULT_ERROR, OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.message))
+ result
+ } finally {
+ if (input != null) {
+ try {
+ input.close()
+ } catch (e: IOException) {
+ Log.e(TAG, "IOException when closing ParcelFileDescriptor!", e)
}
+ }
}
-
- public fun executeApi(data: Intent?, inputStream: InputStream?, outputStream: OutputStream?): Intent? {
- var input: ParcelFileDescriptor? = null
- return try {
- if (inputStream != null) {
- input = ParcelFileDescriptorUtil.pipeFrom(inputStream)
- }
- executeApi(data, input, outputStream)
- } catch (e: Exception) {
- Log.e(TAG, "Exception in executeApi call", e)
- val result = Intent()
- result.putExtra(RESULT_CODE, RESULT_CODE_ERROR)
- result.putExtra(
- RESULT_ERROR,
- OpenPgpError(
- OpenPgpError.CLIENT_SIDE_ERROR,
- e.message
- )
- )
- result
- } finally {
- if (input != null) {
- try {
- input.close()
- } catch (e: IOException) {
- Log.e(TAG, "IOException when closing ParcelFileDescriptor!", e)
- }
- }
+ }
+
+ /** InputStream and OutputStreams are always closed after operating on them! */
+ private fun executeApi(data: Intent?, input: ParcelFileDescriptor?, os: OutputStream?): Intent? {
+ var output: ParcelFileDescriptor? = null
+ return try {
+ // always send version from client
+ data?.putExtra(EXTRA_API_VERSION, API_VERSION)
+ val result: Intent
+ var pumpThread: Thread? = null
+ var outputPipeId = 0
+ if (os != null) {
+ outputPipeId = pipeIdGen.incrementAndGet()
+ output = service.createOutputPipe(outputPipeId)
+ pumpThread = ParcelFileDescriptorUtil.pipeTo(os, output)
+ }
+ // blocks until result is ready
+ result = service.execute(data, input, outputPipeId)
+ // set class loader to current context to allow unparcelling
+ // of OpenPgpError and OpenPgpSignatureResult
+ // http://stackoverflow.com/a/3806769
+ result.setExtrasClassLoader(context.classLoader)
+ // wait for ALL data being pumped from remote side
+ pumpThread?.join()
+ result
+ } catch (e: Exception) {
+ Log.e(TAG, "Exception in executeApi call", e)
+ val result = Intent()
+ result.putExtra(RESULT_CODE, RESULT_CODE_ERROR)
+ result.putExtra(RESULT_ERROR, OpenPgpError(OpenPgpError.CLIENT_SIDE_ERROR, e.message))
+ result
+ } finally {
+ // close() is required to halt the TransferThread
+ if (output != null) {
+ try {
+ output.close()
+ } catch (e: IOException) {
+ Log.e(TAG, "IOException when closing ParcelFileDescriptor!", e)
}
+ }
}
+ }
+
+ public companion object {
+
+ private const val TAG = "OpenPgp API"
+
+ public const val SERVICE_INTENT_2: String = "org.openintents.openpgp.IOpenPgpService2"
+
+ /** see CHANGELOG.md */
+ public const val API_VERSION: Int = 11
/**
- * InputStream and OutputStreams are always closed after operating on them!
+ * General extras --------------
+ *
+ * required extras: int EXTRA_API_VERSION (always required)
+ *
+ * returned extras: int RESULT_CODE (RESULT_CODE_ERROR, RESULT_CODE_SUCCESS or
+ * RESULT_CODE_USER_INTERACTION_REQUIRED) OpenPgpError RESULT_ERROR (if RESULT_CODE ==
+ * RESULT_CODE_ERROR) PendingIntent RESULT_INTENT (if RESULT_CODE ==
+ * RESULT_CODE_USER_INTERACTION_REQUIRED)
*/
- private fun executeApi(
- data: Intent?,
- input: ParcelFileDescriptor?,
- os: OutputStream?
- ): Intent? {
- var output: ParcelFileDescriptor? = null
- return try {
- // always send version from client
- data?.putExtra(EXTRA_API_VERSION, API_VERSION)
- val result: Intent
- var pumpThread: Thread? = null
- var outputPipeId = 0
- if (os != null) {
- outputPipeId = pipeIdGen.incrementAndGet()
- output = service.createOutputPipe(outputPipeId)
- pumpThread = ParcelFileDescriptorUtil.pipeTo(os, output)
- }
- // blocks until result is ready
- result = service.execute(data, input, outputPipeId)
- // set class loader to current context to allow unparcelling
- // of OpenPgpError and OpenPgpSignatureResult
- // http://stackoverflow.com/a/3806769
- result.setExtrasClassLoader(context.classLoader)
- // wait for ALL data being pumped from remote side
- pumpThread?.join()
- result
- } catch (e: Exception) {
- Log.e(TAG, "Exception in executeApi call", e)
- val result = Intent()
- result.putExtra(RESULT_CODE, RESULT_CODE_ERROR)
- result.putExtra(
- RESULT_ERROR,
- OpenPgpError(
- OpenPgpError.CLIENT_SIDE_ERROR,
- e.message
- )
- )
- result
- } finally {
- // close() is required to halt the TransferThread
- if (output != null) {
- try {
- output.close()
- } catch (e: IOException) {
- Log.e(TAG, "IOException when closing ParcelFileDescriptor!", e)
- }
- }
- }
- }
- public companion object {
-
- private const val TAG = "OpenPgp API"
-
- public const val SERVICE_INTENT_2: String = "org.openintents.openpgp.IOpenPgpService2"
-
- /**
- * see CHANGELOG.md
- */
- public const val API_VERSION: Int = 11
-
- /**
- * General extras
- * --------------
- *
- * required extras:
- * int EXTRA_API_VERSION (always required)
- *
- * returned extras:
- * int RESULT_CODE (RESULT_CODE_ERROR, RESULT_CODE_SUCCESS or RESULT_CODE_USER_INTERACTION_REQUIRED)
- * OpenPgpError RESULT_ERROR (if RESULT_CODE == RESULT_CODE_ERROR)
- * PendingIntent RESULT_INTENT (if RESULT_CODE == RESULT_CODE_USER_INTERACTION_REQUIRED)
- */
-
- /**
- * General extras
- * --------------
- *
- * required extras:
- * int EXTRA_API_VERSION (always required)
- *
- * returned extras:
- * int RESULT_CODE (RESULT_CODE_ERROR, RESULT_CODE_SUCCESS or RESULT_CODE_USER_INTERACTION_REQUIRED)
- * OpenPgpError RESULT_ERROR (if RESULT_CODE == RESULT_CODE_ERROR)
- * PendingIntent RESULT_INTENT (if RESULT_CODE == RESULT_CODE_USER_INTERACTION_REQUIRED)
- */
- /**
- * This action performs no operation, but can be used to check if the App has permission
- * to access the API in general, returning a user interaction PendingIntent otherwise.
- * This can be used to trigger the permission dialog explicitly.
- *
- * This action uses no extras.
- */
- public const val ACTION_CHECK_PERMISSION: String = "org.openintents.openpgp.action.CHECK_PERMISSION"
-
- /**
- * Sign text resulting in a cleartext signature
- * Some magic pre-processing of the text is done to convert it to a format usable for
- * cleartext signatures per RFC 4880 before the text is actually signed:
- * - end cleartext with newline
- * - remove whitespaces on line endings
- *
- * required extras:
- * long EXTRA_SIGN_KEY_ID (key id of signing key)
- *
- * optional extras:
- * char[] EXTRA_PASSPHRASE (key passphrase)
- */
- public const val ACTION_CLEARTEXT_SIGN: String = "org.openintents.openpgp.action.CLEARTEXT_SIGN"
-
- /**
- * Sign text or binary data resulting in a detached signature.
- * No OutputStream necessary for ACTION_DETACHED_SIGN (No magic pre-processing like in ACTION_CLEARTEXT_SIGN)!
- * The detached signature is returned separately in RESULT_DETACHED_SIGNATURE.
- *
- * required extras:
- * long EXTRA_SIGN_KEY_ID (key id of signing key)
- *
- * optional extras:
- * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for detached signature)
- * char[] EXTRA_PASSPHRASE (key passphrase)
- *
- * returned extras:
- * byte[] RESULT_DETACHED_SIGNATURE
- * String RESULT_SIGNATURE_MICALG (contains the name of the used signature algorithm as a string)
- */
- public const val ACTION_DETACHED_SIGN: String = "org.openintents.openpgp.action.DETACHED_SIGN"
-
- /**
- * Encrypt
- *
- * required extras:
- * String[] EXTRA_USER_IDS (=emails of recipients, if more than one key has a user_id, a PendingIntent is returned via RESULT_INTENT)
- * or
- * long[] EXTRA_KEY_IDS
- *
- * optional extras:
- * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for output)
- * char[] EXTRA_PASSPHRASE (key passphrase)
- * String EXTRA_ORIGINAL_FILENAME (original filename to be encrypted as metadata)
- * boolean EXTRA_ENABLE_COMPRESSION (enable ZLIB compression, default ist true)
- */
- public const val ACTION_ENCRYPT: String = "org.openintents.openpgp.action.ENCRYPT"
-
- /**
- * Sign and encrypt
- *
- * required extras:
- * String[] EXTRA_USER_IDS (=emails of recipients, if more than one key has a user_id, a PendingIntent is returned via RESULT_INTENT)
- * or
- * long[] EXTRA_KEY_IDS
- *
- * optional extras:
- * long EXTRA_SIGN_KEY_ID (key id of signing key)
- * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for output)
- * char[] EXTRA_PASSPHRASE (key passphrase)
- * String EXTRA_ORIGINAL_FILENAME (original filename to be encrypted as metadata)
- * boolean EXTRA_ENABLE_COMPRESSION (enable ZLIB compression, default ist true)
- */
- public const val ACTION_SIGN_AND_ENCRYPT: String = "org.openintents.openpgp.action.SIGN_AND_ENCRYPT"
-
- public const val ACTION_QUERY_AUTOCRYPT_STATUS: String =
- "org.openintents.openpgp.action.QUERY_AUTOCRYPT_STATUS"
-
- /**
- * Decrypts and verifies given input stream. This methods handles encrypted-only, signed-and-encrypted,
- * and also signed-only input.
- * OutputStream is optional, e.g., for verifying detached signatures!
- *
- * If OpenPgpSignatureResult.getResult() == OpenPgpSignatureResult.RESULT_KEY_MISSING
- * in addition a PendingIntent is returned via RESULT_INTENT to download missing keys.
- * On all other status, in addition a PendingIntent is returned via RESULT_INTENT to open
- * the key view in OpenKeychain.
- *
- * optional extras:
- * byte[] EXTRA_DETACHED_SIGNATURE (detached signature)
- *
- * returned extras:
- * OpenPgpSignatureResult RESULT_SIGNATURE
- * OpenPgpDecryptionResult RESULT_DECRYPTION
- * OpenPgpDecryptMetadata RESULT_METADATA
- * String RESULT_CHARSET (charset which was specified in the headers of ascii armored input, if any)
- */
- public const val ACTION_DECRYPT_VERIFY: String = "org.openintents.openpgp.action.DECRYPT_VERIFY"
-
- /**
- * Decrypts the header of an encrypted file to retrieve metadata such as original filename.
- *
- * This does not decrypt the actual content of the file.
- *
- * returned extras:
- * OpenPgpDecryptMetadata RESULT_METADATA
- * String RESULT_CHARSET (charset which was specified in the headers of ascii armored input, if any)
- */
- public const val ACTION_DECRYPT_METADATA: String = "org.openintents.openpgp.action.DECRYPT_METADATA"
-
- /**
- * Select key id for signing
- *
- * optional extras:
- * String EXTRA_USER_ID
- *
- * returned extras:
- * long EXTRA_SIGN_KEY_ID
- */
- public const val ACTION_GET_SIGN_KEY_ID: String = "org.openintents.openpgp.action.GET_SIGN_KEY_ID"
-
- /**
- * Get key ids based on given user ids (=emails)
- *
- * required extras:
- * String[] EXTRA_USER_IDS
- *
- * returned extras:
- * long[] RESULT_KEY_IDS
- */
- public const val ACTION_GET_KEY_IDS: String = "org.openintents.openpgp.action.GET_KEY_IDS"
-
- /**
- * This action returns RESULT_CODE_SUCCESS if the OpenPGP Provider already has the key
- * corresponding to the given key id in its database.
- *
- * It returns RESULT_CODE_USER_INTERACTION_REQUIRED if the Provider does not have the key.
- * The PendingIntent from RESULT_INTENT can be used to retrieve those from a keyserver.
- *
- * If an Output stream has been defined the whole public key is returned.
- * required extras:
- * long EXTRA_KEY_ID
- *
- * optional extras:
- * String EXTRA_REQUEST_ASCII_ARMOR (request that the returned key is encoded in ASCII Armor)
- */
- public const val ACTION_GET_KEY: String = "org.openintents.openpgp.action.GET_KEY"
-
- /**
- * Backup all keys given by EXTRA_KEY_IDS and if requested their secret parts.
- * The encrypted backup will be written to the OutputStream.
- * The client app has no access to the backup code used to encrypt the backup!
- * This operation always requires user interaction with RESULT_CODE_USER_INTERACTION_REQUIRED!
- *
- * required extras:
- * long[] EXTRA_KEY_IDS (keys that should be included in the backup)
- * boolean EXTRA_BACKUP_SECRET (also backup secret keys)
- */
- public const val ACTION_BACKUP: String = "org.openintents.openpgp.action.BACKUP"
-
- public const val ACTION_UPDATE_AUTOCRYPT_PEER: String =
- "org.openintents.openpgp.action.UPDATE_AUTOCRYPT_PEER"
-
- /* Intent extras */
- public const val EXTRA_API_VERSION: String = "api_version"
-
- // ACTION_DETACHED_SIGN, ENCRYPT, SIGN_AND_ENCRYPT, DECRYPT_VERIFY
- // request ASCII Armor for output
- // OpenPGP Radix-64, 33 percent overhead compared to binary, see http://tools.ietf.org/html/rfc4880#page-53)
- public const val EXTRA_REQUEST_ASCII_ARMOR: String = "ascii_armor"
-
- // ACTION_DETACHED_SIGN
- public const val RESULT_DETACHED_SIGNATURE: String = "detached_signature"
- public const val RESULT_SIGNATURE_MICALG: String = "signature_micalg"
-
- // ENCRYPT, SIGN_AND_ENCRYPT, QUERY_AUTOCRYPT_STATUS
- public const val EXTRA_USER_IDS: String = "user_ids"
- public const val EXTRA_KEY_IDS: String = "key_ids"
- public const val EXTRA_KEY_IDS_SELECTED: String = "key_ids_selected"
- public const val EXTRA_SIGN_KEY_ID: String = "sign_key_id"
-
- public const val RESULT_KEYS_CONFIRMED: String = "keys_confirmed"
- public const val RESULT_AUTOCRYPT_STATUS: String = "autocrypt_status"
- public const val AUTOCRYPT_STATUS_UNAVAILABLE: Int = 0
- public const val AUTOCRYPT_STATUS_DISCOURAGE: Int = 1
- public const val AUTOCRYPT_STATUS_AVAILABLE: Int = 2
- public const val AUTOCRYPT_STATUS_MUTUAL: Int = 3
-
- // optional extras:
- public const val EXTRA_PASSPHRASE: String = "passphrase"
- public const val EXTRA_ORIGINAL_FILENAME: String = "original_filename"
- public const val EXTRA_ENABLE_COMPRESSION: String = "enable_compression"
- public const val EXTRA_OPPORTUNISTIC_ENCRYPTION: String = "opportunistic"
-
- // GET_SIGN_KEY_ID
- public const val EXTRA_USER_ID: String = "user_id"
-
- // GET_KEY
- public const val EXTRA_KEY_ID: String = "key_id"
- public const val EXTRA_MINIMIZE: String = "minimize"
- public const val EXTRA_MINIMIZE_USER_ID: String = "minimize_user_id"
- public const val RESULT_KEY_IDS: String = "key_ids"
-
- // BACKUP
- public const val EXTRA_BACKUP_SECRET: String = "backup_secret"
-
- /* Service Intent returns */
- public const val RESULT_CODE: String = "result_code"
-
- // get actual error object from RESULT_ERROR
- public const val RESULT_CODE_ERROR: Int = 0
-
- // success!
- public const val RESULT_CODE_SUCCESS: Int = 1
-
- // get PendingIntent from RESULT_INTENT, start PendingIntent with startIntentSenderForResult,
- // and execute service method again in onActivityResult
- public const val RESULT_CODE_USER_INTERACTION_REQUIRED: Int = 2
-
- public const val RESULT_ERROR: String = "error"
- public const val RESULT_INTENT: String = "intent"
-
- // DECRYPT_VERIFY
- public const val EXTRA_DETACHED_SIGNATURE: String = "detached_signature"
- public const val EXTRA_PROGRESS_MESSENGER: String = "progress_messenger"
- public const val EXTRA_DATA_LENGTH: String = "data_length"
- public const val EXTRA_DECRYPTION_RESULT: String = "decryption_result"
- public const val EXTRA_SENDER_ADDRESS: String = "sender_address"
- public const val EXTRA_SUPPORT_OVERRIDE_CRYPTO_WARNING: String = "support_override_crpto_warning"
- public const val EXTRA_AUTOCRYPT_PEER_ID: String = "autocrypt_peer_id"
- public const val EXTRA_AUTOCRYPT_PEER_UPDATE: String = "autocrypt_peer_update"
- public const val EXTRA_AUTOCRYPT_PEER_GOSSIP_UPDATES: String = "autocrypt_peer_gossip_updates"
- public const val RESULT_SIGNATURE: String = "signature"
- public const val RESULT_DECRYPTION: String = "decryption"
- public const val RESULT_METADATA: String = "metadata"
- public const val RESULT_INSECURE_DETAIL_INTENT: String = "insecure_detail_intent"
- public const val RESULT_OVERRIDE_CRYPTO_WARNING: String = "override_crypto_warning"
-
- // This will be the charset which was specified in the headers of ascii armored input, if any
- public const val RESULT_CHARSET: String = "charset"
-
- // INTERNAL, must not be used
- internal const val EXTRA_CALL_UUID1 = "call_uuid1"
- internal const val EXTRA_CALL_UUID2 = "call_uuid2"
- }
+ /**
+ * General extras --------------
+ *
+ * required extras: int EXTRA_API_VERSION (always required)
+ *
+ * returned extras: int RESULT_CODE (RESULT_CODE_ERROR, RESULT_CODE_SUCCESS or
+ * RESULT_CODE_USER_INTERACTION_REQUIRED) OpenPgpError RESULT_ERROR (if RESULT_CODE ==
+ * RESULT_CODE_ERROR) PendingIntent RESULT_INTENT (if RESULT_CODE ==
+ * RESULT_CODE_USER_INTERACTION_REQUIRED)
+ */
+ /**
+ * This action performs no operation, but can be used to check if the App has permission to
+ * access the API in general, returning a user interaction PendingIntent otherwise. This can be
+ * used to trigger the permission dialog explicitly.
+ *
+ * This action uses no extras.
+ */
+ public const val ACTION_CHECK_PERMISSION: String = "org.openintents.openpgp.action.CHECK_PERMISSION"
+
+ /**
+ * Sign text resulting in a cleartext signature Some magic pre-processing of the text is done to
+ * convert it to a format usable for cleartext signatures per RFC 4880 before the text is
+ * actually signed:
+ * - end cleartext with newline
+ * - remove whitespaces on line endings
+ *
+ * required extras: long EXTRA_SIGN_KEY_ID (key id of signing key)
+ *
+ * optional extras: char[] EXTRA_PASSPHRASE (key passphrase)
+ */
+ public const val ACTION_CLEARTEXT_SIGN: String = "org.openintents.openpgp.action.CLEARTEXT_SIGN"
+
+ /**
+ * Sign text or binary data resulting in a detached signature. No OutputStream necessary for
+ * ACTION_DETACHED_SIGN (No magic pre-processing like in ACTION_CLEARTEXT_SIGN)! The detached
+ * signature is returned separately in RESULT_DETACHED_SIGNATURE.
+ *
+ * required extras: long EXTRA_SIGN_KEY_ID (key id of signing key)
+ *
+ * optional extras: boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for detached
+ * signature) char[] EXTRA_PASSPHRASE (key passphrase)
+ *
+ * returned extras: byte[] RESULT_DETACHED_SIGNATURE String RESULT_SIGNATURE_MICALG (contains
+ * the name of the used signature algorithm as a string)
+ */
+ public const val ACTION_DETACHED_SIGN: String = "org.openintents.openpgp.action.DETACHED_SIGN"
+
+ /**
+ * Encrypt
+ *
+ * required extras: String[] EXTRA_USER_IDS (=emails of recipients, if more than one key has a
+ * user_id, a PendingIntent is returned via RESULT_INTENT) or long[] EXTRA_KEY_IDS
+ *
+ * optional extras: boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for output) char[]
+ * EXTRA_PASSPHRASE (key passphrase) String EXTRA_ORIGINAL_FILENAME (original filename to be
+ * encrypted as metadata) boolean EXTRA_ENABLE_COMPRESSION (enable ZLIB compression, default ist
+ * true)
+ */
+ public const val ACTION_ENCRYPT: String = "org.openintents.openpgp.action.ENCRYPT"
+
+ /**
+ * Sign and encrypt
+ *
+ * required extras: String[] EXTRA_USER_IDS (=emails of recipients, if more than one key has a
+ * user_id, a PendingIntent is returned via RESULT_INTENT) or long[] EXTRA_KEY_IDS
+ *
+ * optional extras: long EXTRA_SIGN_KEY_ID (key id of signing key) boolean
+ * EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for output) char[] EXTRA_PASSPHRASE (key
+ * passphrase) String EXTRA_ORIGINAL_FILENAME (original filename to be encrypted as metadata)
+ * boolean EXTRA_ENABLE_COMPRESSION (enable ZLIB compression, default ist true)
+ */
+ public const val ACTION_SIGN_AND_ENCRYPT: String = "org.openintents.openpgp.action.SIGN_AND_ENCRYPT"
+
+ public const val ACTION_QUERY_AUTOCRYPT_STATUS: String = "org.openintents.openpgp.action.QUERY_AUTOCRYPT_STATUS"
+
+ /**
+ * Decrypts and verifies given input stream. This methods handles encrypted-only,
+ * signed-and-encrypted, and also signed-only input. OutputStream is optional, e.g., for
+ * verifying detached signatures!
+ *
+ * If OpenPgpSignatureResult.getResult() == OpenPgpSignatureResult.RESULT_KEY_MISSING in
+ * addition a PendingIntent is returned via RESULT_INTENT to download missing keys. On all other
+ * status, in addition a PendingIntent is returned via RESULT_INTENT to open the key view in
+ * OpenKeychain.
+ *
+ * optional extras: byte[] EXTRA_DETACHED_SIGNATURE (detached signature)
+ *
+ * returned extras: OpenPgpSignatureResult RESULT_SIGNATURE OpenPgpDecryptionResult
+ * RESULT_DECRYPTION OpenPgpDecryptMetadata RESULT_METADATA String RESULT_CHARSET (charset which
+ * was specified in the headers of ascii armored input, if any)
+ */
+ public const val ACTION_DECRYPT_VERIFY: String = "org.openintents.openpgp.action.DECRYPT_VERIFY"
+
+ /**
+ * Decrypts the header of an encrypted file to retrieve metadata such as original filename.
+ *
+ * This does not decrypt the actual content of the file.
+ *
+ * returned extras: OpenPgpDecryptMetadata RESULT_METADATA String RESULT_CHARSET (charset which
+ * was specified in the headers of ascii armored input, if any)
+ */
+ public const val ACTION_DECRYPT_METADATA: String = "org.openintents.openpgp.action.DECRYPT_METADATA"
+
+ /**
+ * Select key id for signing
+ *
+ * optional extras: String EXTRA_USER_ID
+ *
+ * returned extras: long EXTRA_SIGN_KEY_ID
+ */
+ public const val ACTION_GET_SIGN_KEY_ID: String = "org.openintents.openpgp.action.GET_SIGN_KEY_ID"
+
+ /**
+ * Get key ids based on given user ids (=emails)
+ *
+ * required extras: String[] EXTRA_USER_IDS
+ *
+ * returned extras: long[] RESULT_KEY_IDS
+ */
+ public const val ACTION_GET_KEY_IDS: String = "org.openintents.openpgp.action.GET_KEY_IDS"
+
+ /**
+ * This action returns RESULT_CODE_SUCCESS if the OpenPGP Provider already has the key
+ * corresponding to the given key id in its database.
+ *
+ * It returns RESULT_CODE_USER_INTERACTION_REQUIRED if the Provider does not have the key. The
+ * PendingIntent from RESULT_INTENT can be used to retrieve those from a keyserver.
+ *
+ * If an Output stream has been defined the whole public key is returned. required extras: long
+ * EXTRA_KEY_ID
+ *
+ * optional extras: String EXTRA_REQUEST_ASCII_ARMOR (request that the returned key is encoded
+ * in ASCII Armor)
+ */
+ public const val ACTION_GET_KEY: String = "org.openintents.openpgp.action.GET_KEY"
+
+ /**
+ * Backup all keys given by EXTRA_KEY_IDS and if requested their secret parts. The encrypted
+ * backup will be written to the OutputStream. The client app has no access to the backup code
+ * used to encrypt the backup! This operation always requires user interaction with
+ * RESULT_CODE_USER_INTERACTION_REQUIRED!
+ *
+ * required extras: long[] EXTRA_KEY_IDS (keys that should be included in the backup) boolean
+ * EXTRA_BACKUP_SECRET (also backup secret keys)
+ */
+ public const val ACTION_BACKUP: String = "org.openintents.openpgp.action.BACKUP"
+
+ public const val ACTION_UPDATE_AUTOCRYPT_PEER: String = "org.openintents.openpgp.action.UPDATE_AUTOCRYPT_PEER"
+
+ /* Intent extras */
+ public const val EXTRA_API_VERSION: String = "api_version"
+
+ // ACTION_DETACHED_SIGN, ENCRYPT, SIGN_AND_ENCRYPT, DECRYPT_VERIFY
+ // request ASCII Armor for output
+ // OpenPGP Radix-64, 33 percent overhead compared to binary, see
+ // http://tools.ietf.org/html/rfc4880#page-53)
+ public const val EXTRA_REQUEST_ASCII_ARMOR: String = "ascii_armor"
+
+ // ACTION_DETACHED_SIGN
+ public const val RESULT_DETACHED_SIGNATURE: String = "detached_signature"
+ public const val RESULT_SIGNATURE_MICALG: String = "signature_micalg"
+
+ // ENCRYPT, SIGN_AND_ENCRYPT, QUERY_AUTOCRYPT_STATUS
+ public const val EXTRA_USER_IDS: String = "user_ids"
+ public const val EXTRA_KEY_IDS: String = "key_ids"
+ public const val EXTRA_KEY_IDS_SELECTED: String = "key_ids_selected"
+ public const val EXTRA_SIGN_KEY_ID: String = "sign_key_id"
+
+ public const val RESULT_KEYS_CONFIRMED: String = "keys_confirmed"
+ public const val RESULT_AUTOCRYPT_STATUS: String = "autocrypt_status"
+ public const val AUTOCRYPT_STATUS_UNAVAILABLE: Int = 0
+ public const val AUTOCRYPT_STATUS_DISCOURAGE: Int = 1
+ public const val AUTOCRYPT_STATUS_AVAILABLE: Int = 2
+ public const val AUTOCRYPT_STATUS_MUTUAL: Int = 3
+
+ // optional extras:
+ public const val EXTRA_PASSPHRASE: String = "passphrase"
+ public const val EXTRA_ORIGINAL_FILENAME: String = "original_filename"
+ public const val EXTRA_ENABLE_COMPRESSION: String = "enable_compression"
+ public const val EXTRA_OPPORTUNISTIC_ENCRYPTION: String = "opportunistic"
+
+ // GET_SIGN_KEY_ID
+ public const val EXTRA_USER_ID: String = "user_id"
+
+ // GET_KEY
+ public const val EXTRA_KEY_ID: String = "key_id"
+ public const val EXTRA_MINIMIZE: String = "minimize"
+ public const val EXTRA_MINIMIZE_USER_ID: String = "minimize_user_id"
+ public const val RESULT_KEY_IDS: String = "key_ids"
+
+ // BACKUP
+ public const val EXTRA_BACKUP_SECRET: String = "backup_secret"
+
+ /* Service Intent returns */
+ public const val RESULT_CODE: String = "result_code"
+
+ // get actual error object from RESULT_ERROR
+ public const val RESULT_CODE_ERROR: Int = 0
+
+ // success!
+ public const val RESULT_CODE_SUCCESS: Int = 1
+
+ // get PendingIntent from RESULT_INTENT, start PendingIntent with
+ // startIntentSenderForResult,
+ // and execute service method again in onActivityResult
+ public const val RESULT_CODE_USER_INTERACTION_REQUIRED: Int = 2
+
+ public const val RESULT_ERROR: String = "error"
+ public const val RESULT_INTENT: String = "intent"
+
+ // DECRYPT_VERIFY
+ public const val EXTRA_DETACHED_SIGNATURE: String = "detached_signature"
+ public const val EXTRA_PROGRESS_MESSENGER: String = "progress_messenger"
+ public const val EXTRA_DATA_LENGTH: String = "data_length"
+ public const val EXTRA_DECRYPTION_RESULT: String = "decryption_result"
+ public const val EXTRA_SENDER_ADDRESS: String = "sender_address"
+ public const val EXTRA_SUPPORT_OVERRIDE_CRYPTO_WARNING: String = "support_override_crpto_warning"
+ public const val EXTRA_AUTOCRYPT_PEER_ID: String = "autocrypt_peer_id"
+ public const val EXTRA_AUTOCRYPT_PEER_UPDATE: String = "autocrypt_peer_update"
+ public const val EXTRA_AUTOCRYPT_PEER_GOSSIP_UPDATES: String = "autocrypt_peer_gossip_updates"
+ public const val RESULT_SIGNATURE: String = "signature"
+ public const val RESULT_DECRYPTION: String = "decryption"
+ public const val RESULT_METADATA: String = "metadata"
+ public const val RESULT_INSECURE_DETAIL_INTENT: String = "insecure_detail_intent"
+ public const val RESULT_OVERRIDE_CRYPTO_WARNING: String = "override_crypto_warning"
+
+ // This will be the charset which was specified in the headers of ascii armored input, if
+ // any
+ public const val RESULT_CHARSET: String = "charset"
+
+ // INTERNAL, must not be used
+ internal const val EXTRA_CALL_UUID1 = "call_uuid1"
+ internal const val EXTRA_CALL_UUID2 = "call_uuid2"
+ }
}
diff --git a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpServiceConnection.kt b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpServiceConnection.kt
index 4efa6a9d..6a0a9933 100644
--- a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpServiceConnection.kt
+++ b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpServiceConnection.kt
@@ -13,76 +13,72 @@ import org.openintents.openpgp.IOpenPgpService2
public class OpenPgpServiceConnection(context: Context, providerPackageName: String?) {
- // callback interface
- public interface OnBound {
+ // callback interface
+ public interface OnBound {
- public fun onBound(service: IOpenPgpService2)
- public fun onError(e: Exception)
- }
+ public fun onBound(service: IOpenPgpService2)
+ public fun onError(e: Exception)
+ }
- private val mApplicationContext: Context = context.applicationContext
- public var service: IOpenPgpService2? = null
- private set
- private val mProviderPackageName: String? = providerPackageName
- private var mOnBoundListener: OnBound? = null
+ private val mApplicationContext: Context = context.applicationContext
+ public var service: IOpenPgpService2? = null
+ private set
+ private val mProviderPackageName: String? = providerPackageName
+ private var mOnBoundListener: OnBound? = null
- /**
- * Create new connection with callback
- *
- * @param context
- * @param providerPackageName specify package name of OpenPGP provider,
- * e.g., "org.sufficientlysecure.keychain"
- * @param onBoundListener callback, executed when connection to service has been established
- */
- public constructor(
- context: Context,
- providerPackageName: String?,
- onBoundListener: OnBound?
- ) : this(context, providerPackageName) {
- mOnBoundListener = onBoundListener
- }
+ /**
+ * Create new connection with callback
+ *
+ * @param context
+ * @param providerPackageName specify package name of OpenPGP provider, e.g.,
+ * "org.sufficientlysecure.keychain"
+ * @param onBoundListener callback, executed when connection to service has been established
+ */
+ public constructor(
+ context: Context,
+ providerPackageName: String?,
+ onBoundListener: OnBound?
+ ) : this(context, providerPackageName) {
+ mOnBoundListener = onBoundListener
+ }
- public val isBound: Boolean
- get() = service != null
+ public val isBound: Boolean
+ get() = service != null
- private val mServiceConnection: ServiceConnection = object : ServiceConnection {
- override fun onServiceConnected(name: ComponentName, service: IBinder) {
- this@OpenPgpServiceConnection.service = IOpenPgpService2.Stub.asInterface(service)
- mOnBoundListener?.onBound(this@OpenPgpServiceConnection.service!!)
- }
+ private val mServiceConnection: ServiceConnection =
+ object : ServiceConnection {
+ override fun onServiceConnected(name: ComponentName, service: IBinder) {
+ this@OpenPgpServiceConnection.service = IOpenPgpService2.Stub.asInterface(service)
+ mOnBoundListener?.onBound(this@OpenPgpServiceConnection.service!!)
+ }
- override fun onServiceDisconnected(name: ComponentName) {
- service = null
- }
+ override fun onServiceDisconnected(name: ComponentName) {
+ service = null
+ }
}
- /**
- * If not already bound, bind to service!
- */
- public fun bindToService() {
- if (service == null) {
- // if not already bound...
- try {
- val serviceIntent = Intent(OpenPgpApi.SERVICE_INTENT_2)
- // NOTE: setPackage is very important to restrict the intent to this provider only!
- serviceIntent.setPackage(mProviderPackageName)
- val connect = mApplicationContext.bindService(
- serviceIntent, mServiceConnection,
- Context.BIND_AUTO_CREATE
- )
- if (!connect) {
- throw Exception("bindService() returned false!")
- }
- } catch (e: Exception) {
- mOnBoundListener?.onError(e)
- }
- } else {
- // already bound, but also inform client about it with callback
- mOnBoundListener?.onBound(service!!)
+ /** If not already bound, bind to service! */
+ public fun bindToService() {
+ if (service == null) {
+ // if not already bound...
+ try {
+ val serviceIntent = Intent(OpenPgpApi.SERVICE_INTENT_2)
+ // NOTE: setPackage is very important to restrict the intent to this provider only!
+ serviceIntent.setPackage(mProviderPackageName)
+ val connect = mApplicationContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE)
+ if (!connect) {
+ throw Exception("bindService() returned false!")
}
+ } catch (e: Exception) {
+ mOnBoundListener?.onError(e)
+ }
+ } else {
+ // already bound, but also inform client about it with callback
+ mOnBoundListener?.onBound(service!!)
}
+ }
- public fun unbindFromService() {
- mApplicationContext.unbindService(mServiceConnection)
- }
+ public fun unbindFromService() {
+ mApplicationContext.unbindService(mServiceConnection)
+ }
}
diff --git a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpUtils.kt b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpUtils.kt
index 03ee11fc..f277615e 100644
--- a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpUtils.kt
+++ b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/OpenPgpUtils.kt
@@ -12,103 +12,96 @@ import java.util.regex.Pattern
public object OpenPgpUtils {
- private val PGP_MESSAGE: Pattern = Pattern.compile(
- ".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*",
- Pattern.DOTALL
+ private val PGP_MESSAGE: Pattern =
+ Pattern.compile(".*?(-----BEGIN PGP MESSAGE-----.*?-----END PGP MESSAGE-----).*", Pattern.DOTALL)
+ private val PGP_SIGNED_MESSAGE: Pattern =
+ Pattern.compile(
+ ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
+ Pattern.DOTALL
)
- private val PGP_SIGNED_MESSAGE: Pattern = Pattern.compile(
- ".*?(-----BEGIN PGP SIGNED MESSAGE-----.*?-----BEGIN PGP SIGNATURE-----.*?-----END PGP SIGNATURE-----).*",
- Pattern.DOTALL
- )
- private val USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$")
- private val EMAIL_PATTERN = Pattern.compile("^<?\"?([^<>\"]*@[^<>\"]*\\.[^<>\"]*)\"?>?$")
- public const val PARSE_RESULT_NO_PGP: Int = -1
- public const val PARSE_RESULT_MESSAGE: Int = 0
- public const val PARSE_RESULT_SIGNED_MESSAGE: Int = 1
+ private val USER_ID_PATTERN = Pattern.compile("^(.*?)(?: \\((.*)\\))?(?: <(.*)>)?$")
+ private val EMAIL_PATTERN = Pattern.compile("^<?\"?([^<>\"]*@[^<>\"]*\\.[^<>\"]*)\"?>?$")
+ public const val PARSE_RESULT_NO_PGP: Int = -1
+ public const val PARSE_RESULT_MESSAGE: Int = 0
+ public const val PARSE_RESULT_SIGNED_MESSAGE: Int = 1
- public fun parseMessage(message: String): Int {
- val matcherSigned = PGP_SIGNED_MESSAGE.matcher(message)
- val matcherMessage = PGP_MESSAGE.matcher(message)
- return when {
- matcherMessage.matches() -> PARSE_RESULT_MESSAGE
- matcherSigned.matches() -> PARSE_RESULT_SIGNED_MESSAGE
- else -> PARSE_RESULT_NO_PGP
- }
+ public fun parseMessage(message: String): Int {
+ val matcherSigned = PGP_SIGNED_MESSAGE.matcher(message)
+ val matcherMessage = PGP_MESSAGE.matcher(message)
+ return when {
+ matcherMessage.matches() -> PARSE_RESULT_MESSAGE
+ matcherSigned.matches() -> PARSE_RESULT_SIGNED_MESSAGE
+ else -> PARSE_RESULT_NO_PGP
}
+ }
- public fun isAvailable(context: Context): Boolean {
- val intent = Intent(OpenPgpApi.SERVICE_INTENT_2)
- val resInfo =
- context.packageManager.queryIntentServices(intent, 0)
- return resInfo.isNotEmpty()
- }
+ public fun isAvailable(context: Context): Boolean {
+ val intent = Intent(OpenPgpApi.SERVICE_INTENT_2)
+ val resInfo = context.packageManager.queryIntentServices(intent, 0)
+ return resInfo.isNotEmpty()
+ }
- public fun convertKeyIdToHex(keyId: Long): String {
- return "0x" + convertKeyIdToHex32bit(keyId shr 32) + convertKeyIdToHex32bit(
- keyId
- )
- }
+ public fun convertKeyIdToHex(keyId: Long): String {
+ return "0x" + convertKeyIdToHex32bit(keyId shr 32) + convertKeyIdToHex32bit(keyId)
+ }
- private fun convertKeyIdToHex32bit(keyId: Long): String {
- var hexString =
- java.lang.Long.toHexString(keyId and 0xffffffffL).toLowerCase(Locale.ENGLISH)
- while (hexString.length < 8) {
- hexString = "0$hexString"
- }
- return hexString
+ private fun convertKeyIdToHex32bit(keyId: Long): String {
+ var hexString = java.lang.Long.toHexString(keyId and 0xffffffffL).toLowerCase(Locale.ENGLISH)
+ while (hexString.length < 8) {
+ hexString = "0$hexString"
}
+ return hexString
+ }
- /**
- * Splits userId string into naming part, email part, and comment part.
- * See SplitUserIdTest for examples.
- */
- public fun splitUserId(userId: String): UserId {
- if (userId.isNotEmpty()) {
- val matcher = USER_ID_PATTERN.matcher(userId)
- if (matcher.matches()) {
- var name = if (matcher.group(1).isEmpty()) null else matcher.group(1)
- val comment = matcher.group(2)
- var email = matcher.group(3)
- if (email != null && name != null) {
- val emailMatcher = EMAIL_PATTERN.matcher(name)
- if (emailMatcher.matches() && email == emailMatcher.group(1)) {
- email = emailMatcher.group(1)
- name = null
- }
- }
- if (email == null && name != null) {
- val emailMatcher = EMAIL_PATTERN.matcher(name)
- if (emailMatcher.matches()) {
- email = emailMatcher.group(1)
- name = null
- }
- }
- return UserId(name, email, comment)
- }
+ /**
+ * Splits userId string into naming part, email part, and comment part. See SplitUserIdTest for
+ * examples.
+ */
+ public fun splitUserId(userId: String): UserId {
+ if (userId.isNotEmpty()) {
+ val matcher = USER_ID_PATTERN.matcher(userId)
+ if (matcher.matches()) {
+ var name = if (matcher.group(1).isEmpty()) null else matcher.group(1)
+ val comment = matcher.group(2)
+ var email = matcher.group(3)
+ if (email != null && name != null) {
+ val emailMatcher = EMAIL_PATTERN.matcher(name)
+ if (emailMatcher.matches() && email == emailMatcher.group(1)) {
+ email = emailMatcher.group(1)
+ name = null
+ }
+ }
+ if (email == null && name != null) {
+ val emailMatcher = EMAIL_PATTERN.matcher(name)
+ if (emailMatcher.matches()) {
+ email = emailMatcher.group(1)
+ name = null
+ }
}
- return UserId(null, null, null)
+ return UserId(name, email, comment)
+ }
}
+ return UserId(null, null, null)
+ }
- /**
- * Returns a composed user id. Returns null if name, email and comment are empty.
- */
- public fun createUserId(userId: UserId): String? {
- val userIdBuilder = StringBuilder()
- if (!userId.name.isNullOrEmpty()) {
- userIdBuilder.append(userId.name)
- }
- if (!userId.comment.isNullOrEmpty()) {
- userIdBuilder.append(" (")
- userIdBuilder.append(userId.comment)
- userIdBuilder.append(")")
- }
- if (!userId.email.isNullOrEmpty()) {
- userIdBuilder.append(" <")
- userIdBuilder.append(userId.email)
- userIdBuilder.append(">")
- }
- return if (userIdBuilder.isEmpty()) null else userIdBuilder.toString()
+ /** Returns a composed user id. Returns null if name, email and comment are empty. */
+ public fun createUserId(userId: UserId): String? {
+ val userIdBuilder = StringBuilder()
+ if (!userId.name.isNullOrEmpty()) {
+ userIdBuilder.append(userId.name)
+ }
+ if (!userId.comment.isNullOrEmpty()) {
+ userIdBuilder.append(" (")
+ userIdBuilder.append(userId.comment)
+ userIdBuilder.append(")")
+ }
+ if (!userId.email.isNullOrEmpty()) {
+ userIdBuilder.append(" <")
+ userIdBuilder.append(userId.email)
+ userIdBuilder.append(">")
}
+ return if (userIdBuilder.isEmpty()) null else userIdBuilder.toString()
+ }
- public class UserId(public val name: String?, public val email: String?, public val comment: String?) : Serializable
+ public class UserId(public val name: String?, public val email: String?, public val comment: String?) : Serializable
}
diff --git a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/ParcelFileDescriptorUtil.kt b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/ParcelFileDescriptorUtil.kt
index 58657118..26e04e97 100644
--- a/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/ParcelFileDescriptorUtil.kt
+++ b/openpgp-ktx/src/main/java/me/msfjarvis/openpgpktx/util/ParcelFileDescriptorUtil.kt
@@ -14,50 +14,47 @@ import java.io.OutputStream
internal object ParcelFileDescriptorUtil {
- private const val TAG = "PFDUtils"
-
- @Throws(IOException::class)
- internal fun pipeFrom(inputStream: InputStream): ParcelFileDescriptor {
- val pipe = ParcelFileDescriptor.createPipe()
- val readSide = pipe[0]
- val writeSide = pipe[1]
- TransferThread(inputStream, AutoCloseOutputStream(writeSide))
- .start()
- return readSide
- }
-
- @Throws(IOException::class)
- internal fun pipeTo(outputStream: OutputStream, output: ParcelFileDescriptor?): TransferThread {
- val t = TransferThread(AutoCloseInputStream(output), outputStream)
- t.start()
- return t
- }
-
- internal class TransferThread(val `in`: InputStream, private val out: OutputStream) : Thread("IPC Transfer Thread") {
-
- override fun run() {
- val buf = ByteArray(4096)
- var len: Int
- try {
- while (`in`.read(buf).also { len = it } > 0) {
- out.write(buf, 0, len)
- }
- } catch (e: IOException) {
- Log.e(TAG, "IOException when writing to out", e)
- } finally {
- try {
- `in`.close()
- } catch (ignored: IOException) {
- }
- try {
- out.close()
- } catch (ignored: IOException) {
- }
- }
+ private const val TAG = "PFDUtils"
+
+ @Throws(IOException::class)
+ internal fun pipeFrom(inputStream: InputStream): ParcelFileDescriptor {
+ val pipe = ParcelFileDescriptor.createPipe()
+ val readSide = pipe[0]
+ val writeSide = pipe[1]
+ TransferThread(inputStream, AutoCloseOutputStream(writeSide)).start()
+ return readSide
+ }
+
+ @Throws(IOException::class)
+ internal fun pipeTo(outputStream: OutputStream, output: ParcelFileDescriptor?): TransferThread {
+ val t = TransferThread(AutoCloseInputStream(output), outputStream)
+ t.start()
+ return t
+ }
+
+ internal class TransferThread(val `in`: InputStream, private val out: OutputStream) : Thread("IPC Transfer Thread") {
+
+ override fun run() {
+ val buf = ByteArray(4096)
+ var len: Int
+ try {
+ while (`in`.read(buf).also { len = it } > 0) {
+ out.write(buf, 0, len)
}
+ } catch (e: IOException) {
+ Log.e(TAG, "IOException when writing to out", e)
+ } finally {
+ try {
+ `in`.close()
+ } catch (ignored: IOException) {}
+ try {
+ out.close()
+ } catch (ignored: IOException) {}
+ }
+ }
- init {
- isDaemon = true
- }
+ init {
+ isDaemon = true
}
+ }
}