From e9c01957f4797d13518115e7e26ed015547f0891 Mon Sep 17 00:00:00 2001 From: Dominik Date: Wed, 20 Jun 2012 14:49:57 +0300 Subject: working on decrypt and restructering... --- .../org/thialfihar/android/apg/util/ApgCon.java | 836 --------------------- .../android/apg/util/ApgConInterface.java | 21 - .../org/thialfihar/android/apg/util/Constants.java | 6 - .../org/thialfihar/android/apg/util/InputData.java | 40 + .../android/apg/util/PositionAwareInputStream.java | 81 ++ .../org/thialfihar/android/apg/util/Primes.java | 185 +++++ .../src/org/thialfihar/android/apg/util/Utils.java | 189 ----- 7 files changed, 306 insertions(+), 1052 deletions(-) delete mode 100644 org_apg/src/org/thialfihar/android/apg/util/ApgCon.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/util/ApgConInterface.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/util/Constants.java create mode 100644 org_apg/src/org/thialfihar/android/apg/util/InputData.java create mode 100644 org_apg/src/org/thialfihar/android/apg/util/PositionAwareInputStream.java create mode 100644 org_apg/src/org/thialfihar/android/apg/util/Primes.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/util/Utils.java (limited to 'org_apg/src/org/thialfihar/android/apg/util') diff --git a/org_apg/src/org/thialfihar/android/apg/util/ApgCon.java b/org_apg/src/org/thialfihar/android/apg/util/ApgCon.java deleted file mode 100644 index 7341341d5..000000000 --- a/org_apg/src/org/thialfihar/android/apg/util/ApgCon.java +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (C) 2011 Markus Doits - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.util; - -import org.thialfihar.android.apg.service.IApgService2; -import org.thialfihar.android.apg.util.ApgConInterface.OnCallFinishListener; - -import android.content.ComponentName; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.os.IBinder; -import android.util.Log; - -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; - -/** - * A APG-AIDL-Wrapper - * - *

- * This class can be used by other projects to simplify connecting to the - * APG-AIDL-Service. Kind of wrapper of for AIDL. - *

- * - *

- * It is not used in this project. - *

- * - * @author Markus Doits - * @version 1.1rc1 - * - */ -public class ApgCon { - private static final boolean LOCAL_LOGV = true; - private static final boolean LOCAL_LOGD = true; - - private final static String TAG = "ApgCon"; - private final static int API_VERSION = 2; // aidl api-version it expects - private final static String BLOB_URI = "content://org.thialfihar.android.apg.provider.apgserviceblobprovider"; - - /** - * How many seconds to wait for a connection to AGP when connecting. - * Being unsuccessful for this number of seconds, a connection - * is assumed to be failed. - */ - public int secondsToWaitForConnection = 15; - - private class CallAsync extends AsyncTask { - - @Override - protected Void doInBackground(String... arg) { - if( LOCAL_LOGD ) Log.d(TAG, "Async execution starting"); - call(arg[0]); - return null; - } - - protected void onPostExecute(Void res) { - if( LOCAL_LOGD ) Log.d(TAG, "Async execution finished"); - mAsyncRunning = false; - - } - - } - - private final Context mContext; - private final error mConnectionStatus; - private boolean mAsyncRunning = false; - private OnCallFinishListener mOnCallFinishListener; - - private final Bundle mResult = new Bundle(); - private final Bundle mArgs = new Bundle(); - private final ArrayList mErrorList = new ArrayList(); - private final ArrayList mWarningList = new ArrayList(); - - /** Remote service for decrypting and encrypting data */ - private IApgService2 mApgService = null; - - /** Set apgService accordingly to connection status */ - private ServiceConnection mApgConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - if( LOCAL_LOGD ) Log.d(TAG, "IApgService bound to apgService"); - mApgService = IApgService2.Stub.asInterface(service); - } - - public void onServiceDisconnected(ComponentName className) { - if( LOCAL_LOGD ) Log.d(TAG, "IApgService disconnected"); - mApgService = null; - } - }; - - /** - * Different types of local errors - */ - public static enum error { - /** - * no error - */ - NO_ERROR, - /** - * generic error - */ - GENERIC, - /** - * connection to apg service not possible - */ - CANNOT_BIND_TO_APG, - /** - * function to call not provided - */ - CALL_MISSING, - /** - * apg service does not know what to do - */ - CALL_NOT_KNOWN, - /** - * could not find APG being installed - */ - APG_NOT_FOUND, - /** - * found APG but without AIDL interface - */ - APG_AIDL_MISSING, - /** - * found APG but with wrong API - */ - APG_API_MISSMATCH - } - - private static enum ret { - ERROR, // returned from AIDL - RESULT, // returned from AIDL - WARNINGS, // mixed AIDL and LOCAL - ERRORS, // mixed AIDL and LOCAL - } - - /** - * Constructor - * - *

- * Creates a new ApgCon object and searches for the right APG version on - * initialization. If not found, errors are printed to the error log. - *

- * - * @param ctx - * the running context - */ - public ApgCon(Context ctx) { - if( LOCAL_LOGV ) Log.v(TAG, "EncryptionService created"); - mContext = ctx; - - error tmpError = null; - try { - if( LOCAL_LOGV ) Log.v(TAG, "Searching for the right APG version"); - ServiceInfo apgServices[] = ctx.getPackageManager().getPackageInfo("org.thialfihar.android.apg", - PackageManager.GET_SERVICES | PackageManager.GET_META_DATA).services; - if (apgServices == null) { - Log.e(TAG, "Could not fetch services"); - tmpError = error.GENERIC; - } else { - boolean apgServiceFound = false; - for (ServiceInfo inf : apgServices) { - if( LOCAL_LOGV ) Log.v(TAG, "Found service of APG: " + inf.name); - if (inf.name.equals("org.thialfihar.android.apg.ApgService")) { - apgServiceFound = true; - if (inf.metaData == null) { - Log.w(TAG, "Could not determine ApgService API"); - Log.w(TAG, "This probably won't work!"); - mWarningList.add("(LOCAL) Could not determine ApgService API"); - tmpError = error.APG_API_MISSMATCH; - } else if (inf.metaData.getInt("api_version") != API_VERSION) { - Log.w(TAG, "Found ApgService API version " + inf.metaData.getInt("api_version") + " but exspected " + API_VERSION); - Log.w(TAG, "This probably won't work!"); - mWarningList.add("(LOCAL) Found ApgService API version " + inf.metaData.getInt("api_version") + " but exspected " + API_VERSION); - tmpError = error.APG_API_MISSMATCH; - } else { - if( LOCAL_LOGV ) Log.v(TAG, "Found api_version " + API_VERSION + ", everything should work"); - tmpError = error.NO_ERROR; - } - } - } - - if (!apgServiceFound) { - Log.e(TAG, "Could not find APG with AIDL interface, this probably won't work"); - mErrorList.add("(LOCAL) Could not find APG with AIDL interface, this probably won't work"); - mResult.putInt(ret.ERROR.name(), error.APG_AIDL_MISSING.ordinal()); - tmpError = error.APG_NOT_FOUND; - } - } - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "Could not find APG, is it installed?", e); - mErrorList.add("(LOCAL) Could not find APG, is it installed?"); - mResult.putInt(ret.ERROR.name(), error.APG_NOT_FOUND.ordinal()); - tmpError = error.APG_NOT_FOUND; - } - - mConnectionStatus = tmpError; - - } - - /** try to connect to the apg service */ - private boolean connect() { - if( LOCAL_LOGV ) Log.v(TAG, "trying to bind the apgService to context"); - - if (mApgService != null) { - if( LOCAL_LOGV ) Log.v(TAG, "allready connected"); - return true; - } - - try { - mContext.bindService(new Intent(IApgService2.class.getName()), mApgConnection, Context.BIND_AUTO_CREATE); - } catch (Exception e) { - Log.e(TAG, "could not bind APG service", e); - return false; - } - - int waitCount = 0; - while (mApgService == null && waitCount++ < secondsToWaitForConnection) { - if( LOCAL_LOGV ) Log.v(TAG, "sleeping 1 second to wait for apg"); - android.os.SystemClock.sleep(1000); - } - - if (waitCount >= secondsToWaitForConnection) { - if( LOCAL_LOGV ) Log.v(TAG, "slept waiting for nothing!"); - return false; - } - - return true; - } - - /** - * Disconnects ApgCon from Apg - * - *

- * This should be called whenever all work with APG is done (e.g. everything - * you wanted to encrypt is encrypted), since connections with AIDL should - * not be upheld indefinitely. - *

- * - *

- * Also, if you destroy you end using your ApgCon-instance, this must be - * called or else the connection to APG is leaked - *

- */ - public void disconnect() { - if( LOCAL_LOGV ) Log.v(TAG, "disconnecting apgService"); - if (mApgService != null) { - mContext.unbindService(mApgConnection); - mApgService = null; - } - } - - private boolean initialize() { - if (mApgService == null) { - if (!connect()) { - if( LOCAL_LOGV ) Log.v(TAG, "connection to apg service failed"); - return false; - } - } - return true; - } - - /** - * Calls a function from APG's AIDL-interface - * - *

- * After you have set up everything with {@link #setArg(String, String)} - * (and variants), you can call a function of the AIDL-interface. This - * will: - *

    - *
  • start connection to the remote interface (if not already connected)
  • - *
  • call the function passed with all parameters synchronously
  • - *
  • set up everything to retrieve the result and/or warnings/errors
  • - *
  • call the callback if provided - *
- *

- * - *

- * Note your thread will be blocked during execution - if you want to call - * the function asynchronously, see {@link #callAsync(String)}. - *

- * - * @param function - * a remote function to call - * @return true, if call successful (= no errors), else false - * - * @see #callAsync(String) - * @see #setArg(String, String) - * @see #setOnCallFinishListener(OnCallFinishListener) - */ - public boolean call(String function) { - boolean success = this.call(function, mArgs, mResult); - if (mOnCallFinishListener != null) { - try { - if( LOCAL_LOGD ) Log.d(TAG, "About to execute callback"); - mOnCallFinishListener.onCallFinish(mResult); - if( LOCAL_LOGD ) Log.d(TAG, "Callback executed"); - } catch (Exception e) { - Log.w(TAG, "Exception on callback: (" + e.getClass() + ") " + e.getMessage(), e); - mWarningList.add("(LOCAL) Could not execute callback (" + e.getClass() + "): " + e.getMessage()); - } - } - return success; - } - - /** - * Calls a function of remote interface asynchronously - * - *

- * This does exactly the same as {@link #call(String)}, but asynchronously. - * While connection to APG and work are done in background, your thread can - * go on executing. - *

- * - *

- * To see whether the task is finished, you have two possibilities: - *

    - *
  • In your thread, poll {@link #isRunning()}
  • - *
  • Supply a callback with {@link #setOnCallFinishListener(OnCallFinishListener)}
  • - *
- *

- * - * @param function - * a remote function to call - * - * @see #call(String) - * @see #isRunning() - * @see #setOnCallFinishListener(OnCallFinishListener) - */ - public void callAsync(String function) { - mAsyncRunning = true; - new CallAsync().execute(function); - } - - private boolean call(String function, Bundle pArgs, Bundle pReturn) { - - if (!initialize()) { - mErrorList.add("(LOCAL) Cannot bind to ApgService"); - mResult.putInt(ret.ERROR.name(), error.CANNOT_BIND_TO_APG.ordinal()); - return false; - } - - if (function == null || function.length() == 0) { - mErrorList.add("(LOCAL) Function to call missing"); - mResult.putInt(ret.ERROR.name(), error.CALL_MISSING.ordinal()); - return false; - } - - try { - Boolean success = (Boolean) IApgService2.class.getMethod(function, Bundle.class, Bundle.class).invoke(mApgService, pArgs, pReturn); - mErrorList.addAll(pReturn.getStringArrayList(ret.ERRORS.name())); - mWarningList.addAll(pReturn.getStringArrayList(ret.WARNINGS.name())); - return success; - } catch (NoSuchMethodException e) { - Log.e(TAG, "Remote call not known (" + function + "): " + e.getMessage(), e); - mErrorList.add("(LOCAL) Remote call not known (" + function + "): " + e.getMessage()); - mResult.putInt(ret.ERROR.name(), error.CALL_NOT_KNOWN.ordinal()); - return false; - } catch (InvocationTargetException e) { - Throwable orig = e.getTargetException(); - Log.w(TAG, "Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage(), orig); - mErrorList.add("(LOCAL) Exception of type '" + orig.getClass() + "' on AIDL call '" + function + "': " + orig.getMessage()); - return false; - } catch (Exception e) { - Log.e(TAG, "Generic error (" + e.getClass() + "): " + e.getMessage(), e); - mErrorList.add("(LOCAL) Generic error (" + e.getClass() + "): " + e.getMessage()); - mResult.putInt(ret.ERROR.name(), error.GENERIC.ordinal()); - return false; - } - - } - - /** - * Set a string argument for APG - * - *

- * This defines a string argument for APG's AIDL-interface. - *

- * - *

- * To know what key-value-pairs are possible (or required), take a look into - * the IApgService.aidl - *

- * - *

- * Note that parameters are not reseted after a call, so you have to - * reset ({@link #clearArgs()}) them manually if you want to. - *

- * - * - * @param key - * the key - * @param val - * the value - * - * @see #clearArgs() - */ - public void setArg(String key, String val) { - mArgs.putString(key, val); - } - - /** - * Set a string-array argument for APG - * - *

- * If the AIDL-parameter is an {@literal ArrayList}, you have to use - * this function. - *

- * - * - *
-     * setArg("a key", new String[]{ "entry 1", "entry 2" });
-     * 
- *
- * - * @param key - * the key - * @param vals - * the value - * - * @see #setArg(String, String) - */ - public void setArg(String key, String vals[]) { - ArrayList list = new ArrayList(); - for (String val : vals) { - list.add(val); - } - mArgs.putStringArrayList(key, list); - } - - /** - * Set up a boolean argument for APG - * - * @param key - * the key - * @param vals - * the value - * - * @see #setArg(String, String) - */ - public void setArg(String key, boolean val) { - mArgs.putBoolean(key, val); - } - - /** - * Set up a int argument for APG - * - * @param key - * the key - * @param vals - * the value - * - * @see #setArg(String, String) - */ - public void setArg(String key, int val) { - mArgs.putInt(key, val); - } - - /** - * Set up a int-array argument for APG - *

- * If the AIDL-parameter is an {@literal ArrayList}, you have to - * use this function. - *

- * - * @param key - * the key - * @param vals - * the value - * - * @see #setArg(String, String) - */ - public void setArg(String key, int vals[]) { - ArrayList list = new ArrayList(); - for (int val : vals) { - list.add(val); - } - mArgs.putIntegerArrayList(key, list); - } - - /** - * Set up binary data to en/decrypt - * - * @param is - * InputStream to get the data from - */ - public void setBlob(InputStream is) { - if( LOCAL_LOGD ) Log.d(TAG, "setBlob() called"); - // 1. get the new contentUri - ContentResolver cr = mContext.getContentResolver(); - Uri contentUri = cr.insert(Uri.parse(BLOB_URI), new ContentValues()); - - // 2. insert binary data - OutputStream os = null; - try { - os = cr.openOutputStream(contentUri, "w"); - } catch( Exception e ) { - Log.e(TAG, "... exception on setBlob", e); - } - - byte[] buffer = new byte[8]; - int len = 0; - try { - while( (len = is.read(buffer)) != -1) { - os.write(buffer, 0, len); - } - if(LOCAL_LOGD) Log.d(TAG, "... write finished, now closing"); - os.close(); - } catch (Exception e) { - Log.e(TAG, "... error on writing buffer", e); - } - - mArgs.putString("BLOB", contentUri.toString() ); - } - - /** - * Clears all arguments - * - *

- * Anything the has been set up with the various - * {@link #setArg(String, String)} functions is cleared. - *

- * - *

- * Note that any warning, error, callback, result, etc. is NOT cleared with - * this. - *

- * - * @see #reset() - */ - public void clearArgs() { - mArgs.clear(); - } - - /** - * Return the object associated with the key - * - * @param key - * the object's key you want to return - * @return an object at position key, or null if not set - */ - public Object getArg(String key) { - return mArgs.get(key); - } - - /** - * Iterates through the errors - * - *

- * With this method you can iterate through all errors. The errors are only - * returned once and deleted immediately afterwards, so you can only return - * each error once. - *

- * - * @return a human readable description of a error that happened, or null if - * no more errors - * - * @see #hasNextError() - * @see #clearErrors() - */ - public String getNextError() { - if (mErrorList.size() != 0) - return mErrorList.remove(0); - else - return null; - } - - /** - * Check if there are any new errors - * - * @return true, if there are unreturned errors, false otherwise - * - * @see #getNextError() - */ - public boolean hasNextError() { - return mErrorList.size() != 0; - } - - /** - * Get the numeric representation of the last error - * - *

- * Values <100 mean the error happened locally, values >=100 mean the error - * happened at the remote side (APG). See the IApgService.aidl (or get the - * human readable description with {@link #getNextError()}) for what - * errors >=100 mean. - *

- * - * @return the id of the error that happened - */ - public int getError() { - if (mResult.containsKey(ret.ERROR.name())) - return mResult.getInt(ret.ERROR.name()); - else - return -1; - } - - /** - * Iterates through the warnings - * - *

- * With this method you can iterate through all warnings. Warnings are - * only returned once and deleted immediately afterwards, so you can only - * return each warning once. - *

- * - * @return a human readable description of a warning that happened, or null - * if no more warnings - * - * @see #hasNextWarning() - * @see #clearWarnings() - */ - public String getNextWarning() { - if (mWarningList.size() != 0) - return mWarningList.remove(0); - else - return null; - } - - /** - * Check if there are any new warnings - * - * @return true, if there are unreturned warnings, false otherwise - * - * @see #getNextWarning() - */ - public boolean hasNextWarning() { - return mWarningList.size() != 0; - } - - /** - * Get the result - * - *

- * This gets your result. After doing an encryption or decryption with APG, - * you get the output with this function. - *

- * - *

- * Note when your last remote call is unsuccessful, the result will - * still have the same value like the last successful call (or null, if no - * call was successful). To ensure you do not work with old call's results, - * either be sure to {@link #reset()} (or at least {@link #clearResult()}) - * your instance before each new call or always check that - * {@link #hasNextError()} is false. - *

- * - *

- * Note: When handling binary data with {@link #setBlob(InputStream)}, you - * get your result with {@link #getBlobResult()}. - *

- * - * @return the mResult of the last {@link #call(String)} or - * {@link #callAsync(String)}. - * - * @see #reset() - * @see #clearResult() - * @see #getResultBundle() - * @see #getBlobResult() - */ - public String getResult() { - return mResult.getString(ret.RESULT.name()); - } - - /** - * Get the binary result - * - *

- * This gets your binary result. It only works if you called {@link #setBlob(InputStream)} before. - * - * If you did not call encrypt nor decrypt, this will be the same data as you inputed. - *

- * - * @return InputStream of the binary data which was en/decrypted - * - * @see #setBlob(InputStream) - * @see #getResult() - */ - public InputStream getBlobResult() { - if(mArgs.containsKey("BLOB")) { - ContentResolver cr = mContext.getContentResolver(); - InputStream in = null; - try { - in = cr.openInputStream(Uri.parse(mArgs.getString("BLOB"))); - } catch( Exception e ) { - Log.e(TAG, "Could not return blob in result", e); - } - return in; - } else { - return null; - } - } - - /** - * Get the result bundle - * - *

- * Unlike {@link #getResult()}, which only returns any en-/decrypted - * message, this function returns the complete information that was returned - * by Apg. This also includes the "RESULT", but additionally the warnings, - * errors and any other information. - *

- *

- * For warnings and errors it is suggested to use the functions that are - * provided here, namely {@link #getError()}, {@link #getNextError()}, - * {@link #get_next_Warning()} etc.), but if any call returns something non - * standard, you have access to the complete result bundle to extract the - * information. - *

- * - * @return the complete result bundle of the last call to apg - */ - public Bundle getResultBundle() { - return mResult; - } - - public error getConnectionStatus() { - return mConnectionStatus; - } - - /** - * Clears all unfetched errors - * - * @see #getNextError() - * @see #hasNextError() - */ - public void clearErrors() { - mErrorList.clear(); - mResult.remove(ret.ERROR.name()); - } - - /** - * Clears all unfetched warnings - * - * @see #getNextWarning() - * @see #hasNextWarning() - */ - public void clearWarnings() { - mWarningList.clear(); - } - - /** - * Clears the last mResult - * - * @see #getResult() - */ - public void clearResult() { - mResult.remove(ret.RESULT.name()); - } - - /** - * Set a callback listener when call to AIDL finishes - * - * @param obj - * a object to call back after async execution - * @see ApgConInterface - */ - public void setOnCallFinishListener(OnCallFinishListener lis) { - mOnCallFinishListener = lis; - } - - /** - * Clears any callback object - * - * @see #setOnCallFinishListener(OnCallFinishListener) - */ - public void clearOnCallFinishListener() { - mOnCallFinishListener = null; - } - - /** - * Checks if an async execution is running - * - *

- * If you started something with {@link #callAsync(String)}, this will - * return true if the task is still running - *

- * - * @return true, if an async task is still running, false otherwise - * - * @see #callAsync(String) - * - */ - public boolean isRunning() { - return mAsyncRunning; - } - - /** - * Completely resets your instance - * - *

- * This currently resets everything in this instance. Errors, warnings, - * results, callbacks, ... are removed. Any connection to the remote - * interface is upheld, though. - *

- * - *

- * Note when an async execution ({@link #callAsync(String)}) is - * running, it's result, warnings etc. will still be evaluated (which might - * be not what you want). Also mind that any callback you set is also - * reseted, so when finishing the execution any before defined callback will - * NOT BE TRIGGERED. - *

- */ - public void reset() { - clearErrors(); - clearWarnings(); - clearArgs(); - clearOnCallFinishListener(); - mResult.clear(); - } - -} diff --git a/org_apg/src/org/thialfihar/android/apg/util/ApgConInterface.java b/org_apg/src/org/thialfihar/android/apg/util/ApgConInterface.java deleted file mode 100644 index 406427231..000000000 --- a/org_apg/src/org/thialfihar/android/apg/util/ApgConInterface.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.util; - -public interface ApgConInterface { - public static interface OnCallFinishListener { - public abstract void onCallFinish(android.os.Bundle result); - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/util/Constants.java b/org_apg/src/org/thialfihar/android/apg/util/Constants.java deleted file mode 100644 index fac9be649..000000000 --- a/org_apg/src/org/thialfihar/android/apg/util/Constants.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.thialfihar.android.apg.util; - -public class Constants { - public static final String TAG = "APG"; - -} diff --git a/org_apg/src/org/thialfihar/android/apg/util/InputData.java b/org_apg/src/org/thialfihar/android/apg/util/InputData.java new file mode 100644 index 000000000..6b357e6de --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/util/InputData.java @@ -0,0 +1,40 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.util; + +import java.io.InputStream; + + +public class InputData { + private PositionAwareInputStream mInputStream; + private long mSize; + + public InputData(InputStream inputStream, long size) { + mInputStream = new PositionAwareInputStream(inputStream); + mSize = size; + } + + public InputStream getInputStream() { + return mInputStream; + } + + public long getSize() { + return mSize; + } + + public long getStreamPosition() { + return mInputStream.position(); + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/util/PositionAwareInputStream.java b/org_apg/src/org/thialfihar/android/apg/util/PositionAwareInputStream.java new file mode 100644 index 000000000..7850e2513 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/util/PositionAwareInputStream.java @@ -0,0 +1,81 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.util; + +import java.io.IOException; +import java.io.InputStream; + +public class PositionAwareInputStream extends InputStream { + private InputStream mStream; + private long mPosition; + + public PositionAwareInputStream(InputStream in) { + mStream = in; + mPosition = 0; + } + + @Override + public int read() throws IOException { + int ch = mStream.read(); + ++mPosition; + return ch; + } + + @Override + public int available() throws IOException { + return mStream.available(); + } + + @Override + public void close() throws IOException { + mStream.close(); + } + + @Override + public boolean markSupported() { + return false; + } + + @Override + public int read(byte[] b) throws IOException { + int result = mStream.read(b); + mPosition += result; + return result; + } + + @Override + public int read(byte[] b, int offset, int length) throws IOException { + int result = mStream.read(b, offset, length); + mPosition += result; + return result; + } + + @Override + public synchronized void reset() throws IOException { + mStream.reset(); + mPosition = 0; + } + + @Override + public long skip(long n) throws IOException { + long result = mStream.skip(n); + mPosition += result; + return result; + } + + public long position() { + return mPosition; + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/util/Primes.java b/org_apg/src/org/thialfihar/android/apg/util/Primes.java new file mode 100644 index 000000000..071673c13 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/util/Primes.java @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2010 Thialfihar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.util; + +import java.math.BigInteger; + +public final class Primes { + // taken from http://www.ietf.org/rfc/rfc3526.txt + public static final String P1536 = + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + + "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF"; + + public static final String P2048 = + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + + "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"; + + public static final String P3072 = + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + + "43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"; + + public static final String P4096 = + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" + + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" + + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" + + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" + + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" + + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" + + "FFFFFFFF FFFFFFFF"; + + public static final String P6144 = + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" + + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" + + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" + + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" + + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" + + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" + + "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" + + "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" + + "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" + + "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" + + "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" + + "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" + + "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" + + "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" + + "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" + + "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" + + "12BF2D5B 0B7474D6 E694F91E 6DCC4024 FFFFFFFF FFFFFFFF"; + + public static final String P8192 = + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" + + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" + + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" + + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" + + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" + + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" + + "36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" + + "F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" + + "179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" + + "DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" + + "5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" + + "D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" + + "23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" + + "CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" + + "06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" + + "DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" + + "12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" + + "38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" + + "741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" + + "3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" + + "22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" + + "4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" + + "062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" + + "4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" + + "B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" + + "4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" + + "9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" + + "60C980DD 98EDD3DF FFFFFFFF FFFFFFFF"; + + public static BigInteger getBestPrime(int keySize) { + String primeString; + if (keySize >= (8192 + 6144) / 2) { + primeString = P8192; + } else if (keySize >= (6144 + 4096) / 2) { + primeString = P6144; + } else if (keySize >= (4096 + 3072) / 2) { + primeString = P4096; + } else if (keySize >= (3072 + 2048) / 2) { + primeString = P3072; + } else if (keySize >= (2048 + 1536) / 2) { + primeString = P2048; + } else { + primeString = P1536; + } + + return new BigInteger(primeString.replaceAll(" ", ""), 16); + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/util/Utils.java b/org_apg/src/org/thialfihar/android/apg/util/Utils.java deleted file mode 100644 index d8b76ad33..000000000 --- a/org_apg/src/org/thialfihar/android/apg/util/Utils.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2012 Dominik Schürmann - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.util; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.Vector; - -import org.spongycastle.openpgp.PGPObjectFactory; -import org.spongycastle.openpgp.PGPSecretKey; -import org.spongycastle.openpgp.PGPSecretKeyRing; -import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.R; - -import android.app.Activity; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.util.Log; -import android.widget.Toast; - -public class Utils { - - /** - * Opens the file manager to select a file to open. - */ - public static void openFile(Activity activity, String filename, String type, int requestCode) { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - - intent.setData(Uri.parse("file://" + filename)); - intent.setType(type); - - try { - activity.startActivityForResult(intent, requestCode); - } catch (ActivityNotFoundException e) { - // No compatible file manager was found. - Toast.makeText(activity, R.string.noFilemanagerInstalled, Toast.LENGTH_SHORT).show(); - } - } - - /** - * Reads html files from /res/raw/example.html to output them as string. See - * http://www.monocube.com/2011/02/08/android-tutorial-html-file-in-webview/ - * - * @param context - * current context - * @param resourceID - * of html file to read - * @return content of html file with formatting - */ - public static String readContentFromResource(Context context, int resourceID) { - InputStream raw = context.getResources().openRawResource(resourceID); - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - int i; - try { - i = raw.read(); - while (i != -1) { - stream.write(i); - i = raw.read(); - } - raw.close(); - } catch (IOException e) { - e.printStackTrace(); - } - return stream.toString(); - } - - /** - * Return the number if days between two dates - * - * @param first - * @param second - * @return number of days - */ - public static long getNumDaysBetween(GregorianCalendar first, GregorianCalendar second) { - GregorianCalendar tmp = new GregorianCalendar(); - tmp.setTime(first.getTime()); - long numDays = (second.getTimeInMillis() - first.getTimeInMillis()) / 1000 / 86400; - tmp.add(Calendar.DAY_OF_MONTH, (int) numDays); - while (tmp.before(second)) { - tmp.add(Calendar.DAY_OF_MONTH, 1); - ++numDays; - } - return numDays; - } - - /** - * Converts Vector to a byte[] array to send it by intent to service - * - * @param keys - * @return - */ - public static byte[] PGPSecretKeyListToBytes(Vector keys) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - for (PGPSecretKey key : keys) { - try { - key.encode(os); - } catch (IOException e) { - Log.e(Constants.TAG, - "Error while converting PGPSecretKey to byte[]: " + e.getMessage()); - e.printStackTrace(); - } - } - - byte[] keysBytes = os.toByteArray(); - - return keysBytes; - } - - /** - * Convert from byte[] to ArrayList - * - * @param keysBytes - * @return - */ - public static PGPSecretKeyRing BytesToPGPSecretKeyRing(byte[] keysBytes) { - PGPObjectFactory factory = new PGPObjectFactory(keysBytes); - PGPSecretKeyRing keyRing = null; - try { - if ((keyRing = (PGPSecretKeyRing) factory.nextObject()) == null) { - Log.e(Constants.TAG, "No keys given!"); - } - } catch (IOException e) { - e.printStackTrace(); - } - - return keyRing; - } - - public static ArrayList BytesToPGPSecretKeyList(byte[] keysBytes) { - PGPSecretKeyRing keyRing = BytesToPGPSecretKeyRing(keysBytes); - ArrayList keys = new ArrayList(); - - Iterator itr = keyRing.getSecretKeys(); - while (itr.hasNext()) { - keys.add(itr.next()); - } - - return keys; - } - - public static PGPSecretKey BytesToPGPSecretKey(byte[] keyBytes) { - PGPSecretKey key = BytesToPGPSecretKeyList(keyBytes).get(0); - - return key; - } - - public static byte[] PGPSecretKeyToBytes(PGPSecretKey key) { - try { - return key.getEncoded(); - } catch (IOException e) { - Log.e(Constants.TAG, "Encoding failed: ", e); - - return null; - } - } - - public static byte[] PGPSecretKeyRingToBytes(PGPSecretKeyRing keyRing) { - try { - return keyRing.getEncoded(); - } catch (IOException e) { - Log.e(Constants.TAG, "Encoding failed: ", e); - - return null; - } - } - -} -- cgit v1.2.3