diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2016-05-07 12:20:03 +0300 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2016-05-07 12:20:03 +0300 |
commit | e908a2122c717463ebed21e850f5ef8770dfb9de (patch) | |
tree | db66c395f3c9cb1b5b4e2452b5802b0ab8953aa3 | |
parent | ab5fec23d751a017ab0fdac93950c00ce7b8c1dc (diff) | |
parent | deb09151190336097078a5b8738b9aa235cc1aa7 (diff) | |
download | openpgp-api-e908a2122c717463ebed21e850f5ef8770dfb9de.tar.gz openpgp-api-e908a2122c717463ebed21e850f5ef8770dfb9de.tar.bz2 openpgp-api-e908a2122c717463ebed21e850f5ef8770dfb9de.zip |
Merge branch 'master' of github.com:open-keychain/openpgp-api
-rw-r--r-- | example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java | 29 | ||||
-rw-r--r-- | example/src/main/res/layout/openpgp_provider.xml | 8 | ||||
-rw-r--r-- | gradle/wrapper/gradle-wrapper.jar | bin | 52141 -> 53639 bytes | |||
-rw-r--r-- | gradle/wrapper/gradle-wrapper.properties | 5 | ||||
-rwxr-xr-x | gradlew | 10 | ||||
-rw-r--r-- | gradlew.bat | 2 | ||||
-rw-r--r-- | openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpDecryptionResult.java | 39 | ||||
-rw-r--r-- | openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpError.java | 2 | ||||
-rw-r--r-- | openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java | 11 | ||||
-rw-r--r-- | openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java | 77 |
10 files changed, 118 insertions, 65 deletions
diff --git a/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java b/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java index 823c202..00a8f7d 100644 --- a/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java +++ b/example/src/main/java/org/openintents/openpgp/example/OpenPgpApiActivity.java @@ -49,6 +49,7 @@ public class OpenPgpApiActivity extends Activity { private EditText mDetachedSignature; private EditText mEncryptUserIds; private EditText mGetKeyEdit; + private EditText mGetKeyIdsEdit; private OpenPgpServiceConnection mServiceConnection; @@ -62,6 +63,7 @@ public class OpenPgpApiActivity extends Activity { public static final int REQUEST_CODE_GET_KEY_IDS = 9915; public static final int REQUEST_CODE_DETACHED_SIGN = 9916; public static final int REQUEST_CODE_DECRYPT_AND_VERIFY_DETACHED = 9917; + public static final int REQUEST_CODE_BACKUP = 9918; @Override public void onCreate(Bundle savedInstanceState) { @@ -79,9 +81,10 @@ public class OpenPgpApiActivity extends Activity { Button decryptAndVerify = (Button) findViewById(R.id.crypto_provider_demo_decrypt_and_verify); Button verifyDetachedSignature = (Button) findViewById(R.id.crypto_provider_demo_verify_detached_signature); mGetKeyEdit = (EditText) findViewById(R.id.crypto_provider_demo_get_key_edit); - EditText getKeyIdsEdit = (EditText) findViewById(R.id.crypto_provider_demo_get_key_ids_edit); + mGetKeyIdsEdit = (EditText) findViewById(R.id.crypto_provider_demo_get_key_ids_edit); Button getKey = (Button) findViewById(R.id.crypto_provider_demo_get_key); Button getKeyIds = (Button) findViewById(R.id.crypto_provider_demo_get_key_ids); + Button backup = (Button) findViewById(R.id.crypto_provider_demo_backup); cleartextSign.setOnClickListener(new View.OnClickListener() { @Override @@ -131,6 +134,12 @@ public class OpenPgpApiActivity extends Activity { getKeyIds(new Intent()); } }); + backup.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + backup(new Intent()); + } + }); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); String providerPackageName = settings.getString("openpgp_provider_list", ""); @@ -387,6 +396,7 @@ public class OpenPgpApiActivity extends Activity { public void getKeyIds(Intent data) { data.setAction(OpenPgpApi.ACTION_GET_KEY_IDS); + data.putExtra(OpenPgpApi.EXTRA_USER_IDS, mGetKeyIdsEdit.getText().toString().split(",")); OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService()); api.executeApiAsync(data, null, null, new MyCallback(false, null, REQUEST_CODE_GET_KEY_IDS)); @@ -394,12 +404,23 @@ public class OpenPgpApiActivity extends Activity { public void getAnyKeyIds(Intent data) { data.setAction(OpenPgpApi.ACTION_GET_KEY_IDS); -// data.putExtra(OpenPgpApi.EXTRA_USER_IDS, mGetKeyIdsEdit.getText().toString().split(",")); OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService()); api.executeApiAsync(data, null, null, new MyCallback(false, null, REQUEST_CODE_GET_KEY_IDS)); } + public void backup(Intent data) { + data.setAction(OpenPgpApi.ACTION_BACKUP); + data.putExtra(OpenPgpApi.EXTRA_KEY_IDS, new long[]{Long.decode(mGetKeyEdit.getText().toString())}); + data.putExtra(OpenPgpApi.EXTRA_BACKUP_SECRET, true); + data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService()); + api.executeApiAsync(data, null, os, new MyCallback(true, os, REQUEST_CODE_BACKUP)); + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -446,6 +467,10 @@ public class OpenPgpApiActivity extends Activity { getKeyIds(data); break; } + case REQUEST_CODE_BACKUP: { + backup(data); + break; + } } } } diff --git a/example/src/main/res/layout/openpgp_provider.xml b/example/src/main/res/layout/openpgp_provider.xml index 13096b4..d2b4572 100644 --- a/example/src/main/res/layout/openpgp_provider.xml +++ b/example/src/main/res/layout/openpgp_provider.xml @@ -153,7 +153,7 @@ <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Get key:" + android:text="Get key/backup key:" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText @@ -168,6 +168,12 @@ android:layout_height="wrap_content" android:text="Get key" /> + <Button + android:id="@+id/crypto_provider_demo_backup" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Backup" /> + <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar Binary files differindex 085a1cd..2c6137b 100644 --- a/gradle/wrapper/gradle-wrapper.jar +++ b/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 24ceae4..8ef44da 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Mon Aug 10 21:47:49 CEST 2015 +#Tue Apr 12 19:22:55 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip +distributionSha256Sum=d8b1948a575dc9ec13e03db94502ce91815d73da023f611296c04b852164cb5f
\ No newline at end of file @@ -42,11 +42,6 @@ case "`uname`" in ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" @@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do fi done SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -114,6 +109,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` diff --git a/gradlew.bat b/gradlew.bat index aec9973..72d362d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -46,7 +46,7 @@ echo location of your Java installation. goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpDecryptionResult.java b/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpDecryptionResult.java index 2090b55..513b502 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpDecryptionResult.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpDecryptionResult.java @@ -25,7 +25,7 @@ public class OpenPgpDecryptionResult implements Parcelable { * old versions of the protocol (and thus old versions of this class), we need a versioning * system for the parcels sent between the clients and the providers. */ - public static final int PARCELABLE_VERSION = 1; + public static final int PARCELABLE_VERSION = 2; // content not encrypted public static final int RESULT_NOT_ENCRYPTED = -1; @@ -34,26 +34,37 @@ public class OpenPgpDecryptionResult implements Parcelable { // encrypted public static final int RESULT_ENCRYPTED = 1; - int result; + public final int result; + public final byte[] sessionKey; + public final byte[] decryptedSessionKey; public int getResult() { return result; } - public void setResult(int result) { + public OpenPgpDecryptionResult(int result) { this.result = result; + this.sessionKey = null; + this.decryptedSessionKey = null; } - public OpenPgpDecryptionResult() { - - } - - public OpenPgpDecryptionResult(int result) { + public OpenPgpDecryptionResult(int result, byte[] sessionKey, byte[] decryptedSessionKey) { this.result = result; + if ((sessionKey == null) != (decryptedSessionKey == null)) { + throw new AssertionError("sessionkey must be null iff decryptedSessionKey is null"); + } + this.sessionKey = sessionKey; + this.decryptedSessionKey = decryptedSessionKey; } public OpenPgpDecryptionResult(OpenPgpDecryptionResult b) { this.result = b.result; + this.sessionKey = b.sessionKey; + this.decryptedSessionKey = b.decryptedSessionKey; + } + + public boolean hasDecryptedSessionKey() { + return sessionKey != null; } public int describeContents() { @@ -73,6 +84,9 @@ public class OpenPgpDecryptionResult implements Parcelable { int startPosition = dest.dataPosition(); // version 1 dest.writeInt(result); + // version 2 + dest.writeByteArray(sessionKey); + dest.writeByteArray(decryptedSessionKey); // Go back and write the size int parcelableSize = dest.dataPosition() - startPosition; dest.setDataPosition(sizePosition); @@ -82,12 +96,15 @@ public class OpenPgpDecryptionResult implements Parcelable { public static final Creator<OpenPgpDecryptionResult> CREATOR = new Creator<OpenPgpDecryptionResult>() { public OpenPgpDecryptionResult createFromParcel(final Parcel source) { - source.readInt(); // parcelableVersion + int version = source.readInt(); // parcelableVersion int parcelableSize = source.readInt(); int startPosition = source.dataPosition(); - OpenPgpDecryptionResult vr = new OpenPgpDecryptionResult(); - vr.result = source.readInt(); + int result = source.readInt(); + byte[] sessionKey = version > 1 ? source.createByteArray() : null; + byte[] decryptedSessionKey = version > 1 ? source.createByteArray() : null; + + OpenPgpDecryptionResult vr = new OpenPgpDecryptionResult(result, sessionKey, decryptedSessionKey); // skip over all fields added in future versions of this parcel source.setDataPosition(startPosition + parcelableSize); diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpError.java b/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpError.java index 69c39fd..67b10aa 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpError.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpError.java @@ -33,6 +33,8 @@ public class OpenPgpError implements Parcelable { public static final int INCOMPATIBLE_API_VERSIONS = 1; public static final int NO_OR_WRONG_PASSPHRASE = 2; public static final int NO_USER_IDS = 3; + public static final int OPPORTUNISTIC_MISSING_KEYS = 4; + int errorId; String message; diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java b/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java index f188968..ad3bb29 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/OpenPgpSignatureResult.java @@ -49,10 +49,11 @@ public class OpenPgpSignatureResult implements Parcelable { public static final int RESULT_INVALID_INSECURE = 6; int result; - boolean signatureOnly; String primaryUserId; ArrayList<String> userIds; long keyId; + @Deprecated + boolean signatureOnly; public int getResult() { return result; @@ -62,16 +63,12 @@ public class OpenPgpSignatureResult implements Parcelable { this.result = result; } - /** - * @deprecated - */ + @Deprecated public boolean isSignatureOnly() { return signatureOnly; } - /** - * @deprecated - */ + @Deprecated public void setSignatureOnly(boolean signatureOnly) { this.signatureOnly = signatureOnly; } diff --git a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java index 658823a..87a1605 100644 --- a/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java +++ b/openpgp-api/src/main/java/org/openintents/openpgp/util/OpenPgpApi.java @@ -60,19 +60,12 @@ public class OpenPgpApi { * 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 static final String ACTION_CHECK_PERMISSION = "org.openintents.openpgp.action.CHECK_PERMISSION"; - /** - * DEPRECATED - * Same as ACTION_CLEARTEXT_SIGN - * <p/> - * optional extras: - * boolean EXTRA_REQUEST_ASCII_ARMOR (DEPRECATED: this makes no sense here) - * char[] EXTRA_PASSPHRASE (key passphrase) - */ + @Deprecated public static final String ACTION_SIGN = "org.openintents.openpgp.action.SIGN"; /** @@ -81,10 +74,10 @@ public class OpenPgpApi { * cleartext signatures per RFC 4880 before the text is actually signed: * - end cleartext with newline * - remove whitespaces on line endings - * <p/> + * * required extras: * long EXTRA_SIGN_KEY_ID (key id of signing key) - * <p/> + * * optional extras: * char[] EXTRA_PASSPHRASE (key passphrase) */ @@ -94,14 +87,14 @@ public class OpenPgpApi { * 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. - * <p/> + * * required extras: * long EXTRA_SIGN_KEY_ID (key id of signing key) - * <p/> + * * optional extras: * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for detached signature) * char[] EXTRA_PASSPHRASE (key passphrase) - * <p/> + * * returned extras: * byte[] RESULT_DETACHED_SIGNATURE * String RESULT_SIGNATURE_MICALG (contains the name of the used signature algorithm as a string) @@ -110,12 +103,12 @@ public class OpenPgpApi { /** * Encrypt - * <p/> + * * 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 - * <p/> + * * optional extras: * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for output) * char[] EXTRA_PASSPHRASE (key passphrase) @@ -126,12 +119,12 @@ public class OpenPgpApi { /** * Sign and encrypt - * <p/> + * * 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 - * <p/> + * * optional extras: * long EXTRA_SIGN_KEY_ID (key id of signing key) * boolean EXTRA_REQUEST_ASCII_ARMOR (request ascii armor for output) @@ -145,15 +138,15 @@ public class OpenPgpApi { * 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! - * <p/> + * * 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. - * <p/> + * * optional extras: * byte[] EXTRA_DETACHED_SIGNATURE (detached signature) - * <p/> + * * returned extras: * OpenPgpSignatureResult RESULT_SIGNATURE * OpenPgpDecryptionResult RESULT_DECRYPTION @@ -164,9 +157,9 @@ public class OpenPgpApi { /** * Decrypts the header of an encrypted file to retrieve metadata such as original filename. - * <p/> + * * This does not decrypt the actual content of the file. - * <p/> + * * returned extras: * OpenPgpDecryptMetadata RESULT_METADATA * String RESULT_CHARSET (charset which was specified in the headers of ascii armored input, if any) @@ -175,10 +168,10 @@ public class OpenPgpApi { /** * Select key id for signing - * <p/> + * * optional extras: * String EXTRA_USER_ID - * <p/> + * * returned extras: * long EXTRA_SIGN_KEY_ID */ @@ -186,10 +179,10 @@ public class OpenPgpApi { /** * Get key ids based on given user ids (=emails) - * <p/> + * * required extras: * String[] EXTRA_USER_IDS - * <p/> + * * returned extras: * long[] RESULT_KEY_IDS */ @@ -198,25 +191,35 @@ public class OpenPgpApi { /** * This action returns RESULT_CODE_SUCCESS if the OpenPGP Provider already has the key * corresponding to the given key id in its database. - * <p/> + * * 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. - * <p/> + * * If an Output stream has been defined the whole public key is returned. * required extras: * long EXTRA_KEY_ID - * <p/> + * * optional extras: * String EXTRA_REQUEST_ASCII_ARMOR (request that the returned key is encoded in ASCII Armor) - * */ public static final String ACTION_GET_KEY = "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 static final String ACTION_BACKUP = "org.openintents.openpgp.action.BACKUP"; /* Intent extras */ public static final String EXTRA_API_VERSION = "api_version"; - // DEPRECATED!!! + @Deprecated public static final String EXTRA_ACCOUNT_NAME = "account_name"; // ACTION_DETACHED_SIGN, ENCRYPT, SIGN_AND_ENCRYPT, DECRYPT_VERIFY @@ -236,6 +239,7 @@ public class OpenPgpApi { public static final String EXTRA_PASSPHRASE = "passphrase"; public static final String EXTRA_ORIGINAL_FILENAME = "original_filename"; public static final String EXTRA_ENABLE_COMPRESSION = "enable_compression"; + public static final String EXTRA_OPPORTUNISTIC_ENCRYPTION = "opportunistic"; // GET_SIGN_KEY_ID public static final String EXTRA_USER_ID = "user_id"; @@ -244,6 +248,9 @@ public class OpenPgpApi { public static final String EXTRA_KEY_ID = "key_id"; public static final String RESULT_KEY_IDS = "key_ids"; + // BACKUP + public static final String EXTRA_BACKUP_SECRET = "backup_secret"; + /* Service Intent returns */ public static final String RESULT_CODE = "result_code"; @@ -260,13 +267,15 @@ public class OpenPgpApi { // DECRYPT_VERIFY public static final String EXTRA_DETACHED_SIGNATURE = "detached_signature"; + public static final String EXTRA_DECRYPTION_RESULT_WRAPPER = "decryption_result_wrapper"; + public static final String EXTRA_DECRYPTION_RESULT = "decryption_result"; public static final String RESULT_SIGNATURE = "signature"; public static final String RESULT_DECRYPTION = "decryption"; public static final String RESULT_METADATA = "metadata"; // This will be the charset which was specified in the headers of ascii armored input, if any public static final String RESULT_CHARSET = "charset"; - // INTERNAL, should not be used + // INTERNAL, must not be used public static final String EXTRA_CALL_UUID1 = "call_uuid1"; public static final String EXTRA_CALL_UUID2 = "call_uuid2"; @@ -357,7 +366,7 @@ public class OpenPgpApi { Intent result; - Thread pumpThread =null; + Thread pumpThread = null; int outputPipeId = 0; if (os != null) { |