From 5e07d0c9e0ae81721ba33a66417f5f11e9e51676 Mon Sep 17 00:00:00 2001 From: Abdul Mannan Date: Tue, 15 Mar 2022 01:55:07 +0500 Subject: [PATCH] B B --- .idea/deploymentTargetDropDown.xml | 17 + app/build.gradle | 18 +- app/google-services.json | 2 +- app/src/main/AndroidManifest.xml | 7 +- .../externalURLNavigationContoller.java | 5 +- .../geckoManager/geckoClients.java | 4 + .../geckoManager/geckoSession.java | 174 ++++++--- .../geckoManager/mediaDelegate.java | 82 +++++ .../homeController/homeController.java | 19 +- .../homeController/homeViewController.java | 7 +- .../constants/constants.java | 9 +- .../constants/enums.java | 1 + .../constants/keys.java | 3 +- .../constants/status.java | 2 +- .../libs/fernet/Constants.java | 100 +++++ .../libs/fernet/IllegalTokenException.java | 37 ++ .../libs/fernet/Key.java | 343 ++++++++++++++++++ .../fernet/PayloadValidationException.java | 43 +++ .../libs/fernet/StringObjectValidator.java | 50 +++ .../libs/fernet/StringValidator.java | 51 +++ .../libs/fernet/Token.java | 326 +++++++++++++++++ .../libs/fernet/TokenExpiredException.java | 45 +++ .../libs/fernet/TokenValidationException.java | 42 +++ .../libs/fernet/Validator.java | 37 ++ .../libs/trueTime/trueTimeEncryption.java | 19 +- .../adPluginManager/admobManager.java | 114 ------ .../adPluginManager/mopubManager.java | 125 +++---- .../analyticManager.java | 2 +- .../messagePluginManager/messageManager.java | 3 + .../widgetManager/widgetModelController.java | 6 + .../res/layouts/home/layout/home_view.xml | 7 +- app/variables.gradle | 10 +- build.gradle | 2 +- orbotmanager/build.gradle | 30 +- .../android/service/OrbotService.java | 12 +- 35 files changed, 1447 insertions(+), 307 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/mediaDelegate.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Constants.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/IllegalTokenException.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Key.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/PayloadValidationException.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringObjectValidator.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringValidator.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Token.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenExpiredException.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenValidationException.java create mode 100644 app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Validator.java diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 00000000..7adba1ec --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index eb639259..25743929 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,10 +39,6 @@ android { } } - lintOptions { - checkReleaseBuilds project.ext.checkReleaseBuilds - abortOnError project.ext.abortOnError - } flavorDimensions project.ext.dimen @@ -102,23 +98,23 @@ dependencies { implementation "org.mozilla.components:browser-engine-gecko:75.0.0" implementation "org.mozilla.components:browser-icons:91.0.6" - implementation "org.mozilla.geckoview:geckoview: 97.0.20220202182137" + implementation "org.mozilla.geckoview:geckoview: 98.0.20220313140707" implementation "org.mozilla.components:concept-fetch:91.0.6" implementation "org.mozilla.components:concept-base:91.0.6" implementation "org.mozilla.components:support-utils:91.0.6" /*Crashlytics*/ - implementation 'com.flurry.android:analytics:12.13.0@aar' + implementation 'com.flurry.android:analytics:13.1.0@aar' /* Ads Manager */ implementation 'com.android.support:support-annotations:29.0.0' implementation 'com.facebook.android:audience-network-sdk:6.6.0' implementation 'com.mopub.mediation:facebookaudiencenetwork:6.6.0.0' - implementation('com.mopub:mopub-sdk:5.17.0@aar') { - transitive = true - } - + implementation 'com.applovin:applovin-sdk:+' + implementation 'com.applovin.mediation:facebook-adapter:+' + implementation 'com.android.support:recyclerview-v7:28.+' + implementation 'com.android.support:appcompat-v7:28.+' /* Crawler Service */ implementation 'org.jsoup:jsoup:1.13.1' @@ -142,8 +138,6 @@ dependencies { implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' implementation 'com.google.android.material:material:1.5.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'com.google.android.gms:play-services-ads:20.5.0' - implementation group: 'com.macasaet.fernet', name: 'fernet-java8', version: '1.4.2' implementation 'org.apache.commons:commons-text:1.3' } diff --git a/app/google-services.json b/app/google-services.json index 64ef9006..71935c15 100755 --- a/app/google-services.json +++ b/app/google-services.json @@ -10,7 +10,7 @@ "client_info": { "mobilesdk_app_id": "1:1026582312920:android:056aacc3b6f0c3b3f164ad", "android_client_info": { - "package_name": "com.hiddenservices.genesissearchengine.production" + "package_name": "com.darkweb.genesissearchengine.production" } }, "oauth_client": [ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0cefd8a0..76d407e7 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,12 +29,17 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true" tools:targetApi="n"> + + + - + diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/externalCommandManager/externalURLNavigationContoller.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/externalCommandManager/externalURLNavigationContoller.java index 7dd70a9c..1ca32232 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/externalCommandManager/externalURLNavigationContoller.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/externalCommandManager/externalURLNavigationContoller.java @@ -23,10 +23,13 @@ public class externalURLNavigationContoller extends AppCompatActivity { status.sExternalWebsite = strings.GENERIC_EMPTY_STR; Uri mData = externalURLNavigationContoller.this.getIntent().getData(); + if(mData.toString().contains("applovin")){ + helperMethod.openURLInCustomBrowser(mData.toString(), activityContextManager.getInstance().getHomeController()); + return; + } if(mData == null){ mData = Uri.parse(constants.CONST_BACKEND_GENESIS_URL); } - if(activityContextManager.getInstance().getHomeController()==null){ Intent mIntent = new Intent(this, homeController.class); mIntent.putExtra(EXTERNAL_SHORTCUT_COMMAND_NAVIGATE, mData.toString()); diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoClients.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoClients.java index f6160b22..dd976662 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoClients.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoClients.java @@ -368,6 +368,10 @@ public class geckoClients return mSession; } + public void onStopMedia(){ + mSession.onStopMedia(); + } + public void onUploadRequest(int resultCode,Intent data){ mSession.onFileUploadRequest(resultCode,data); } diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoSession.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoSession.java index e00011a0..5864502d 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoSession.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/geckoSession.java @@ -22,15 +22,12 @@ import android.util.Base64; import android.util.Log; import android.view.autofill.AutofillManager; import android.view.autofill.AutofillValue; - -import androidx.annotation.AnyThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.NotificationCompat; import androidx.core.content.FileProvider; - import com.hiddenservices.genesissearchengine.production.constants.constants; import com.hiddenservices.genesissearchengine.production.constants.enums; import com.hiddenservices.genesissearchengine.production.constants.keys; @@ -43,7 +40,6 @@ import com.hiddenservices.genesissearchengine.production.libs.trueTime.trueTimeE import com.hiddenservices.genesissearchengine.production.pluginManager.pluginController; import com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums; import com.example.myapplication.R; - import org.json.JSONException; import org.json.JSONObject; import org.mozilla.gecko.PrefsHelper; @@ -53,12 +49,12 @@ import org.mozilla.geckoview.Autofill; import org.mozilla.geckoview.GeckoResult; import org.mozilla.geckoview.GeckoSession; import org.mozilla.geckoview.GeckoView; +import org.mozilla.geckoview.MediaSession; import org.mozilla.geckoview.SlowScriptResponse; import org.mozilla.geckoview.WebExtension; import org.mozilla.geckoview.WebRequestError; import org.mozilla.geckoview.WebResponse; import org.orbotproject.android.service.wrapper.orbotLocalConstants; - import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; @@ -70,7 +66,6 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Objects; - import static com.hiddenservices.genesissearchengine.production.constants.constants.CONST_GENESIS_BADCERT_CACHED; import static com.hiddenservices.genesissearchengine.production.constants.constants.CONST_GENESIS_BADCERT_CACHED_DARK; import static com.hiddenservices.genesissearchengine.production.constants.constants.CONST_GENESIS_ERROR_CACHED; @@ -88,7 +83,7 @@ import static org.mozilla.geckoview.GeckoSessionSettings.USER_AGENT_MODE_DESKTOP import static org.mozilla.geckoview.GeckoSessionSettings.USER_AGENT_MODE_MOBILE; public class -geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSession.ScrollDelegate,GeckoSession.PermissionDelegate,GeckoSession.ProgressDelegate, GeckoSession.HistoryDelegate,GeckoSession.NavigationDelegate,GeckoSession.ContentDelegate +geckoSession extends GeckoSession implements MediaSession.Delegate,GeckoSession.MediaDelegate,GeckoSession.ScrollDelegate,GeckoSession.PermissionDelegate,GeckoSession.ProgressDelegate, GeckoSession.HistoryDelegate,GeckoSession.NavigationDelegate,GeckoSession.ContentDelegate { private eventObserver.eventListener event; @@ -99,6 +94,7 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes private boolean mFullScreen = false; private boolean isPageLoading = false; private int mProgress = 0; + private boolean isMediaRunning = false; private String mPrevURL = "about:blank"; private String mCurrentTitle = "loading"; private String mCurrentURL = "about:blank"; @@ -126,6 +122,7 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes public boolean mCloseRequested = false; public boolean mOnBackPressed = false; public SessionState mSessionState; + MediaSession.Delegate mMediaSession; geckoSession(eventObserver.eventListener event,String mSessionID,AppCompatActivity mContext, GeckoView pGeckoView){ @@ -142,12 +139,65 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes setAutoFillDelegate(); setPermissionDelegate(this); setScrollDelegate(this); + setMediaSessionDelegate(this); + + + setMediaDelegate(new mediaDelegate(mContext, mContext)); mDownloadManager = new geckoDownloadManager(); mSelectionActionDelegate = new selectionActionDelegate(mContext, true); setPromptDelegate(new geckoPromptView(mContext)); setSelectionActionDelegate(mSelectionActionDelegate); } + @Override + public void onActivated(@NonNull GeckoSession session, @NonNull MediaSession mediaSession) { + MediaSession.Delegate.super.onActivated(session, mediaSession); + } + + @Override + public void onDeactivated(@NonNull GeckoSession session, @NonNull MediaSession mediaSession) { + MediaSession.Delegate.super.onDeactivated(session, mediaSession); + isMediaRunning = false; + } + + @Override + public void onMetadata(@NonNull GeckoSession session, @NonNull MediaSession mediaSession, @NonNull MediaSession.Metadata meta) { + MediaSession.Delegate.super.onMetadata(session, mediaSession, meta); + } + + @Override + public void onFeatures(@NonNull GeckoSession session, @NonNull MediaSession mediaSession, long features) { + MediaSession.Delegate.super.onFeatures(session, mediaSession, features); + } + + @Override + public void onPlay(@NonNull GeckoSession session, @NonNull MediaSession mediaSession) { + MediaSession.Delegate.super.onPlay(session, mediaSession); + isMediaRunning = true; + } + + @Override + public void onPause(@NonNull GeckoSession session, @NonNull MediaSession mediaSession) { + MediaSession.Delegate.super.onPause(session, mediaSession); + isMediaRunning = false; + } + + @Override + public void onStop(@NonNull GeckoSession session, @NonNull MediaSession mediaSession) { + MediaSession.Delegate.super.onStop(session, mediaSession); + isMediaRunning = false; + } + + @Override + public void onPositionState(@NonNull GeckoSession session, @NonNull MediaSession mediaSession, @NonNull MediaSession.PositionState state) { + MediaSession.Delegate.super.onPositionState(session, mediaSession, state); + } + + @Override + public void onFullscreen(@NonNull GeckoSession session, @NonNull MediaSession mediaSession, boolean enabled, @Nullable @org.jetbrains.annotations.Nullable MediaSession.ElementMetadata meta) { + MediaSession.Delegate.super.onFullscreen(session, mediaSession, enabled, meta); + } + public void onDestroy(){ close(); setProgressDelegate(null); @@ -190,6 +240,12 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes Objects.requireNonNull(mPromptDelegate).onFileCallbackResult(resultCode,data); } + public void onStopMedia(){ + if(isMediaRunning){ + close(); + } + } + public void onSessionReinit(){ if(mClosed){ return; @@ -330,7 +386,7 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes PrefsHelper.setPref(keys.PROXY_SOCKS_REMOTE_DNS,true); if(mIsLoaded){ - if(helperMethod.getHost(var2).endsWith(".onion")){ + if(!var2.equals("about:blank") && helperMethod.getHost(var2).endsWith(".onion")){ var2 = var2.replace("www.",""); } @@ -545,10 +601,12 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes private String setGenesisVerificationToken(String pString){ try{ - Uri built = Uri.parse(pString).buildUpon() - .appendQueryParameter(constants.CONST_GENESIS_GMT_TIME_GET_KEY, trueTimeEncryption.getInstance().getSecretToken()) - .build(); - return built.toString(); + if (pString.contains("?")){ + pString += "&"+constants.CONST_GENESIS_GMT_TIME_GET_KEY+"="+trueTimeEncryption.getInstance().getSecretToken(); + }else { + pString += "?"+constants.CONST_GENESIS_GMT_TIME_GET_KEY+"="+trueTimeEncryption.getInstance().getSecretToken(); + } + return pString; }catch (Exception ex){ return pString; } @@ -657,53 +715,57 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes } - public GeckoResult onLoadError(@NonNull GeckoSession var1, @Nullable String var2, WebRequestError var3) { + public GeckoResult onLoadError(@NonNull GeckoSession var1, @Nullable String var2, @NonNull WebRequestError var3) { - if(helperMethod.getHost(var2).endsWith(".onion")){ - var2 = var2.replace("www.",""); - } - - if(var2.startsWith("https://trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd")){ - var2 = var2.replace("https","http"); - mCurrentURL = var2; - } - if(mCurrentURL.contains("genesis.onion")){ - event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, mTheme), enums.etype.M_NEW_IDENTITY); - } - if(status.sSettingIsAppStarted && orbotLocalConstants.mIsTorInitialized){ - errorHandler handler = new errorHandler(); - mProgress = 0; - mPreviousErrorPage = true; - event.invokeObserver(Arrays.asList(var2,mSessionID), enums.etype.on_load_error); - event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, mTheme), enums.etype.ON_UPDATE_THEME); - - InputStream mResourceURL = null; - try { - if(var3.code==50){ - if(status.sTheme == enums.Theme.THEME_LIGHT || helperMethod.isDayMode(mContext.get())){ - mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_BADCERT_CACHED); - }else { - mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_BADCERT_CACHED_DARK); - } - } - else { - if(status.sTheme == enums.Theme.THEME_LIGHT || helperMethod.isDayMode(mContext.get())){ - mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_ERROR_CACHED); - }else { - mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_ERROR_CACHED_DARK); - } - } - }catch (Exception ex){ - Log.i("asd","asd : " + ex.getMessage()); + try { + if(helperMethod.getHost(var2).endsWith(".onion")){ + var2 = var2.replace("www.",""); } - return GeckoResult.fromValue("data:text/html," + handler.createErrorPage(var3.category, var3.code,mContext.get(),var2, mResourceURL)); - }else { - event.invokeObserver(Arrays.asList(var2,mSessionID), enums.etype.M_ORBOT_LOADING); - mCurrentURL = mPrevURL; - event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, m_current_url_id, mTheme, this), enums.etype.ON_UPDATE_SEARCH_BAR); + if(var2.startsWith("https://trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd")){ + var2 = var2.replace("https","http"); + mCurrentURL = var2; + } + if(mCurrentURL.contains("genesis.onion")){ + event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, mTheme), enums.etype.M_NEW_IDENTITY); + } + if(status.sSettingIsAppStarted && orbotLocalConstants.mIsTorInitialized){ + errorHandler handler = new errorHandler(); + mProgress = 0; + mPreviousErrorPage = true; + event.invokeObserver(Arrays.asList(var2,mSessionID), enums.etype.on_load_error); + event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, mTheme), enums.etype.ON_UPDATE_THEME); + + InputStream mResourceURL = null; + try { + if(var3.code==50){ + if(status.sTheme == enums.Theme.THEME_LIGHT || helperMethod.isDayMode(mContext.get())){ + mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_BADCERT_CACHED); + }else { + mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_BADCERT_CACHED_DARK); + } + } + else { + if(status.sTheme == enums.Theme.THEME_LIGHT || helperMethod.isDayMode(mContext.get())){ + mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_ERROR_CACHED); + }else { + mResourceURL = mContext.get().getResources().getAssets().open(CONST_GENESIS_ERROR_CACHED_DARK); + } + } + }catch (Exception ex){ + Log.i("asd","asd : " + ex.getMessage()); + } + + return GeckoResult.fromValue("data:text/html," + handler.createErrorPage(var3.category, var3.code,mContext.get(),var2, mResourceURL)); + }else { + event.invokeObserver(Arrays.asList(var2,mSessionID), enums.etype.M_ORBOT_LOADING); + mCurrentURL = mPrevURL; + event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, m_current_url_id, mTheme, this), enums.etype.ON_UPDATE_SEARCH_BAR); + } + return null; + }catch (Exception ex){ + return null; } - return null; } /*Content Delegate*/ @@ -731,7 +793,7 @@ geckoSession extends GeckoSession implements GeckoSession.MediaDelegate,GeckoSes public void onFirstContentfulPaint(@NonNull GeckoSession var1) { isFirstPaintExecuted = true; - if(mPreviousErrorPage || mCurrentURL.contains("trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd.onion") || mCurrentURL.startsWith(CONST_GENESIS_URL_CACHED) || mCurrentURL.startsWith(CONST_GENESIS_URL_CACHED_DARK) || mCurrentURL.startsWith(CONST_GENESIS_HELP_URL_CACHE) || mCurrentURL.toString().startsWith(CONST_GENESIS_HELP_URL_CACHE_DARK)){ + if(mPreviousErrorPage || mCurrentURL.contains("trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd.onion") || mCurrentURL.startsWith(CONST_GENESIS_URL_CACHED) || mCurrentURL.startsWith(CONST_GENESIS_URL_CACHED_DARK) || mCurrentURL.startsWith(CONST_GENESIS_HELP_URL_CACHE) || mCurrentURL.startsWith(CONST_GENESIS_HELP_URL_CACHE_DARK)){ event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, false), enums.etype.M_ON_BANNER_UPDATE); }else { event.invokeObserver(Arrays.asList(mCurrentURL,mSessionID,mCurrentTitle, true), enums.etype.M_ON_BANNER_UPDATE); diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/mediaDelegate.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/mediaDelegate.java new file mode 100644 index 00000000..f828c30a --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/geckoManager/mediaDelegate.java @@ -0,0 +1,82 @@ +package com.hiddenservices.genesissearchengine.production.appManager.homeManager.geckoManager; + + +import static com.hiddenservices.genesissearchengine.production.appManager.homeManager.geckoManager.geckoPromptView.LOGTAG; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + +import com.example.myapplication.R; + +import org.mozilla.geckoview.GeckoSession; + +class mediaDelegate implements GeckoSession.MediaDelegate { + private Integer mLastNotificationId = 100; + private Integer mNotificationId; + private final Activity mActivity; + private Context mContext; + + public mediaDelegate(Activity activity, Context pContext) { + mActivity = activity; + mContext = pContext; + } + + @Override + public void onRecordingStatusChanged(@NonNull GeckoSession session, RecordingDevice[] devices) { + String message; + int icon; + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mActivity); + RecordingDevice camera = null; + RecordingDevice microphone = null; + + for (RecordingDevice device : devices) { + if (device.type == RecordingDevice.Type.CAMERA) { + camera = device; + } else if (device.type == RecordingDevice.Type.MICROPHONE) { + microphone = device; + } + } + if (camera != null && microphone != null) { + Log.d(LOGTAG, "ExampleDeviceDelegate:onRecordingDeviceEvent display alert_mic_camera"); + message = "Microphone and Camera is on"; + } else if (camera != null) { + Log.d(LOGTAG, "ExampleDeviceDelegate:onRecordingDeviceEvent display alert_camera"); + message = "Camera is on"; + } else if (microphone != null) { + Log.d(LOGTAG, "ExampleDeviceDelegate:onRecordingDeviceEvent display alert_mic"); + message = "Microphone is on"; + } else { + Log.d(LOGTAG, "ExampleDeviceDelegate:onRecordingDeviceEvent dismiss any notifications"); + if (mNotificationId != null) { + notificationManager.cancel(mNotificationId); + mNotificationId = null; + } + return; + } + if (mNotificationId == null) { + mNotificationId = ++mLastNotificationId; + } + + Intent intent = new Intent(mActivity, mediaDelegate.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + PendingIntent pendingIntent = + PendingIntent.getActivity(mActivity.getApplicationContext(), 0, intent, 0); + + NotificationCompat.Builder builder = + new NotificationCompat.Builder(mActivity.getApplicationContext(), "GeckoChannel") + .setContentTitle("Genesis Browser") + .setContentText(message) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setContentIntent(pendingIntent) + .setCategory(NotificationCompat.CATEGORY_SERVICE); + + notificationManager.notify(mNotificationId, builder.build()); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeController.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeController.java index 61233278..c49d2876 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeController.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeController.java @@ -46,6 +46,8 @@ import androidx.core.widget.NestedScrollView; import androidx.fragment.app.FragmentContainerView; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; + +import com.applovin.mediation.ads.MaxAdView; import com.hiddenservices.genesissearchengine.production.appManager.activityContextManager; import com.hiddenservices.genesissearchengine.production.appManager.bookmarkManager.bookmarkSettings.bookmarkSettingController; import com.hiddenservices.genesissearchengine.production.appManager.bookmarkManager.bookmarkHome.bookmarkController; @@ -77,7 +79,6 @@ import com.hiddenservices.genesissearchengine.production.libs.trueTime.trueTimeE import com.hiddenservices.genesissearchengine.production.pluginManager.pluginController; import com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums; import com.example.myapplication.R; -import com.mopub.mobileads.MoPubView; import com.widget.Genesis.widgetManager.widgetController; import org.mozilla.geckoview.ContentBlocking; @@ -88,7 +89,6 @@ import org.orbotproject.android.service.util.Prefs; import org.orbotproject.android.service.wrapper.LocaleHelper; import org.orbotproject.android.service.wrapper.orbotLocalConstants; import java.lang.ref.WeakReference; -import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -150,7 +150,7 @@ public class homeController extends AppCompatActivity implements ComponentCallba private ImageView mLoadingIcon; private ImageView mBlocker; private TextView mLoadingText; - private MoPubView mBannerAds = null; + private MaxAdView mBannerAds = null; private ImageButton mGatewaySplash; private ImageButton mPanicButton; private ImageButton mPanicButtonLandscape; @@ -549,10 +549,10 @@ public class homeController extends AppCompatActivity implements ComponentCallba Method method = Objects.requireNonNull(clazz.getSuperclass()).getDeclaredMethod("stop"); method.setAccessible(true); - Field field = clazz.getDeclaredField("INSTANCE"); - field.setAccessible(true); + // Field field = clazz.getDeclaredField("INSTANCE"); + // field.setAccessible(true); - method.invoke(field.get(null)); + // method.invoke(field.get(null)); } catch (Throwable e) { e.printStackTrace(); @@ -1460,6 +1460,11 @@ public class homeController extends AppCompatActivity implements ComponentCallba mSearchbar.clearFocus(); mHomeViewController.onUpdateSearchBar(mGeckoClient.getSession().getCurrentURL(),false,false, true); + + if (mGeckoClient.getSession()!=null && mGeckoClient!=null) { + mGeckoClient.onStopMedia(); + } + } @Override @@ -1699,7 +1704,7 @@ public class homeController extends AppCompatActivity implements ComponentCallba mGeckoClient.manualDownloadWithName(pURL,pPath,this); } - public MoPubView getBannerAd() + public MaxAdView getBannerAd() { return mBannerAds; } diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeViewController.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeViewController.java index 70d6d3fb..2cf70db5 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeViewController.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/appManager/homeManager/homeController/homeViewController.java @@ -41,6 +41,8 @@ import androidx.core.graphics.ColorUtils; import androidx.core.widget.NestedScrollView; import androidx.fragment.app.FragmentContainerView; import androidx.recyclerview.widget.RecyclerView; + +import com.applovin.mediation.ads.MaxAdView; import com.hiddenservices.genesissearchengine.production.constants.*; import com.hiddenservices.genesissearchengine.production.dataManager.dataController; import com.hiddenservices.genesissearchengine.production.dataManager.dataEnums; @@ -49,7 +51,6 @@ import com.hiddenservices.genesissearchengine.production.eventObserver; import com.hiddenservices.genesissearchengine.production.helperManager.helperMethod; import com.example.myapplication.R; import com.google.android.material.appbar.AppBarLayout; -import com.mopub.mobileads.MoPubView; import org.mozilla.geckoview.GeckoView; import org.orbotproject.android.service.wrapper.orbotLocalConstants; import java.util.Arrays; @@ -76,7 +77,7 @@ class homeViewController private editTextManager mSearchbar; private ConstraintLayout mSplashScreen; private TextView mLoadingText; - private MoPubView mBannerAds = null; + private MaxAdView mBannerAds = null; private Handler mUpdateUIHandler = null; private ImageButton mGatewaySplash; private LinearLayout mTopBar; @@ -117,7 +118,7 @@ class homeViewController private MovementMethod mSearchBarMovementMethod = null; private boolean mIsTopBarExpanded = true; - void initialization(eventObserver.eventListener event, AppCompatActivity context, Button mNewTab, ConstraintLayout webviewContainer, TextView loadingText, ProgressBar progressBar, editTextManager searchbar, ConstraintLayout splashScreen, ImageView loading, MoPubView banner_ads, ImageButton gateway_splash, LinearLayout top_bar, GeckoView gecko_view, ImageView backsplash, Button connect_button, View pFindBar, EditText pFindText, TextView pFindCount, androidx.constraintlayout.widget.ConstraintLayout pTopLayout, ImageButton pVoiceInput, ImageButton pMenu, androidx.core.widget.NestedScrollView pNestedScroll, ImageView pBlocker, ImageView pBlockerFullSceen, View mSearchEngineBar, TextView pCopyright, RecyclerView pHistListView, com.google.android.material.appbar.AppBarLayout pAppBar, ImageButton pOrbotLogManager, ConstraintLayout pInfoLandscape, ConstraintLayout pInfoPortrait, ProgressBar pProgressBarIndeterminate, FragmentContainerView pTabFragment, LinearLayout pTopBarContainer, ImageView pSearchLock, ImageView pTopBarHider, ImageView pNewTabBlocker, CoordinatorLayout mCoordinatorLayout, ImageView pImageDivider, ImageButton pPanicButton, ImageView pGenesisLogo, ImageButton pPanicButtonLandscape){ + void initialization(eventObserver.eventListener event, AppCompatActivity context, Button mNewTab, ConstraintLayout webviewContainer, TextView loadingText, ProgressBar progressBar, editTextManager searchbar, ConstraintLayout splashScreen, ImageView loading, MaxAdView banner_ads, ImageButton gateway_splash, LinearLayout top_bar, GeckoView gecko_view, ImageView backsplash, Button connect_button, View pFindBar, EditText pFindText, TextView pFindCount, androidx.constraintlayout.widget.ConstraintLayout pTopLayout, ImageButton pVoiceInput, ImageButton pMenu, androidx.core.widget.NestedScrollView pNestedScroll, ImageView pBlocker, ImageView pBlockerFullSceen, View mSearchEngineBar, TextView pCopyright, RecyclerView pHistListView, com.google.android.material.appbar.AppBarLayout pAppBar, ImageButton pOrbotLogManager, ConstraintLayout pInfoLandscape, ConstraintLayout pInfoPortrait, ProgressBar pProgressBarIndeterminate, FragmentContainerView pTabFragment, LinearLayout pTopBarContainer, ImageView pSearchLock, ImageView pTopBarHider, ImageView pNewTabBlocker, CoordinatorLayout mCoordinatorLayout, ImageView pImageDivider, ImageButton pPanicButton, ImageView pGenesisLogo, ImageButton pPanicButtonLandscape){ this.mContext = context; this.mProgressBar = progressBar; this.mSearchbar = searchbar; diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/constants.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/constants.java index 85132e3a..c8403277 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/constants.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/constants.java @@ -5,13 +5,14 @@ public class constants /*LOCAL URL CONSTANTS*/ public static final String CONST_PLAYSTORE_URL = "http://play.google.com/store/apps/details?id=com.hiddenservices.genesissearchengine.production"; - public static final String CONST_AMAZON_URL = "http://www.amazon.com/gp/mas/dl/android?p=com.hiddenservices.genesissearchengine.production"; - public static final String CONST_SAMSUNG_URL = "http://www.samsungapps.com/appquery/appDetail.as?appId=com.hiddenservices.genesissearchengine.production"; + public static final String CONST_AMAZON_URL = "http://www.amazon.com/gp/mas/dl/android?p=com.darkweb.genesissearchengine.production"; + public static final String CONST_SAMSUNG_URL = "http://www.samsungapps.com/appquery/appDetail.as?appId=com.darkweb.genesissearchengine.production"; + public static final String CONST_HUAWEI_URL = "https://appgallery.cloud.huawei.com/uowap/index.html#/detailApp/C105664271?appId=C105664271"; public static final String CONST_PRIVACY_POLICY_URL = "http://trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd.onion/privacy"; - public static final String CONST_REPORT_URL = "http://trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd.onion/reportus?url="; + public static final String CONST_REPORT_URL = "http://trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd.onion/report?url="; public static final String CONST_SITEMAP = "http://trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd.onion/create"; - public static final String CONST_PACKAGE_NAME = "com.hiddenservices.genesissearchengine.production"; + public static final String CONST_PACKAGE_NAME = "com.darkweb.genesissearchengine.production"; public static final String CONST_GENESIS_ONION = "genesis.onion"; public static final String CONST_GENESIS_ONION_V2 = "trcip42ymcgvv5hsa7nxpwdnott46ebomnn5pm5lovg5hpszyo4n35yd.onion"; diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/enums.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/enums.java index 6b6cded2..718beee6 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/enums.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/enums.java @@ -16,6 +16,7 @@ public class enums public static final int GOOGLE_PLAY = 0; public static final int AMAZON = 1; public static final int SAMSUNG = 2; + public static final int HUAWEI = 0; } public static class AddTabCallback { diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/keys.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/keys.java index f8dd55e6..076c591b 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/keys.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/keys.java @@ -83,7 +83,6 @@ public class keys public static final String EXTERNAL_SHORTCUT_COMMAND_NAVIGATE = "EXTERNAL_SHORTCUT_COMMAND"; /*Admanager*/ - public static final String ADMANAGER_APPID_KEY = "c122efbe224f46678800d2f73389d258"; - + public static final String ADMANAGER_APPID_KEY = "6afabb72c853c683"; } diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/status.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/status.java index a701a0e5..5d3b1539 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/status.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/constants/status.java @@ -18,7 +18,7 @@ public class status public static boolean sPaidStatus = false; public static boolean sDeveloperBuild = false; - public static int sStoreType = enums.StoreType.GOOGLE_PLAY; + public static int sStoreType = enums.StoreType.SAMSUNG; /*Settings Status*/ public static Locale mSystemLocale = null; diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Constants.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Constants.java new file mode 100644 index 00000000..05e28772 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Constants.java @@ -0,0 +1,100 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 + + https://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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Base64.getUrlDecoder; +import static java.util.Base64.getUrlEncoder; + +import java.nio.charset.Charset; +import java.util.Base64.Decoder; +import java.util.Base64.Encoder; + +import javax.crypto.Cipher; + +/** + * This contains common values used throughout the framework. + * + *

Copyright © 2017 Carlos Macasaet.

+ * @author Carlos Macasaet + */ +class Constants { + + static final Charset charset = UTF_8; + /** + * The algorithm used to encrypt the token contents. + */ + static final String encryptionAlgorithm = "AES"; + /** + * The algorithm used to sign the token. + */ + static final String signingAlgorithm = "HmacSHA256"; + /** + * The number of bytes used to store the encryption initialisation vector + */ + static final int initializationVectorBytes = 16; + /** + * The number of bytes used to store the timestamp of a Fernet token. + */ + static final int timestampBytes = 8; + /** + * The number of bytes used to indicate the version of a Fernet token. + */ + static final int versionBytes = 1; + /** + * The number of bytes before the cipher text portion of a Fernet token. + */ + static final int tokenPrefixBytes = versionBytes + timestampBytes + initializationVectorBytes; + /** + * The number of bytes in a valid signing key. + */ + static final int signingKeyBytes = 16; + /** + * The number of bytes in a valid encryption key. + */ + static final int encryptionKeyBytes = 16; + /** + * The total number of bytes in a valid Fernet key. + */ + static final int fernetKeyBytes = signingKeyBytes + encryptionKeyBytes; + /** + * The AES block size used by the cipher. + */ + static final int cipherTextBlockSize = 16; + /** + * The transformation (algorithm, mode, and padding) used by the cipher. + * + * @see Cipher#getInstance(String) + */ + static final String cipherTransformation = encryptionAlgorithm + "/CBC/PKCS5Padding"; + /** + * The number of bytes for the HMAC signature. + */ + static final int signatureBytes = 32; + /** + * The Fernet token version supported by this library. + */ + static final byte supportedVersion = (byte) 0x80; + /** + * The number of bytes in the static portion of the token (excludes cipher text). + */ + static final int tokenStaticBytes = versionBytes + timestampBytes + initializationVectorBytes + signatureBytes; + /** + * The minimum number of bytes in a token (i.e. with an empty plaintext). + */ + static final int minimumTokenBytes = tokenStaticBytes + cipherTextBlockSize; + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/IllegalTokenException.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/IllegalTokenException.java new file mode 100644 index 00000000..58896c21 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/IllegalTokenException.java @@ -0,0 +1,37 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +/** + * This exception indicates that a Fernet token could not be created because one or more of the parameters was invalid. + * + *

Copyright © 2017 Carlos Macasaet.

+ * + * @author Carlos Macasaet + */ +public class IllegalTokenException extends IllegalArgumentException { + + private static final long serialVersionUID = -1794971941479648725L; + + public IllegalTokenException(final String message) { + super(message); + } + + public IllegalTokenException(final String message, final Throwable cause) { + super(message, cause); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Key.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Key.java new file mode 100644 index 00000000..8bba8494 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Key.java @@ -0,0 +1,343 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 + + https://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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.cipherTransformation; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.encryptionAlgorithm; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.encryptionKeyBytes; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.fernetKeyBytes; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.signingAlgorithm; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.signingKeyBytes; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.tokenPrefixBytes; +import static java.util.Arrays.copyOf; +import static java.util.Arrays.copyOfRange; +import static javax.crypto.Cipher.DECRYPT_MODE; +import static javax.crypto.Cipher.ENCRYPT_MODE; + +import android.util.Base64; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.time.Instant; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.Mac; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * A Fernet shared secret key. + * + *

Copyright © 2017 Carlos Macasaet.

+ * + * @author Carlos Macasaet + */ +@SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods"}) +public class Key { + + private byte[] signingKey; + private byte[] encryptionKey; + + /** + * Create a Key from individual components. + * + * @param signingKey + * a 128-bit (16 byte) key for signing tokens. + * @param encryptionKey + * a 128-bit (16 byte) key for encrypting and decrypting token contents. + */ + public Key(final byte[] signingKey, final byte[] encryptionKey) { + if (signingKey == null || signingKey.length != signingKeyBytes) { + throw new IllegalArgumentException("Signing key must be 128 bits"); + } + if (encryptionKey == null || encryptionKey.length != encryptionKeyBytes) { + throw new IllegalArgumentException("Encryption key must be 128 bits"); + } + this.signingKey = copyOf(signingKey, signingKeyBytes); + this.encryptionKey = copyOf(encryptionKey, encryptionKeyBytes); + } + + /** + * Create a Key from a payload containing the signing and encryption + * key. + * + * @param concatenatedKeys an array of 32 bytes of which the first 16 is + * the signing key and the last 16 is the + * encryption/decryption key + */ + public Key(final byte[] concatenatedKeys) { + this(copyOfRange(concatenatedKeys, 0, signingKeyBytes), + copyOfRange(concatenatedKeys, signingKeyBytes, fernetKeyBytes)); + } + + /** + * @param string + * a Base 64 URL string in the format Signing-key (128 bits) || Encryption-key (128 bits) + */ + public Key(final String string) { + this(android.util.Base64.decode(string, Base64.DEFAULT)); + } + + /** + * Generate a random key + * + * @return a new shared secret key + */ + public static Key generateKey() { + return generateKey(new SecureRandom()); + } + + /** + * Generate a random key + * + * @param random + * source of entropy + * @return a new shared secret key + */ + public static Key generateKey(final SecureRandom random) { + final byte[] signingKey = new byte[signingKeyBytes]; + random.nextBytes(signingKey); + final byte[] encryptionKey = new byte[encryptionKeyBytes]; + random.nextBytes(encryptionKey); + return new Key(signingKey, encryptionKey); + } + + /** + * Generate an HMAC SHA-256 signature from the components of a Fernet token. + * + * @param version + * the Fernet version number + * @param timestamp + * the seconds after the epoch that the token was generated + * @param initializationVector + * the encryption and decryption initialization vector + * @param cipherText + * the encrypted content of the token + * @return the HMAC signature + */ + public byte[] sign(final byte version, final Instant timestamp, final IvParameterSpec initializationVector, + final byte[] cipherText) { + try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream( + getTokenPrefixBytes() + cipherText.length)) { + return sign(version, timestamp, initializationVector, cipherText, byteStream); + } catch (final IOException e) { + // this should not happen as I/O is to memory only + throw new IllegalStateException(e.getMessage(), e); + } + } + + /** + * Encrypt a payload to embed in a Fernet token + * + * @param payload the raw bytes of the data to store in a token + * @param initializationVector random bytes from a high-entropy source to initialise the AES cipher + * @return the AES-encrypted payload. The length will always be a multiple of 16 (128 bits). + * @see #decrypt(byte[], IvParameterSpec) + */ + @SuppressWarnings("PMD.LawOfDemeter") + public byte[] encrypt(final byte[] payload, final IvParameterSpec initializationVector) { + final SecretKeySpec encryptionKeySpec = getEncryptionKeySpec(); + try { + final Cipher cipher = Cipher.getInstance(cipherTransformation); + cipher.init(ENCRYPT_MODE, encryptionKeySpec, initializationVector); + return cipher.doFinal(payload); + } catch (final NoSuchAlgorithmException | NoSuchPaddingException e) { + // these should not happen as we use an algorithm (AES) and padding (PKCS5) that are guaranteed to exist + throw new IllegalStateException("Unable to access cipher " + cipherTransformation + ": " + e.getMessage(), e); + } catch (final InvalidKeyException | InvalidAlgorithmParameterException e) { + // this should not happen as the key is validated ahead of time and + // we use an algorithm guaranteed to exist + throw new IllegalStateException( + "Unable to initialise encryption cipher with algorithm " + encryptionKeySpec.getAlgorithm() + + " and format " + encryptionKeySpec.getFormat() + ": " + e.getMessage(), + e); + } catch (final IllegalBlockSizeException | BadPaddingException e) { + // these should not happen as we control the block size and padding + throw new IllegalStateException("Unable to encrypt data: " + e.getMessage(), e); + } + } + + /** + *

Decrypt the payload of a Fernet token.

+ * + *

Warning: Do not call this unless the cipher text has first been verified. Attempting to decrypt a cipher text + * that has been tampered with will leak whether or not the padding is correct and this can be used to decrypt + * stolen cipher text.

+ * + * @param cipherText + * the verified padded encrypted payload of a token. The length must be a multiple of 16 (128 + * bits). + * @param initializationVector + * the random bytes used in the AES encryption of the token + * @return the decrypted payload + * @see Key#encrypt(byte[], IvParameterSpec) + */ + @SuppressWarnings("PMD.LawOfDemeter") + protected byte[] decrypt(final byte[] cipherText, final IvParameterSpec initializationVector) { + try { + final Cipher cipher = Cipher.getInstance(getCipherTransformation()); + cipher.init(DECRYPT_MODE, getEncryptionKeySpec(), initializationVector); + return cipher.doFinal(cipherText); + } catch (final NoSuchAlgorithmException | NoSuchPaddingException + | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException e) { + // this should not happen as we use an algorithm (AES) and padding + // (PKCS5) that are guaranteed to exist. + // in addition, we validate the encryption key and initialization vector up front + throw new IllegalStateException(e.getMessage(), e); + } catch (final BadPaddingException bpe) { + throw new TokenValidationException("Invalid padding in token: " + bpe.getMessage(), bpe); + } + } + + /** + * @return the Base 64 URL representation of this Fernet key + */ + @SuppressWarnings("PMD.LawOfDemeter") + public String serialise() { + try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream(fernetKeyBytes)) { + writeTo(byteStream); + return android.util.Base64.encodeToString(byteStream.toByteArray(), Base64.DEFAULT); + } catch (final IOException ioe) { + // this should not happen as I/O is to memory + throw new IllegalStateException(ioe.getMessage(), ioe); + } + } + + /** + * Write the raw bytes of this key to the specified output stream. + * + * @param outputStream + * the target + * @throws IOException + * if the underlying I/O device cannot be written to + */ + public void writeTo(final OutputStream outputStream) throws IOException { + outputStream.write(getSigningKey()); + outputStream.write(getEncryptionKey()); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(getSigningKey()); + result = prime * result + Arrays.hashCode(getEncryptionKey()); + return result; + } + + @SuppressWarnings("PMD.LawOfDemeter") + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Key)) { + return false; + } + final Key other = (Key) obj; + + return MessageDigest.isEqual(getSigningKey(), other.getSigningKey()) + && MessageDigest.isEqual(getEncryptionKey(), other.getEncryptionKey()); + } + + @SuppressWarnings("PMD.LawOfDemeter") + protected byte[] sign(final byte version, final Instant timestamp, final IvParameterSpec initializationVector, + final byte[] cipherText, final ByteArrayOutputStream byteStream) + throws IOException { + try (DataOutputStream dataStream = new DataOutputStream(byteStream)) { + long mTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); + dataStream.writeByte(version); + dataStream.writeLong(mTime); + dataStream.write(initializationVector.getIV()); + dataStream.write(cipherText); + + try { + final Mac mac = Mac.getInstance(getSigningAlgorithm()); + mac.init(getSigningKeySpec()); + return mac.doFinal(byteStream.toByteArray()); + } catch (final InvalidKeyException ike) { + // this should not happen because we control the signing key + // algorithm and pre-validate the length + throw new IllegalStateException("Unable to initialise HMAC with shared secret: " + ike.getMessage(), + ike); + } catch (final NoSuchAlgorithmException nsae) { + // this should not happen as implementors are required to + // provide the HmacSHA256 algorithm. + throw new IllegalStateException(nsae.getMessage(), nsae); + } + } + } + + /** + * @return an HMAC SHA-256 key for signing the token + */ + protected java.security.Key getSigningKeySpec() { + return new SecretKeySpec(getSigningKey(), getSigningAlgorithm()); + } + + /** + * @return the AES key for encrypting and decrypting the token payload + */ + protected SecretKeySpec getEncryptionKeySpec() { + return new SecretKeySpec(getEncryptionKey(), getEncryptionAlgorithm()); + } + + /** + * Warning: Modifying the returned byte array will write through to this object. + * + * @return the raw underlying signing key bytes + */ + @SuppressWarnings("PMD.MethodReturnsInternalArray") + protected byte[] getSigningKey() { + return signingKey; + } + + /** + * Warning: Modifying the returned byte array will write through to this object. + * + * @return the raw underlying encryption key bytes + */ + @SuppressWarnings("PMD.MethodReturnsInternalArray") + protected byte[] getEncryptionKey() { + return encryptionKey; + } + + protected int getTokenPrefixBytes() { + return tokenPrefixBytes; + } + + protected String getSigningAlgorithm() { + return signingAlgorithm; + } + + protected String getEncryptionAlgorithm() { + return encryptionAlgorithm; + } + + protected String getCipherTransformation() { + return cipherTransformation; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/PayloadValidationException.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/PayloadValidationException.java new file mode 100644 index 00000000..ddafbdad --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/PayloadValidationException.java @@ -0,0 +1,43 @@ +/** + Copyright 2018 Carlos Macasaet + + 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 + + https://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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +import com.hiddenservices.genesissearchengine.production.libs.fernet.TokenValidationException; + +/** + * This exception indicates that a Fernet token is valid, but the payload inside fails business logic validation. + * + *

Copyright © 2018 Carlos Macasaet.

+ * + * @author Carlos Macasaet + */ +public class PayloadValidationException extends TokenValidationException { + + private static final long serialVersionUID = -2067765218609208844L; + + public PayloadValidationException(final String message) { + super(message); + } + + public PayloadValidationException(final Throwable cause) { + super(cause.getMessage(), cause); + } + + public PayloadValidationException(final String message, final Throwable cause) { + super(message, cause); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringObjectValidator.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringObjectValidator.java new file mode 100644 index 00000000..9545cc97 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringObjectValidator.java @@ -0,0 +1,50 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 com.hiddenservices.genesissearchengine.production.libs.fernet; + + +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.hiddenservices.genesissearchengine.production.libs.fernet.Validator; + +import java.nio.charset.Charset; +import java.util.function.Function; + +public interface StringObjectValidator extends Validator { + + default Charset getCharset() { + return UTF_8; + } + + /** + * Override this to specify an alternative way to convert binary data into a String. The default implementation uses + * the UTF-8 character set. + * + * @return a method for converting a byte array into a String + */ + default Function getStringCreator() { + return bytes -> new String(bytes, getCharset()); + } + + + /** + * Plug in your String deserialisation method here. + * + * @return a method for converting a String into an Object. + */ + Function getStringTransformer(); + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringValidator.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringValidator.java new file mode 100644 index 00000000..d5906376 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/StringValidator.java @@ -0,0 +1,51 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.charset; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.hiddenservices.genesissearchengine.production.libs.fernet.StringObjectValidator; + +import java.nio.charset.Charset; +import java.util.function.Function; + +/** + * A {@link com.macasaet.fernet.Validator} for String payloads. This is useful if your + * payload contains unique identifiers like user names. If the payload + * is a structured String like JSON or XML, use {@link com.macasaet.fernet.Validator} or + * {@link StringObjectValidator} instead. + * + *

Copyright © 2017 Carlos Macasaet.

+ * + * @author Carlos Macasaet + */ +public interface StringValidator extends Validator { + + default Charset getCharset() { + return UTF_8; + } + + default Function getTransformer() { + return bytes -> { + final String retval = new String(bytes, getCharset()); + for (int i = bytes.length; --i >= 0; bytes[i] = 0); + return retval; + }; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Token.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Token.java new file mode 100644 index 00000000..da9ed590 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Token.java @@ -0,0 +1,326 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.charset; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.cipherTextBlockSize; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.initializationVectorBytes; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.minimumTokenBytes; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.signatureBytes; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.supportedVersion; +import static com.hiddenservices.genesissearchengine.production.libs.fernet.Constants.tokenStaticBytes; + +import android.util.Base64; + + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.time.Instant; +import java.util.Base64.Encoder; +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +import javax.crypto.spec.IvParameterSpec; + +/** + * A Fernet token. + * + *

Copyright © 2017 Carlos Macasaet.

+ * + * @author Carlos Macasaet + */ +@SuppressWarnings({"PMD.TooManyMethods", "PMD.AvoidDuplicateLiterals"}) +/* + * TooManyMethods can be avoided by making the following API-breaking changes: + * * remove the static `generate` methods and introduce a `TokenFactory` or `TokenBuilder` + * * remove the public `validateAndDecrypt` methods since they are already available in the `Validator` interface + * + * AvoidDuplicateLiterals is from the method-level @SuppressWarnings annotations + */ +public class Token { + + private final byte version; + private final Instant timestamp; + private final IvParameterSpec initializationVector; + private final byte[] cipherText; + private final byte[] hmac; + + /** + *

Initialise a new Token from raw components. No validation of the signature is performed. However, the other + * fields are validated to ensure they conform to the Fernet specification.

+ * + *

Warning: Subsequent modifications to the input arrays will write through to this object.

+ * + * @param version + * The version of the Fernet token specification. Currently, only 0x80 is supported. + * @param timestamp + * the time the token was generated + * @param initializationVector + * the randomly-generated bytes used to initialise the encryption cipher + * @param cipherText + * the encrypted the encrypted payload + * @param hmac + * the signature of the token + */ + @SuppressWarnings({"PMD.ArrayIsStoredDirectly", "PMD.CyclomaticComplexity"}) + protected Token(final byte version, final Instant timestamp, final IvParameterSpec initializationVector, + final byte[] cipherText, final byte[] hmac) { + if (version != supportedVersion) { + throw new IllegalTokenException("Unsupported version: " + version); + } + if (initializationVector == null || initializationVector.getIV().length != initializationVectorBytes) { + throw new IllegalTokenException("Initialization Vector must be 128 bits"); + } + if (cipherText == null || cipherText.length % cipherTextBlockSize != 0) { + throw new IllegalTokenException("Ciphertext must be a multiple of 128 bits"); + } + if (hmac == null || hmac.length != signatureBytes) { + throw new IllegalTokenException("hmac must be 256 bits"); + } + this.version = version; + this.timestamp = timestamp; + this.initializationVector = initializationVector; + this.cipherText = cipherText; + this.hmac = hmac; + } + @SuppressWarnings({"PMD.PrematureDeclaration", "PMD.DataflowAnomalyAnalysis"}) + public static Token fromBytes(final byte[] bytes) { + if (bytes.length < minimumTokenBytes) { + throw new IllegalTokenException("Not enough bits to generate a Token"); + } + try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) { + try (DataInputStream dataStream = new DataInputStream(inputStream)) { + final byte version = dataStream.readByte(); + final long timestampSeconds = dataStream.readLong(); + + final byte[] initializationVector = read(dataStream, initializationVectorBytes); + final byte[] cipherText = read(dataStream, bytes.length - tokenStaticBytes); + final byte[] hmac = read(dataStream, signatureBytes); + + if (dataStream.read() != -1) { + throw new IllegalTokenException("more bits found"); + } + + return new Token(version, null, + new IvParameterSpec(initializationVector), cipherText, hmac); + } + } catch (final IOException ioe) { + // this should not happen as I/O is from memory and stream + // length is verified ahead of time + throw new IllegalStateException(ioe.getMessage(), ioe); + } + } + + protected static byte[] read(final DataInputStream stream, final int numBytes) throws IOException { + final byte[] retval = new byte[numBytes]; + final int bytesRead = stream.read(retval); + if (bytesRead < numBytes) { + throw new IllegalTokenException("Not enough bits to generate a Token"); + } + return retval; + } + + public static Token fromString(final String string) { + return fromBytes(android.util.Base64.decode(string, Base64.DEFAULT)); + } + + /** + * Convenience method to generate a new Fernet token with a string payload. + * + * @param key the secret key for encrypting plainText and signing the token + * @param plainText the payload to embed in the token + * @return a unique Fernet token + */ + public static Token generate(final com.hiddenservices.genesissearchengine.production.libs.fernet.Key key, final String plainText) { + return generate(new SecureRandom(), key, plainText); + } + + /** + * Convenience method to generate a new Fernet token with a string payload. + * + * @param random a source of entropy for your application + * @param key the secret key for encrypting plainText and signing the token + * @param plainText the payload to embed in the token + * @return a unique Fernet token + */ + public static Token generate(final SecureRandom random, final com.hiddenservices.genesissearchengine.production.libs.fernet.Key key, final String plainText) { + return generate(random, key, plainText.getBytes(charset)); + } + + /** + * Convenience method to generate a new Fernet token. + * + * @param key the secret key for encrypting payload and signing the token + * @param payload the unencrypted data to embed in the token + * @return a unique Fernet token + */ + public static Token generate(final com.hiddenservices.genesissearchengine.production.libs.fernet.Key key, final byte[] payload) { + return generate(new SecureRandom(), key, payload); + } + + /** + * Generate a new Fernet token. + * + * @param random a source of entropy for your application + * @param key the secret key for encrypting payload and signing the token + * @param payload the unencrypted data to embed in the token + * @return a unique Fernet token + */ + public static Token generate(final SecureRandom random, final com.hiddenservices.genesissearchengine.production.libs.fernet.Key key, final byte[] payload) { + final IvParameterSpec initializationVector = generateInitializationVector(random); + final byte[] cipherText = key.encrypt(payload, initializationVector); + final Instant timestamp = null; + final byte[] hmac = key.sign(supportedVersion, timestamp, initializationVector, cipherText); + return new Token(supportedVersion, timestamp, initializationVector, cipherText, hmac); + } + + /** + * Check the validity of this token. + * + * @param key the secret key against which to validate the token + * @param validator an object that encapsulates the validation parameters (e.g. TTL) + * @return the decrypted, deserialised payload of this token + * @throws TokenValidationException if key was NOT used to generate this token + */ + + /** + * Check the validity of this token against a collection of keys. Use this if you have implemented key rotation. + * + * @param keys the active keys which may have been used to generate token + * @param validator an object that encapsulates the validation parameters (e.g. TTL) + * @return the decrypted, deserialised payload of this token + * @throws TokenValidationException if none of the keys were used to generate this token + */ + + /** + * @return the Base 64 URL encoding of this token in the form Version | Timestamp | IV | Ciphertext | HMAC + */ + @SuppressWarnings("PMD.LawOfDemeter") + public String serialise() { + try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream( + tokenStaticBytes + getCipherText().length)) { + writeTo(byteStream); + return android.util.Base64.encodeToString(byteStream.toByteArray(), Base64.DEFAULT); + } catch (final IOException e) { + // this should not happen as IO is to memory only + throw new IllegalStateException(e.getMessage(), e); + } + } + + /** + * Write the raw bytes of this token to the specified output stream. + * + * @param outputStream + * the target + * @throws IOException + * if data cannot be written to the underlying stream + */ + @SuppressWarnings("PMD.LawOfDemeter") + public void writeTo(final OutputStream outputStream) throws IOException { + try (DataOutputStream dataStream = new DataOutputStream(outputStream)) { + long mTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()); + dataStream.writeByte(getVersion()); + dataStream.writeLong(mTime); + dataStream.write(getInitializationVector().getIV()); + dataStream.write(getCipherText()); + dataStream.write(getHmac()); + } + } + + /** + * @return the Fernet specification version of this token + */ + public byte getVersion() { + return version; + } + + /** + * @return the time that this token was generated + */ + public Instant getTimestamp() { + return timestamp; + } + + /** + * @return the initialisation vector used to encrypt the token contents + */ + public IvParameterSpec getInitializationVector() { + return initializationVector; + } + + public String toString() { + final StringBuilder builder = new StringBuilder(107); + builder.append("Token [version=").append(String.format("0x%x", new BigInteger(1, new byte[] {getVersion()}))) + .append(", timestamp=").append(getTimestamp()) + .append(", hmac=").append(android.util.Base64.encodeToString(getHmac(), Base64.DEFAULT)).append(']'); + return builder.toString(); + } + + protected static IvParameterSpec generateInitializationVector(final SecureRandom random) { + return new IvParameterSpec(generateInitializationVectorBytes(random)); + } + + protected static byte[] generateInitializationVectorBytes(final SecureRandom random) { + final byte[] retval = new byte[initializationVectorBytes]; + random.nextBytes(retval); + return retval; + } + + /** + * Recompute the HMAC signature of the token with the stored shared secret key. + * + * @param key + * the shared secret key against which to validate the token + * @return true if and only if the signature on the token was generated using the supplied key + */ + public boolean isValidSignature(final Key key) { + final byte[] computedHmac = key.sign(getVersion(), getTimestamp(), getInitializationVector(), + getCipherText()); + return MessageDigest.isEqual(getHmac(), computedHmac); + } + + /** + * Warning: modifications to the returned array will write through to this object. + * + * @return the raw encrypted payload bytes + */ + @SuppressWarnings("PMD.MethodReturnsInternalArray") + protected byte[] getCipherText() { + return cipherText; + } + + /** + * Warning: modifications to the returned array will write through to this object. + * + * @return the HMAC 256 signature of this token + */ + @SuppressWarnings("PMD.MethodReturnsInternalArray") + protected byte[] getHmac() { + return hmac; + } + + public byte[] validateAndDecrypt(final com.hiddenservices.genesissearchengine.production.libs.fernet.Key key) { + return key.decrypt(getCipherText(), getInitializationVector()); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenExpiredException.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenExpiredException.java new file mode 100644 index 00000000..c4573bc9 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenExpiredException.java @@ -0,0 +1,45 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +import com.hiddenservices.genesissearchengine.production.libs.fernet.TokenValidationException; + +/** + * This is a special case of the {@link TokenValidationException} that indicates that the Fernet token is invalid + * because the application-defined time-to-live has elapsed. Applications can use this to communicate to the client that + * a new Fernet must be generated, possibly by re-authenticating. + * + *

Copyright © 2017 Carlos Macasaet.

+ * + * @author Carlos Macasaet + */ +public class TokenExpiredException extends TokenValidationException { + + private static final long serialVersionUID = -8250681539503776783L; + + public TokenExpiredException(final String message) { + super(message); + } + + public TokenExpiredException(final Throwable cause) { + this(cause.getMessage(), cause); + } + + public TokenExpiredException(final String message, final Throwable cause) { + super(message, cause); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenValidationException.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenValidationException.java new file mode 100644 index 00000000..38e3cf97 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/TokenValidationException.java @@ -0,0 +1,42 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 com.hiddenservices.genesissearchengine.production.libs.fernet; + +/** + * This exception indicates that an operation (e.g. payload decryption) was + * attempted on an invalid Fernet token. + * + *

Copyright © 2017 Carlos Macasaet.

+ * + * @author Carlos Macasaet + */ +public class TokenValidationException extends RuntimeException { + + private static final long serialVersionUID = 5175834607547919885L; + + public TokenValidationException(final String message) { + super(message); + } + + public TokenValidationException(final Throwable cause) { + this(cause.getMessage(), cause); + } + + public TokenValidationException(final String message, final Throwable cause) { + super(message, cause); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Validator.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Validator.java new file mode 100644 index 00000000..24648843 --- /dev/null +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/fernet/Validator.java @@ -0,0 +1,37 @@ +/** + Copyright 2017 Carlos Macasaet + + 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 com.hiddenservices.genesissearchengine.production.libs.fernet; + + +/** + * This class validates a token according to the Fernet specification. It may be extended to provide domain-specific + * validation of the decrypted content of the token. If you use a dependency injection / inversion of control framework, + * it would be appropriate for a subclass to be a singleton which accesses a data store. + * + *

Copyright © 2017 Carlos Macasaet.

+ * + * @param + * The type of the payload. The Fernet token encodes the payload in binary. The type T should be a domain + * object or data transfer object representation of that data. + * @see StringObjectValidator + * @see StringValidator + * @author Carlos Macasaet + */ +public interface Validator { + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/trueTime/trueTimeEncryption.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/trueTime/trueTimeEncryption.java index f6a6850e..90636207 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/trueTime/trueTimeEncryption.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/libs/trueTime/trueTimeEncryption.java @@ -1,15 +1,13 @@ package com.hiddenservices.genesissearchengine.production.libs.trueTime; import com.instacart.library.truetime.TrueTime; -import com.macasaet.fernet.Key; -import com.macasaet.fernet.Token; -import java.util.Base64; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; public class trueTimeEncryption { public static String S_FERNET_KEY = "W#ZYBHQa9G_DB_iU@yjA3Es@COu4-UzU"; public static String S_APP_BLOCK_KEY = "D~S=05y68#M25oj]vprm}9HE))Tr'VX?[p|m-Wg`mrg^"; - private static trueTimeEncryption ourInstance = new trueTimeEncryption(); public static trueTimeEncryption getInstance() { @@ -22,13 +20,10 @@ public class trueTimeEncryption { }catch (Exception ignored){ } } - - public String getSecretToken() { - Key mkey = null; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - mkey = new Key(Base64.getUrlEncoder().encodeToString(S_FERNET_KEY.getBytes())); - } - Token token = Token.generate(mkey, S_APP_BLOCK_KEY + "----" + System.currentTimeMillis()/1000); - return token.serialise(); + public String getSecretToken() throws UnsupportedEncodingException { + String mTime = String.valueOf(System.currentTimeMillis()/1000); + com.hiddenservices.genesissearchengine.production.libs.fernet.Key mKey = new com.hiddenservices.genesissearchengine.production.libs.fernet.Key(android.util.Base64.encodeToString(S_FERNET_KEY.getBytes(), android.util.Base64.DEFAULT).replace("\n","")); + com.hiddenservices.genesissearchengine.production.libs.fernet.Token mToken = com.hiddenservices.genesissearchengine.production.libs.fernet.Token.generate(mKey, S_APP_BLOCK_KEY + "----" + mTime); + return URLEncoder.encode(mToken.serialise()); } } diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/admobManager.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/admobManager.java index 108d0bbe..e69de29b 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/admobManager.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/admobManager.java @@ -1,114 +0,0 @@ -package com.hiddenservices.genesissearchengine.production.pluginManager.adPluginManager; - -import android.content.Context; -import android.util.Log; -import com.hiddenservices.genesissearchengine.production.eventObserver; -import com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums; -import com.google.android.gms.ads.AdListener; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.AdView; -import com.google.android.gms.ads.LoadAdError; - -import java.lang.ref.WeakReference; - -import static com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums.eAdManagerCallbacks.M_ON_AD_CLICK; -import static com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums.eAdManagerCallbacks.M_ON_AD_HIDE; -import static com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums.eAdManagerCallbacks.M_ON_AD_LOAD; - -public class admobManager extends AdListener { - - /*Private Variables */ - - private eventObserver.eventListener mEvent; - private WeakReference mBannerAds; - - private boolean bannerAdsLoaded = false; - private boolean mAdvertClicked = false; - private static boolean mBannerAdvertLoadReqest = false; - - /*Initializations*/ - - public admobManager(eventObserver.eventListener pEvent, AdView pBannerAds, Context pContext) { - this.mEvent = pEvent; - this.mBannerAds = new WeakReference(pBannerAds); - loadAds(pContext); - } - - /*Local Overrides*/ - - @Override - public void onAdLoaded() { - super.onAdLoaded(); - bannerAdsLoaded = true; - mEvent.invokeObserver(null, M_ON_AD_LOAD); - } - - @Override - public void onAdClicked(){ - super.onAdClicked(); - mEvent.invokeObserver(null, M_ON_AD_CLICK); - onDestroy(); - mAdvertClicked = true; - } - - @Override - public void onAdOpened(){ - super.onAdClicked(); - mEvent.invokeObserver(null, M_ON_AD_CLICK); - onDestroy(); - mAdvertClicked = true; - } - - @Override - public void onAdFailedToLoad(LoadAdError var1){ - Log.i("asd","asd"); - } - - /*Local Helper Methods*/ - - private void loadAds(Context pContext){ - if(!mBannerAdvertLoadReqest){ - mBannerAdvertLoadReqest = true; - - - AdRequest adRequest = new AdRequest.Builder().build(); - mBannerAds.get().setAdListener(this); - mBannerAds.get().loadAd(adRequest); - - - }else { - onDestroy(); - mEvent.invokeObserver(null, M_ON_AD_HIDE); - } - } - - - private boolean isAdvertLoaded(){ - if(mAdvertClicked){ - return false; - }else { - return bannerAdsLoaded; - } - } - - private void onDestroy(){ - mBannerAds.get().destroy(); - } - - /*External Triggers*/ - - public Object onTrigger(pluginEnums.eAdManager pEventType) { - if(pEventType.equals(pluginEnums.eAdManager.M_INITIALIZE_BANNER_ADS)) - { - } - else if(pEventType.equals(pluginEnums.eAdManager.M_IS_ADVERT_LOADED)) - { - return isAdvertLoaded(); - } - else if(pEventType.equals(pluginEnums.eAdManager.M_DESTROY)) - { - onDestroy(); - } - return null; - } -} diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/mopubManager.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/mopubManager.java index 8594af47..54ed6211 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/mopubManager.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/adPluginManager/mopubManager.java @@ -2,27 +2,22 @@ package com.hiddenservices.genesissearchengine.production.pluginManager.adPlugin import android.content.Context; import android.os.Handler; -import androidx.annotation.NonNull; -import com.hiddenservices.genesissearchengine.production.constants.keys; +import com.applovin.mediation.MaxAd; +import com.applovin.mediation.MaxAdViewAdListener; +import com.applovin.mediation.MaxError; +import com.applovin.mediation.ads.MaxAdView; +import com.applovin.sdk.AppLovinSdk; +import com.facebook.ads.AdSettings; import com.hiddenservices.genesissearchengine.production.eventObserver; import com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums; -import com.facebook.ads.AudienceNetworkAds; -import com.mopub.common.MoPub; -import com.mopub.common.SdkConfiguration; -import com.mopub.common.SdkInitializationListener; -import com.mopub.mobileads.MoPubErrorCode; -import com.mopub.mobileads.MoPubView; import java.lang.ref.WeakReference; import static com.hiddenservices.genesissearchengine.production.pluginManager.pluginEnums.eAdManagerCallbacks.M_ON_AD_LOAD; -import static com.mopub.common.logging.MoPubLog.LogLevel.INFO; - -public class mopubManager implements MoPubView.BannerAdListener +public class mopubManager implements MaxAdViewAdListener { - //70f6dfc0cde14baaaa25083653700416 /*Private Variables */ private eventObserver.eventListener mEvent; - private WeakReference mBannerAds; + private WeakReference mBannerAds; private int mRequestCount = 0; private boolean bannerAdsLoaded = false; @@ -30,60 +25,18 @@ public class mopubManager implements MoPubView.BannerAdListener /*Initializations*/ - public mopubManager(eventObserver.eventListener pEvent, MoPubView pBannerAds, Context pContext) { + public mopubManager(eventObserver.eventListener pEvent, MaxAdView pBannerAds, Context pContext) { this.mEvent = pEvent; this.mBannerAds = new WeakReference(pBannerAds); initializeBannerAds(pContext); } private void initializeBannerAds(Context pContext){ - final SdkConfiguration.Builder configBuilder = new SdkConfiguration.Builder(keys.ADMANAGER_APPID_KEY); - configBuilder.withLogLevel(INFO); - - AudienceNetworkAds.initialize(pContext); - MoPub.initializeSdk(pContext, configBuilder.build(), initSdkListener()); - } - - private SdkInitializationListener initSdkListener() { - return () -> { - }; - } - - /* Local Overrides */ - - @Override - public void onBannerLoaded(@NonNull MoPubView moPubView) { - bannerAdsLoaded = true; - mEvent.invokeObserver(null, M_ON_AD_LOAD); - } - - @Override - public void onBannerFailed(MoPubView moPubView, MoPubErrorCode moPubErrorCode) { - new Handler().postDelayed(() -> - { - if(mRequestCount<=10){ - mRequestCount +=1; - mBannerAds.get().setAdUnitId(keys.ADMANAGER_APPID_KEY); - mBannerAds.get().setAdSize(MoPubView.MoPubAdSize.HEIGHT_50); - mBannerAds.get().loadAd(); - mBannerAds.get().setBannerAdListener(this); - } - }, 10000); - } - - @Override - public void onBannerClicked(MoPubView moPubView) { - - } - - @Override - public void onBannerExpanded(MoPubView moPubView) { - - } - - @Override - public void onBannerCollapsed(MoPubView moPubView) { + AdSettings.setDataProcessingOptions( new String[] {} ); + AppLovinSdk.getInstance( pContext ).setMediationProvider( "max" ); + AppLovinSdk.initializeSdk( pContext, configuration -> { + }); } /*Local Helper Methods*/ @@ -91,9 +44,8 @@ public class mopubManager implements MoPubView.BannerAdListener private void loadAds(){ if(!bannerAdRequested){ bannerAdRequested = true; - mBannerAds.get().setAdUnitId(keys.ADMANAGER_APPID_KEY); mBannerAds.get().loadAd(); - mBannerAds.get().setBannerAdListener(this); + mBannerAds.get().setListener(this); } } @@ -114,5 +66,54 @@ public class mopubManager implements MoPubView.BannerAdListener } return null; } + + @Override + public void onAdExpanded(MaxAd ad) { + + } + + @Override + public void onAdCollapsed(MaxAd ad) { + + } + + @Override + public void onAdLoaded(MaxAd ad) { + bannerAdsLoaded = true; + mEvent.invokeObserver(null, M_ON_AD_LOAD); + } + + @Override + public void onAdDisplayed(MaxAd ad) { + + } + + @Override + public void onAdHidden(MaxAd ad) { + + } + + @Override + public void onAdClicked(MaxAd ad) { + + } + + @Override + public void onAdLoadFailed(String adUnitId, MaxError error) { + new Handler().postDelayed(() -> + { + if(mRequestCount<=10){ + mRequestCount +=1; + bannerAdRequested = true; + mBannerAds.get().loadAd(); + mBannerAds.get().setListener(this); + } + }, 10000); + } + + @Override + public void onAdDisplayFailed(MaxAd ad, MaxError error) { + + } } diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/analyticPluginManager/analyticManager.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/analyticPluginManager/analyticManager.java index 0c449ef1..831a59ef 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/analyticPluginManager/analyticManager.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/analyticPluginManager/analyticManager.java @@ -23,7 +23,7 @@ public class analyticManager private void initialize() { - new FlurryAgent.Builder() .withLogEnabled(false) .build(mAppContext.get().getApplicationContext(), "4C4K4T5ND9RJKT4H47GQ"); + new FlurryAgent.Builder() .withLogEnabled(false) .build(mAppContext.get().getApplicationContext(), "ND6QCR4JSHSJ25VWC8DN"); } /*External Triggers*/ diff --git a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/messagePluginManager/messageManager.java b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/messagePluginManager/messageManager.java index 13c064cf..850d9a8c 100644 --- a/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/messagePluginManager/messageManager.java +++ b/app/src/main/java/com/hiddenservices/genesissearchengine.production/pluginManager/messagePluginManager/messageManager.java @@ -441,6 +441,9 @@ public class messageManager implements View.OnClickListener, DialogInterface.OnD else if(status.sStoreType == enums.StoreType.AMAZON){ return CONST_AMAZON_URL; } + else if(status.sStoreType == enums.StoreType.HUAWEI){ + return CONST_HUAWEI_URL; + } else { return CONST_SAMSUNG_URL; } diff --git a/app/src/main/java/com/widget/Genesis/widgetManager/widgetModelController.java b/app/src/main/java/com/widget/Genesis/widgetManager/widgetModelController.java index b77954ad..d58a96b9 100644 --- a/app/src/main/java/com/widget/Genesis/widgetManager/widgetModelController.java +++ b/app/src/main/java/com/widget/Genesis/widgetManager/widgetModelController.java @@ -4,6 +4,8 @@ import android.appwidget.AppWidgetManager; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.util.Log; + import com.hiddenservices.genesissearchengine.production.constants.enums; import com.hiddenservices.genesissearchengine.production.constants.status; import com.hiddenservices.genesissearchengine.production.eventObserver; @@ -27,13 +29,16 @@ public class widgetModelController { private void initialize(Context context, Intent intent){ String action = intent.getAction(); + Log.i("22adsasdasddas","22asdasdsadasdadsasd"); switch (action) { case enums.WidgetCommands.OPEN_APPLICATION: { + Log.i("33adsasdasddas","33asdasdsadasdadsasd"); status.sWidgetResponse = enums.WidgetResponse.SEARCHBAR; helperMethod.onStartApplication(context, CONST_PACKAGE_NAME); break; } case enums.WidgetCommands.OPEN_VOICE: { + Log.i("44adsasdasddas","44asdasdsadasdadsasd"); status.sWidgetResponse = enums.WidgetResponse.VOICE; helperMethod.onStartApplication(context, CONST_PACKAGE_NAME); break; @@ -83,6 +88,7 @@ public class widgetModelController { public Object onTrigger(widgetEnums.eModelViewController pCommands, List pData){ if(pCommands.equals(widgetEnums.eModelViewController.M_ON_RECIEVE)){ + Log.i("11adsasdasddas","11asdasdsadasdadsasd"); initialize((Context)pData.get(0), (Intent) pData.get(1)); } return null; diff --git a/app/src/main/res/layouts/home/layout/home_view.xml b/app/src/main/res/layouts/home/layout/home_view.xml index f8fe4776..60b880d4 100644 --- a/app/src/main/res/layouts/home/layout/home_view.xml +++ b/app/src/main/res/layouts/home/layout/home_view.xml @@ -8,20 +8,21 @@ android:background="@color/black" tools:context="com.hiddenservices.genesissearchengine.production.appManager.homeManager.homeController.homeController"> - -