diff --git a/otgc/build.gradle b/otgc/build.gradle
index 91bc28abf878c092e3edc57e37dd550169b49a8c..10a3102b8e536c2a9d109dab30cc77bc1f9fd2b3 100644
--- a/otgc/build.gradle
+++ b/otgc/build.gradle
@@ -30,7 +30,7 @@ android {
minSdkVersion 21
targetSdkVersion 28
versionCode 13
- versionName "2.10.0"
+ versionName "2.11.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
compileOptions {
diff --git a/otgc/src/main/AndroidManifest.xml b/otgc/src/main/AndroidManifest.xml
index 56e31385dfdcac33916196a4cb68577d6185da8e..2c7adcdc73957c5d1a8cedfbfa08341f4a13673b 100644
--- a/otgc/src/main/AndroidManifest.xml
+++ b/otgc/src/main/AndroidManifest.xml
@@ -101,6 +101,11 @@
android:configChanges="orientation|screenSize"
android:label="@string/trust_anchor_title"
android:parentActivityName=".view.devicelist.DeviceListActivity" />
+
{
+ if (OCPki.addMfgIntermediateCert(0 /* First device */, credid, cert) == -1) {
+ emitter.onError(new Exception("Add intermediate certificate error"));
+ }
+
+ emitter.onComplete();
+ });
+ }
+
+ public Completable addEndEntityCertificate(byte[] cert, byte[] key) {
+ return Completable.create(emitter -> {
+ if (OCPki.addMfgCert(0 /* First device */, cert, key) == -1) {
+ emitter.onError(new Exception("Add end entity certificate error"));
+ }
+
+ emitter.onComplete();
+ });
+ }
+
public Completable removeTrustAnchor(long credid) {
return Completable.create(emitter -> {
int ret = OCObt.deleteOwnCredByCredId((int)credid);
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/data/repository/IORepository.java b/otgc/src/main/java/org/openconnectivity/otgc/data/repository/IORepository.java
index 17f2c81162f09ae71a4e22e00047b68a839ad756..dbdb6cd33835e7dfebfd395b9f08b653599a7ca7 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/data/repository/IORepository.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/data/repository/IORepository.java
@@ -178,6 +178,17 @@ public class IORepository {
});
}
+ public Single getBytesFromFile(InputStream is) {
+ return Single.fromCallable(() -> {
+ int numBytes = is.available() + 1;
+ byte[] fileBytes = new byte[numBytes];
+ is.read(fileBytes);
+ fileBytes[numBytes - 1] = '\0';
+
+ return fileBytes;
+ });
+ }
+
public Single getAssetSvrAsCbor(String resource, long device) {
return Single.create(emitter -> {
try (FileInputStream stream = new FileInputStream(mContext.getFilesDir() +
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/InitializeIotivityUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/InitializeIotivityUseCase.java
index 34422716bf646e86a945dddfb364d3da13987753..65e8ce46abbd961f824ccc953c417a51231e378c 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/InitializeIotivityUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/InitializeIotivityUseCase.java
@@ -22,6 +22,8 @@
package org.openconnectivity.otgc.domain.usecase;
+import android.content.Context;
+
import org.iotivity.OCFactoryPresetsHandler;
import org.iotivity.OCObt;
import org.iotivity.OCPki;
@@ -30,6 +32,11 @@ import org.openconnectivity.otgc.data.repository.IotivityRepository;
import org.openconnectivity.otgc.data.repository.PreferencesRepository;
import org.openconnectivity.otgc.utils.constant.OtgcConstant;
import org.openconnectivity.otgc.utils.constant.OtgcMode;
+import org.openconnectivity.otgc.utils.handler.DisplayNotValidCertificateHandler;
+
+import java.io.InputStream;
+import java.security.cert.X509Certificate;
+import java.util.Date;
import javax.inject.Inject;
@@ -40,6 +47,9 @@ public class InitializeIotivityUseCase {
private final IORepository ioRepository;
private final PreferencesRepository settingRepository;
+ private Context context;
+ private DisplayNotValidCertificateHandler displayNotValidCertificateHandler;
+
@Inject
public InitializeIotivityUseCase(IotivityRepository iotivityRepository,
IORepository ioRepository,
@@ -49,7 +59,10 @@ public class InitializeIotivityUseCase {
this.settingRepository = settingRepository;
}
- public Completable execute() {
+ public Completable execute(Context context, DisplayNotValidCertificateHandler displayNotValidCertificateHandler) {
+ this.context = context;
+ this.displayNotValidCertificateHandler = displayNotValidCertificateHandler;
+
Completable initOic = iotivityRepository.initOICStack();
Completable completable = iotivityRepository.setFactoryResetHandler(factoryReset);
@@ -76,31 +89,58 @@ public class InitializeIotivityUseCase {
}
});
private void factoryResetHandler(long device) throws Exception {
+ /* Current date */
+ Date date = new Date();
+
/* Kyrio end-entity cert */
- byte[] kyrioEeCertificate = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_EE_CERTIFICATE).blockingGet();
- /* private key of Kyrio end-entity cert */
- byte[] kyrioEeKey = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_EE_KEY).blockingGet();
- int credid = OCPki.addMfgCert(device, kyrioEeCertificate, kyrioEeKey);
- if (credid == -1) {
- throw new Exception("Add identity certificate error");
- }
+ InputStream inputStream = context.getAssets().open(OtgcConstant.KYRIO_EE_CERTIFICATE);
+ X509Certificate eeCert = ioRepository.getFileAsX509Certificate(inputStream).blockingGet();
+ if (date.after(eeCert.getNotBefore()) && date.before(eeCert.getNotAfter())) {
+ byte[] kyrioEeCertificate = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_EE_CERTIFICATE).blockingGet();
+ /* private key of Kyrio end-entity cert */
+ byte[] kyrioEeKey = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_EE_KEY).blockingGet();
+ int credid = OCPki.addMfgCert(device, kyrioEeCertificate, kyrioEeKey);
+ if (credid == -1) {
+ throw new Exception("Add identity certificate error");
+ }
- /* Kyrio intermediate cert */
- byte[] kyrioSubcaCertificate = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_SUBCA_CERTIFICATE).blockingGet();
- if (OCPki.addMfgIntermediateCert(device, credid, kyrioSubcaCertificate) == -1) {
- throw new Exception("Add intermediate certificate error");
+ /* Kyrio intermediate cert */
+ inputStream = context.getAssets().open(OtgcConstant.KYRIO_SUBCA_CERTIFICATE);
+ X509Certificate subCaCert = ioRepository.getFileAsX509Certificate(inputStream).blockingGet();
+ if (date.after(subCaCert.getNotBefore()) && date.before(subCaCert.getNotAfter())) {
+ byte[] kyrioSubcaCertificate = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_SUBCA_CERTIFICATE).blockingGet();
+ if (OCPki.addMfgIntermediateCert(device, credid, kyrioSubcaCertificate) == -1) {
+ throw new Exception("Add intermediate certificate error");
+ }
+ } else {
+ this.displayNotValidCertificateHandler.handler("Kyrio intermediate certificate is not valid");
+ }
+ } else {
+ this.displayNotValidCertificateHandler.handler("Kyrio end entity certificate is not valid");
}
/* Kyrio root cert */
- byte[] kyrioRootcaCertificate = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_ROOT_CERTIFICATE).blockingGet();
- if (OCPki.addMfgTrustAnchor(device, kyrioRootcaCertificate) == -1) {
- throw new Exception("Add root certificate error");
+ inputStream = context.getAssets().open(OtgcConstant.KYRIO_ROOT_CERTIFICATE);
+ X509Certificate caCert = ioRepository.getFileAsX509Certificate(inputStream).blockingGet();
+ if (date.after(caCert.getNotBefore()) && date.before(caCert.getNotAfter())) {
+ byte[] kyrioRootcaCertificate = ioRepository.getBytesFromFile(OtgcConstant.KYRIO_ROOT_CERTIFICATE).blockingGet();
+ if (OCPki.addMfgTrustAnchor(device, kyrioRootcaCertificate) == -1) {
+ throw new Exception("Add root certificate error");
+ }
+ } else {
+ this.displayNotValidCertificateHandler.handler("Kyrio root certificate is not valid");
}
/* EonTi root cert */
- byte[] eontiRootcaCertificate = ioRepository.getBytesFromFile(OtgcConstant.EONTI_ROOT_CERTIFICATE).blockingGet();
- if (OCPki.addMfgTrustAnchor(device, eontiRootcaCertificate) == -1) {
- throw new Exception("Add root certificate error");
+ inputStream = context.getAssets().open(OtgcConstant.EONTI_ROOT_CERTIFICATE);
+ caCert = ioRepository.getFileAsX509Certificate(inputStream).blockingGet();
+ if (date.after(caCert.getNotBefore()) && date.before(caCert.getNotAfter())) {
+ byte[] eontiRootcaCertificate = ioRepository.getBytesFromFile(OtgcConstant.EONTI_ROOT_CERTIFICATE).blockingGet();
+ if (OCPki.addMfgTrustAnchor(device, eontiRootcaCertificate) == -1) {
+ throw new Exception("Add root certificate error");
+ }
+ } else {
+ this.displayNotValidCertificateHandler.handler("EonTi root certificate is not valid");
}
OCObt.shutdown();
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/GetTrustAnchorUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/GetTrustAnchorUseCase.java
index 4c25eb54b7547e9b967cff1444248170a74c9a16..3dbf39a21080d98d0eb2cb1e8522006cd920363a 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/GetTrustAnchorUseCase.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/GetTrustAnchorUseCase.java
@@ -45,7 +45,9 @@ public class GetTrustAnchorUseCase {
for (OcCredential cred : creds.getCredList()) {
if (cred.getCredusage() != null && !cred.getCredusage().isEmpty()
&& (OCCredUtil.parseCredUsage(cred.getCredusage()) == OCCredUsage.OC_CREDUSAGE_MFG_TRUSTCA
- || OCCredUtil.parseCredUsage(cred.getCredusage()) == OCCredUsage.OC_CREDUSAGE_TRUSTCA)) {
+ || OCCredUtil.parseCredUsage(cred.getCredusage()) == OCCredUsage.OC_CREDUSAGE_TRUSTCA
+ || OCCredUtil.parseCredUsage(cred.getCredusage()) == OCCredUsage.OC_CREDUSAGE_IDENTITY_CERT
+ || OCCredUtil.parseCredUsage(cred.getCredusage()) == OCCredUsage.OC_CREDUSAGE_MFG_CERT)) {
trustAnchorList.add(cred);
}
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/SaveEndEntityCertificateUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/SaveEndEntityCertificateUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..4851da47d26fae7890b772a0da21536281ad4aa1
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/SaveEndEntityCertificateUseCase.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * *****************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openconnectivity.otgc.domain.usecase.trustanchor;
+
+import org.openconnectivity.otgc.data.repository.CmsRepository;
+import org.openconnectivity.otgc.data.repository.IORepository;
+
+import java.io.InputStream;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+import io.reactivex.Single;
+
+public class SaveEndEntityCertificateUseCase {
+
+ private final IORepository ioRepository;
+ private final CmsRepository cmsRepository;
+
+ @Inject
+ public SaveEndEntityCertificateUseCase(IORepository ioRepository,
+ CmsRepository cmsRepository) {
+ this.ioRepository = ioRepository;
+ this.cmsRepository = cmsRepository;
+ }
+
+ public Completable execute(InputStream certIs, InputStream keyIs) {
+ Single pemCertObservable = ioRepository.getBytesFromFile(certIs);
+
+ Single pemKeyCertObservable = ioRepository.getBytesFromFile(keyIs);
+
+ return pemCertObservable.flatMapCompletable(
+ cert -> pemKeyCertObservable.flatMapCompletable(
+ keyCert -> cmsRepository.addEndEntityCertificate(cert, keyCert)
+ ));
+ }
+
+}
\ No newline at end of file
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/SaveIntermediateCertificateUseCase.java b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/SaveIntermediateCertificateUseCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..675dc2bf4ff90bf788a415615c0bc87f2bee942c
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/domain/usecase/trustanchor/SaveIntermediateCertificateUseCase.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * *****************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openconnectivity.otgc.domain.usecase.trustanchor;
+
+import org.openconnectivity.otgc.data.repository.CmsRepository;
+import org.openconnectivity.otgc.data.repository.IORepository;
+
+import java.io.InputStream;
+
+import javax.inject.Inject;
+
+import io.reactivex.Completable;
+
+public class SaveIntermediateCertificateUseCase {
+
+ private final IORepository ioRepository;
+ private final CmsRepository cmsRepository;
+
+ @Inject
+ public SaveIntermediateCertificateUseCase(IORepository ioRepository,
+ CmsRepository cmsRepository) {
+ this.ioRepository = ioRepository;
+ this.cmsRepository = cmsRepository;
+ }
+
+ public Completable execute(Integer credid, InputStream is) {
+ return ioRepository.getBytesFromFile(is)
+ .flatMapCompletable(cert -> cmsRepository.addIntermediateCertificate(credid, cert));
+ }
+
+}
\ No newline at end of file
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/utils/di/BuildersModule.java b/otgc/src/main/java/org/openconnectivity/otgc/utils/di/BuildersModule.java
index a130f3727edd479bfc14825ff5f55382957e960f..3ed73e94c2e2305afd1fdd80127852cb223c6625 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/utils/di/BuildersModule.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/utils/di/BuildersModule.java
@@ -32,6 +32,7 @@ import org.openconnectivity.otgc.view.devicelist.DeviceListActivity;
import org.openconnectivity.otgc.view.link.LinkedRolesActivity;
import org.openconnectivity.otgc.view.login.LoginActivity;
import org.openconnectivity.otgc.view.splash.SplashActivity;
+import org.openconnectivity.otgc.view.trustanchor.CertificateActivity;
import org.openconnectivity.otgc.view.trustanchor.TrustAnchorActivity;
import org.openconnectivity.otgc.view.wlanscan.WlanScanActivity;
@@ -73,4 +74,7 @@ public interface BuildersModule {
@ContributesAndroidInjector
abstract TrustAnchorActivity bindTrustAnchorActivity();
+
+ @ContributesAndroidInjector
+ abstract CertificateActivity bindCertificateActivity();
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/utils/di/ViewModelModule.java b/otgc/src/main/java/org/openconnectivity/otgc/utils/di/ViewModelModule.java
index cf828aa552ec526b3aa6d7540e0ebe47d7f49f9c..23722e7cd22c775de7ecce926dda39d58c18d7cb 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/utils/di/ViewModelModule.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/utils/di/ViewModelModule.java
@@ -27,6 +27,7 @@ import androidx.lifecycle.ViewModelProvider;
import org.openconnectivity.otgc.viewmodel.AccessControlViewModel;
import org.openconnectivity.otgc.viewmodel.AceViewModel;
+import org.openconnectivity.otgc.viewmodel.CertificateViewModel;
import org.openconnectivity.otgc.viewmodel.ResourceViewModel;
import org.openconnectivity.otgc.utils.viewmodel.ViewModelFactory;
import org.openconnectivity.otgc.viewmodel.GenericClientViewModel;
@@ -119,4 +120,9 @@ abstract class ViewModelModule {
@IntoMap
@ViewModelKey(TrustAnchorViewModel.class)
abstract ViewModel bindTrustAnchorsViewModel(TrustAnchorViewModel trustAnchorViewModel);
+
+ @Binds
+ @IntoMap
+ @ViewModelKey(CertificateViewModel.class)
+ abstract ViewModel bindCertificateViewModel(CertificateViewModel certificateViewModel);
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/utils/handler/DisplayNotValidCertificateHandler.java b/otgc/src/main/java/org/openconnectivity/otgc/utils/handler/DisplayNotValidCertificateHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8decf00413208721878826c828ff81c928e8c98
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/utils/handler/DisplayNotValidCertificateHandler.java
@@ -0,0 +1,27 @@
+/*
+ * *****************************************************************
+ *
+ * Copyright 2018 DEKRA Testing and Certification, S.A.U. All Rights Reserved.
+ *
+ * *****************************************************************
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************
+ */
+
+package org.openconnectivity.otgc.utils.handler;
+
+public interface DisplayNotValidCertificateHandler {
+ public void handler(String content);
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/view/devicelist/DeviceListActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/view/devicelist/DeviceListActivity.java
index 9efe12f47435f39e8b28e4c1b56e2351732281c4..216b77dd14b847e14c5d21797ecd20cb3ebf77bc 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/view/devicelist/DeviceListActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/view/devicelist/DeviceListActivity.java
@@ -39,6 +39,7 @@ import android.widget.Toast;
import org.iotivity.OCRandomPinHandler;
import org.openconnectivity.otgc.utils.constant.OtgcMode;
+import org.openconnectivity.otgc.utils.handler.DisplayNotValidCertificateHandler;
import org.openconnectivity.otgc.utils.handler.OCSetRandomPinHandler;
import org.openconnectivity.otgc.utils.view.RecyclerWithSwipeFragment;
import org.openconnectivity.otgc.utils.viewmodel.CommonError;
@@ -131,6 +132,18 @@ public class DeviceListActivity extends AppCompatActivity implements HasSupportF
});
};
+ DisplayNotValidCertificateHandler displayNotValidCertificateHandler = content -> {
+ runOnUiThread(() -> {
+ AlertDialog.Builder alertDialog = new AlertDialog.Builder(new ContextThemeWrapper(DeviceListActivity.this, R.style.AppTheme));
+ alertDialog.setTitle(DeviceListActivity.this.getString(R.string.devices_dialog_show_not_valid_certificate_title));
+ alertDialog.setMessage(content);
+ alertDialog.setCancelable(false);
+ alertDialog.setPositiveButton(
+ DeviceListActivity.this.getString(R.string.devices_dialog_show_not_valid_certificate_ok_option),
+ (dialog, which) -> dialog.dismiss()).show();
+ });
+ };
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -169,7 +182,7 @@ public class DeviceListActivity extends AppCompatActivity implements HasSupportF
}
}
- mViewModel.initializeIotivityStack();
+ mViewModel.initializeIotivityStack(getApplicationContext(), displayNotValidCertificateHandler);
return true;
}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/view/trustanchor/CertificateActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/view/trustanchor/CertificateActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..201d525a64ef0fa18b7e9c6a2cebf52daedf648c
--- /dev/null
+++ b/otgc/src/main/java/org/openconnectivity/otgc/view/trustanchor/CertificateActivity.java
@@ -0,0 +1,241 @@
+package org.openconnectivity.otgc.view.trustanchor;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProviders;
+
+import org.openconnectivity.otgc.R;
+import org.openconnectivity.otgc.domain.model.resource.secure.cred.OcCredential;
+import org.openconnectivity.otgc.utils.di.Injectable;
+import org.openconnectivity.otgc.utils.viewmodel.ViewModelError;
+import org.openconnectivity.otgc.viewmodel.CertificateViewModel;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import javax.inject.Inject;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+public class CertificateActivity extends AppCompatActivity implements Injectable {
+ @Inject
+ ViewModelProvider.Factory mViewModelFactory;
+
+ @BindView(R.id.toolbar) Toolbar mToolbar;
+ @BindView(R.id.trust_anchor_select_end_entity_layout) LinearLayout selectEndEntityLayout;
+ @BindView(R.id.spinner_select_end_entity_certificate) Spinner selectEndEntityCert;
+ @BindView(R.id.button_select_certificate) Button selectCertificate;
+ @BindView(R.id.trust_anchor_selected_certificate_text) TextView selectedCertificateText;
+ @BindView(R.id.trust_anchor_select_key_layout) LinearLayout selectKeyLayout;
+ @BindView(R.id.button_select_key) Button selectKey;
+ @BindView(R.id.trust_anchor_selected_key_text) TextView selectKeyText;
+ @BindView(R.id.radio_root_certificate) RadioButton rootRadioButton;
+ @BindView(R.id.radio_intermediate_certificate) RadioButton intermediateRadioButton;
+ @BindView(R.id.radio_end_entity_certificate) RadioButton endEntityRadioButton;
+
+ @OnClick({ R.id.radio_root_certificate, R.id.radio_intermediate_certificate, R.id.radio_end_entity_certificate})
+ public void onRadioButtonClicked(RadioButton rb) {
+ // Is the button now checked?
+ boolean checked = rb.isChecked();
+
+ // Check which radio button was clicked
+ switch (rb.getId()) {
+ case R.id.radio_root_certificate:
+ if (checked) {
+ selectEndEntityLayout.setVisibility(View.GONE);
+ selectKeyLayout.setVisibility(View.GONE);
+ }
+ break;
+ case R.id.radio_intermediate_certificate:
+ if (checked) {
+ selectEndEntityLayout.setVisibility(View.VISIBLE);
+ selectKeyLayout.setVisibility(View.GONE);
+ }
+ break;
+ case R.id.radio_end_entity_certificate:
+ if (checked) {
+ selectEndEntityLayout.setVisibility(View.GONE);
+ selectKeyLayout.setVisibility(View.VISIBLE);
+ }
+ break;
+ }
+ }
+
+ private static final int READ_REQUEST_CODE = 42;
+
+ @OnClick({ R.id.button_select_certificate, R.id.button_select_key })
+ public void onSelectFileClicked(Button button) {
+ if (button.getId() == R.id.button_select_certificate) {
+ isForCert = true;
+ isForKey = false;
+ } else if (button.getId() == R.id.button_select_key) {
+ isForCert = false;
+ isForKey = true;
+ }
+
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("*/*");
+ startActivityForResult(intent, READ_REQUEST_CODE);
+ }
+
+ private boolean isForCert = false;
+ private boolean isForKey = false;
+ private InputStream fileIs;
+ private InputStream keyIs;
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode,
+ Intent resultData) {
+
+ // The ACTION_OPEN_DOCUMENT intent was sent with the request code
+ // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
+ // response to some other intent, and the code below shouldn't run at all.
+
+ if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
+ // The document selected by the user won't be returned in the intent.
+ // Instead, a URI to that document will be contained in the return intent
+ // provided to this method as a parameter.
+ // Pull that URI using resultData.getData().
+ Uri uri = null;
+ if (resultData != null) {
+ uri = resultData.getData();
+ try {
+ InputStream is = getContentResolver().openInputStream(uri);
+ if (isForCert) {
+ fileIs = is;
+ isForCert = false;
+ selectedCertificateText.setText(uri.getPath());
+ } else if (isForKey) {
+ keyIs = is;
+ isForKey = false;
+ selectKeyText.setText(uri.getPath());
+ }
+ } catch (Exception e) {
+ int errorId = R.string.trust_anchor_create_error;
+ Toast.makeText(this, errorId, Toast.LENGTH_SHORT).show();
+ }
+
+ }
+ }
+ }
+
+ @OnClick(R.id.floating_button_cert_save)
+ protected void onSavePressed() {
+ if (rootRadioButton.isChecked()) {
+ mViewModel.saveTrustAnchor(fileIs);
+ } else if (intermediateRadioButton.isChecked()) {
+ if (selectEndEntityCert.getSelectedItem() != null) {
+ int index = selectEndEntityCert.getSelectedItemPosition();
+ Integer credid = (Integer)selectEndEntityCert.getAdapter().getItem(index);
+ mViewModel.saveIntermediateCertificate(credid, fileIs);
+ }
+ } else if (endEntityRadioButton.isChecked()) {
+ mViewModel.saveEndEntityCertificate(fileIs, keyIs);
+ }
+ }
+
+ private CertificateViewModel mViewModel;
+
+ private ArrayList mCertList;
+
+ private ArrayAdapter mAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_certificate);
+
+ Intent intent = getIntent();
+ mCertList = (ArrayList) intent.getSerializableExtra("certs");
+
+ ButterKnife.bind(this);
+ initViews();
+ initViewModel();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+ if (id == android.R.id.home) {
+ onBackPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void initViews() {
+ setSupportActionBar(mToolbar);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ selectedCertificateText.setText(R.string.trust_anchor_no_selected_certificate_text);
+ selectKeyText.setText(R.string.trust_anchor_no_selected_key_text);
+
+ mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item);
+ if (mCertList != null) {
+ mAdapter.addAll(mCertList);
+ }
+ selectEndEntityCert.setAdapter(mAdapter);
+ }
+
+ private void initViewModel() {
+ mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(CertificateViewModel.class);
+
+ mViewModel.isProcessing().observe(this, this::handleProcessing);
+ mViewModel.getError().observe(this, this::handleError);
+
+ mViewModel.getSuccess().observe(this, this::processSuccess);
+ }
+
+ private void handleProcessing(@NonNull Boolean isProcessing) {
+ // TODO
+ }
+
+ private void handleError(@NonNull ViewModelError error) {
+ int errorId = 0;
+ switch ((CertificateViewModel.Error)error.getType()) {
+ case ROOT_CERTIFICATE:
+ errorId = R.string.trust_anchor_error_create_root_certificate;
+ break;
+ case INTERMEDIATE_CERTIFICATE:
+ errorId = R.string.trust_anchor_error_create_intermediate_certificate;
+ break;
+ case END_ENTITY_CERTIFICATE:
+ errorId = R.string.trust_anchor_error_create_end_entity_certificate;
+ break;
+ }
+
+ Toast.makeText(this, errorId, Toast.LENGTH_SHORT).show();
+ }
+
+ private void processSuccess(@NonNull Boolean operationSucceeded) {
+ if (operationSucceeded) {
+ finish();
+ } else {
+ // TODO
+ }
+ }
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/view/trustanchor/TrustAnchorActivity.java b/otgc/src/main/java/org/openconnectivity/otgc/view/trustanchor/TrustAnchorActivity.java
index 2b301866c6e8ebdad7c6e46425643c4ee1f9ce07..8246956220ca756c7f199fad6cda14ac0ebc982c 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/view/trustanchor/TrustAnchorActivity.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/view/trustanchor/TrustAnchorActivity.java
@@ -18,9 +18,7 @@
package org.openconnectivity.otgc.view.trustanchor;
-import android.app.Activity;
import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
@@ -49,16 +47,14 @@ import org.openconnectivity.otgc.viewmodel.TrustAnchorViewModel;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.util.encoders.Base64;
-import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
-import java.util.Objects;
+import java.util.ArrayList;
+import java.util.List;
import javax.inject.Inject;
@@ -75,41 +71,16 @@ public class TrustAnchorActivity extends AppCompatActivity implements Injectable
@BindView(R.id.recycler_ocf_trustanchors) EmptyRecyclerView mRecyclerView;
@BindView(R.id.floating_button_trustanchor_add) FloatingActionButton mFloatingActionButton;
- private static final int READ_REQUEST_CODE = 42;
-
@OnClick(R.id.floating_button_trustanchor_add)
protected void onAddPressed() {
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("*/*");
- startActivityForResult(intent, READ_REQUEST_CODE);
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode,
- Intent resultData) {
-
- // The ACTION_OPEN_DOCUMENT intent was sent with the request code
- // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
- // response to some other intent, and the code below shouldn't run at all.
-
- if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
- // The document selected by the user won't be returned in the intent.
- // Instead, a URI to that document will be contained in the return intent
- // provided to this method as a parameter.
- // Pull that URI using resultData.getData().
- Uri uri = null;
- if (resultData != null) {
- uri = resultData.getData();
- try {
- mViewModel.addTrustAnchor(getContentResolver().openInputStream(uri));
- } catch (Exception e) {
- int errorId = R.string.trust_anchor_create_error;
- Toast.makeText(this, errorId, Toast.LENGTH_SHORT).show();
- }
-
- }
+ Intent intent = new Intent(this, CertificateActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ ArrayList certList = new ArrayList<>();
+ for (int i=0; i mProcessing = new MutableLiveData<>();
+ private final MutableLiveData mError = new MutableLiveData<>();
+
+ private final MutableLiveData mSuccess = new MutableLiveData<>();
+
+ @Inject
+ CertificateViewModel(SchedulersFacade schedulersFacade,
+ StoreTrustAnchorUseCase storeTrustAnchorUseCase,
+ SaveIntermediateCertificateUseCase saveIntermediateCertificateUseCase,
+ SaveEndEntityCertificateUseCase saveEndEntityCertificateUseCase) {
+ this.mSchedulersFacade = schedulersFacade;
+ this.storeTrustAnchorUseCase = storeTrustAnchorUseCase;
+ this.saveIntermediateCertificateUseCase = saveIntermediateCertificateUseCase;
+ this.saveEndEntityCertificateUseCase = saveEndEntityCertificateUseCase;
+ }
+
+ @Override
+ protected void onCleared() {
+ mDisposables.clear();
+ }
+
+ public LiveData isProcessing() {
+ return mProcessing;
+ }
+
+ public LiveData getError() {
+ return mError;
+ }
+
+ public LiveData getSuccess() {
+ return mSuccess;
+ }
+
+ public void saveTrustAnchor(InputStream is) {
+ mDisposables.add(storeTrustAnchorUseCase.execute(is)
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .subscribe(
+ () -> mSuccess.setValue(true),
+ throwable -> {
+ mSuccess.setValue(false);
+ mError.setValue(new ViewModelError(Error.ROOT_CERTIFICATE, null));
+ }
+ ));
+ }
+
+ public void saveIntermediateCertificate(int credid, InputStream is) {
+ mDisposables.add(saveIntermediateCertificateUseCase.execute(credid, is)
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .subscribe(
+ () -> mSuccess.setValue(true),
+ throwable -> {
+ mSuccess.setValue(false);
+ mError.setValue(new ViewModelError(Error.INTERMEDIATE_CERTIFICATE, null));
+ }
+ ));
+ }
+
+ public void saveEndEntityCertificate(InputStream fileIs, InputStream keyIs) {
+ mDisposables.add(saveEndEntityCertificateUseCase.execute(fileIs, keyIs)
+ .subscribeOn(mSchedulersFacade.io())
+ .observeOn(mSchedulersFacade.ui())
+ .subscribe(
+ () -> mSuccess.setValue(true),
+ throwable -> {
+ mSuccess.setValue(false);
+ mError.setValue(new ViewModelError(Error.END_ENTITY_CERTIFICATE, null));
+ }
+ ));
+ }
+
+ public enum Error implements ViewModelErrorType {
+ ROOT_CERTIFICATE,
+ INTERMEDIATE_CERTIFICATE,
+ END_ENTITY_CERTIFICATE
+ }
+
+}
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/DeviceListViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/DeviceListViewModel.java
index c9dd2dcec00f5d55e490ddfa829c5f129a787f0e..b8385b3ac3580fb2dca5fc0da6ad361d2ce96d9f 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/DeviceListViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/DeviceListViewModel.java
@@ -21,6 +21,8 @@
*/
package org.openconnectivity.otgc.viewmodel;
+import android.content.Context;
+
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
@@ -36,6 +38,7 @@ import org.openconnectivity.otgc.domain.usecase.SetObtModeUseCase;
import org.openconnectivity.otgc.domain.usecase.wifi.CheckConnectionUseCase;
import org.openconnectivity.otgc.domain.usecase.InitializeIotivityUseCase;
import org.openconnectivity.otgc.domain.usecase.login.LogoutUseCase;
+import org.openconnectivity.otgc.utils.handler.DisplayNotValidCertificateHandler;
import org.openconnectivity.otgc.utils.handler.OCSetRandomPinHandler;
import org.openconnectivity.otgc.utils.viewmodel.CommonError;
import org.openconnectivity.otgc.utils.viewmodel.Response;
@@ -147,8 +150,8 @@ public class DeviceListViewModel extends ViewModel {
return mDeviceId;
}
- public void initializeIotivityStack() {
- disposables.add(mInitializeIotivityUseCase.execute()
+ public void initializeIotivityStack(Context context, DisplayNotValidCertificateHandler displayNotValidCertificateHandler) {
+ disposables.add(mInitializeIotivityUseCase.execute(context, displayNotValidCertificateHandler)
.subscribeOn(schedulersFacade.io())
.observeOn(schedulersFacade.ui())
.subscribe(
diff --git a/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/TrustAnchorViewModel.java b/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/TrustAnchorViewModel.java
index 7849c2ce9af96f64213196da4ddf5ece69117eac..2b6b936abbe4c3d75b91f301f4d57228a169cc23 100644
--- a/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/TrustAnchorViewModel.java
+++ b/otgc/src/main/java/org/openconnectivity/otgc/viewmodel/TrustAnchorViewModel.java
@@ -9,6 +9,8 @@ import androidx.lifecycle.ViewModel;
import org.openconnectivity.otgc.domain.model.resource.secure.cred.OcCredential;
import org.openconnectivity.otgc.domain.usecase.trustanchor.GetTrustAnchorUseCase;
import org.openconnectivity.otgc.domain.usecase.trustanchor.RemoveTrustAnchorByCredidUseCase;
+import org.openconnectivity.otgc.domain.usecase.trustanchor.SaveEndEntityCertificateUseCase;
+import org.openconnectivity.otgc.domain.usecase.trustanchor.SaveIntermediateCertificateUseCase;
import org.openconnectivity.otgc.domain.usecase.trustanchor.StoreTrustAnchorUseCase;
import org.openconnectivity.otgc.utils.rx.SchedulersFacade;
import org.openconnectivity.otgc.utils.viewmodel.ViewModelError;
@@ -31,6 +33,8 @@ public class TrustAnchorViewModel extends ViewModel {
// Use cases
private final StoreTrustAnchorUseCase storeTrustAnchorUseCase;
+ private final SaveIntermediateCertificateUseCase saveIntermediateCertificateUseCase;
+ private final SaveEndEntityCertificateUseCase saveEndEntityCertificateUseCase;
private final GetTrustAnchorUseCase getTrustAnchorUseCase;
private final RemoveTrustAnchorByCredidUseCase removeTrustAnchorByCredidUseCase;
@@ -41,10 +45,14 @@ public class TrustAnchorViewModel extends ViewModel {
@Inject
public TrustAnchorViewModel(SchedulersFacade schedulersFacade,
StoreTrustAnchorUseCase storeTrustAnchorUseCase,
+ SaveIntermediateCertificateUseCase saveIntermediateCertificateUseCase,
+ SaveEndEntityCertificateUseCase saveEndEntityCertificateUseCase,
GetTrustAnchorUseCase getTrustAnchorUseCase,
RemoveTrustAnchorByCredidUseCase removeTrustAnchorByCredidUseCase) {
this.schedulersFacade = schedulersFacade;
this.storeTrustAnchorUseCase = storeTrustAnchorUseCase;
+ this.saveIntermediateCertificateUseCase = saveIntermediateCertificateUseCase;
+ this.saveEndEntityCertificateUseCase = saveEndEntityCertificateUseCase;
this.getTrustAnchorUseCase = getTrustAnchorUseCase;
this.removeTrustAnchorByCredidUseCase = removeTrustAnchorByCredidUseCase;
}
@@ -70,7 +78,7 @@ public class TrustAnchorViewModel extends ViewModel {
return deleteCredid;
}
- public void retrieveTrustAnchors() {
+ public void retrieveCertificates() {
disposable.add(getTrustAnchorUseCase.execute()
.subscribeOn(schedulersFacade.io())
.observeOn(schedulersFacade.ui())
@@ -90,12 +98,32 @@ public class TrustAnchorViewModel extends ViewModel {
.subscribeOn(schedulersFacade.io())
.observeOn(schedulersFacade.ui())
.subscribe(
- () -> retrieveTrustAnchors(),
+ () -> retrieveCertificates(),
throwable -> mError.setValue(new ViewModelError(Error.ADD_ROOT_CERT, throwable.getMessage()))
));
}
- public void removeTrustAnchorByCredid(long credid) {
+ public void saveIntermediateCertificate(Integer credid, InputStream is) {
+ disposable.add(saveIntermediateCertificateUseCase.execute(credid, is)
+ .subscribeOn(schedulersFacade.io())
+ .observeOn(schedulersFacade.ui())
+ .subscribe(
+ () -> retrieveCertificates(),
+ throwable -> mError.setValue(new ViewModelError(Error.ADD_ROOT_CERT, throwable.getMessage()))
+ ));
+ }
+
+ public void saveEndEntityCertificate(InputStream fileIs, InputStream keyIs) {
+ disposable.add(saveEndEntityCertificateUseCase.execute(fileIs, keyIs)
+ .subscribeOn(schedulersFacade.io())
+ .observeOn(schedulersFacade.ui())
+ .subscribe(
+ () -> retrieveCertificates(),
+ throwable -> mError.setValue(new ViewModelError(Error.ADD_ROOT_CERT, throwable.getMessage()))
+ ));
+ }
+
+ public void removeCertificateByCredid(long credid) {
disposable.add(removeTrustAnchorByCredidUseCase.execute(credid)
.subscribeOn(schedulersFacade.io())
.observeOn(schedulersFacade.ui())
diff --git a/otgc/src/main/res/drawable-v23/ic_ocf_logo_white.png b/otgc/src/main/res/drawable-v23/ic_ocf_logo_white.png
new file mode 100644
index 0000000000000000000000000000000000000000..8d6315ad5b10c2b87d8ac4970d730826e5bc9e6d
Binary files /dev/null and b/otgc/src/main/res/drawable-v23/ic_ocf_logo_white.png differ
diff --git a/otgc/src/main/res/drawable-v23/ic_ocf_logo_white.xml b/otgc/src/main/res/drawable-v23/ic_ocf_logo_white_old.xml
similarity index 100%
rename from otgc/src/main/res/drawable-v23/ic_ocf_logo_white.xml
rename to otgc/src/main/res/drawable-v23/ic_ocf_logo_white_old.xml
diff --git a/otgc/src/main/res/drawable-v23/splash.xml b/otgc/src/main/res/drawable-v23/splash.xml
index 93fa1f498b3be517affdd86f5acbe5c4216080d4..4f2e0696f27cc3d3ecf5f6d95f9f2be7716442ea 100644
--- a/otgc/src/main/res/drawable-v23/splash.xml
+++ b/otgc/src/main/res/drawable-v23/splash.xml
@@ -23,8 +23,10 @@
-
+ android:drawable="@color/colorPrimary" />
+ -
+
+
\ No newline at end of file
diff --git a/otgc/src/main/res/drawable/ocf_logo_horizontal.png b/otgc/src/main/res/drawable/ocf_logo_horizontal.png
index e588d337bd0af4b541374d85f013b8ed7d6c0146..3ee083e7622aa22bef04b96f092d9757030462e5 100644
Binary files a/otgc/src/main/res/drawable/ocf_logo_horizontal.png and b/otgc/src/main/res/drawable/ocf_logo_horizontal.png differ
diff --git a/otgc/src/main/res/layout/activity_certificate.xml b/otgc/src/main/res/layout/activity_certificate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..808762b49514f1e383d22f8184e22796422ddd88
--- /dev/null
+++ b/otgc/src/main/res/layout/activity_certificate.xml
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/otgc/src/main/res/mipmap-hdpi/ic_launcher.png b/otgc/src/main/res/mipmap-hdpi/ic_launcher.png
index 6295522eeff9c1aaa38d56b1c78925b8a97b3b95..bdc512864d1583bc041788ada66b90109e2ac548 100644
Binary files a/otgc/src/main/res/mipmap-hdpi/ic_launcher.png and b/otgc/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/otgc/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/otgc/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
index 27b0bb2a9e092e1ff1f4a6640b662fc1544648a8..320ca1734a36774d0ef02409f23fa447f4db1791 100644
Binary files a/otgc/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and b/otgc/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/otgc/src/main/res/mipmap-hdpi/ic_launcher_round.png b/otgc/src/main/res/mipmap-hdpi/ic_launcher_round.png
index e47f68e7ae4791f47eecc2b45779c1c5c3afb053..e4397cca6331c6293c5ce4965d5d7fa000f66510 100644
Binary files a/otgc/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/otgc/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/otgc/src/main/res/mipmap-mdpi/ic_launcher.png b/otgc/src/main/res/mipmap-mdpi/ic_launcher.png
index cc4cc3b1bce7b72c7a375f202c6d67f2373e2468..428a1f8c61c549f8ba6006c13401ee5de153db7e 100644
Binary files a/otgc/src/main/res/mipmap-mdpi/ic_launcher.png and b/otgc/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/otgc/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/otgc/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
index 56458fbc88d65f8dd13deceb7b0b94e5c1e4d968..b07d216b6286ab1d7550ba5a075c3f1f0dd0492a 100644
Binary files a/otgc/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and b/otgc/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/otgc/src/main/res/mipmap-mdpi/ic_launcher_round.png b/otgc/src/main/res/mipmap-mdpi/ic_launcher_round.png
index 909632b490ea829b24f5407f228dab680c4f9487..d092b0aec8249514c4ab5dd04f4273fff6d9acd0 100644
Binary files a/otgc/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/otgc/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/otgc/src/main/res/mipmap-xhdpi/ic_launcher.png b/otgc/src/main/res/mipmap-xhdpi/ic_launcher.png
index d3781c9e2a6155835aa70ce3fba6241d4aa46ce2..c079b596020ee37be49e05e487324993a8aa67fa 100644
Binary files a/otgc/src/main/res/mipmap-xhdpi/ic_launcher.png and b/otgc/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/otgc/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/otgc/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
index 88426e9eb6dbf0d337692480b89997b53b4f0426..4a1a11a532f527a496e2011f85b0cebe8f2c4aa1 100644
Binary files a/otgc/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and b/otgc/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/otgc/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/otgc/src/main/res/mipmap-xhdpi/ic_launcher_round.png
index 93bff2198a69ae7770ea793c3474ed914666e609..2eaedb0cfe78a83e12d827ff0119f309fa0b2eca 100644
Binary files a/otgc/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/otgc/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/otgc/src/main/res/mipmap-xxhdpi/ic_launcher.png b/otgc/src/main/res/mipmap-xxhdpi/ic_launcher.png
index b8cfb86d013cd791f1b4937fa03d1fd352059665..dba50e629896a3233729bd4f6866c6dd58d92a96 100644
Binary files a/otgc/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/otgc/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
index 34a3f846d5eecd80cf0befcf1b43907aed65e12d..59480a365533fa4750f6a5251a050f30f57e00d8 100644
Binary files a/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and b/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
index 06120d31021b4423650503fc765f94672c9d0c7b..6778dcae57deaa1e977846b4913c46d46635999c 100644
Binary files a/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/otgc/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher.png
index ee74ec630ee7d8acb930d2f0dbb0191798a010ef..d684c7169f9c51e0e95f2e3cd7f8f8d9dd4fa6c2 100644
Binary files a/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
index 32815fb21cad4c22c230938ae29e912fa4d97729..0838d2d4b98557c7dc091ca25845253238d0fadc 100644
Binary files a/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and b/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
index f73ccde54c577ef1f168b6eb1ce8ac996011e3fe..c3051620029aca4a07dfd5046ed9c63a17476831 100644
Binary files a/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/otgc/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/otgc/src/main/res/values-es/strings.xml b/otgc/src/main/res/values-es/strings.xml
index bdf95663a0e4881092d4462a22b96c51b38a3b31..b6f839872c2a9ad4401b9d3ea08d102a56166ae7 100644
--- a/otgc/src/main/res/values-es/strings.xml
+++ b/otgc/src/main/res/values-es/strings.xml
@@ -60,7 +60,7 @@
Cerrar
Modo cliente
Modo OBT
- Certificados de confianza
+ Gestión de certificados
Mostrar trazas
Ajustes
Sin nombre
@@ -76,6 +76,7 @@
El dispositivo está siendo eliminado de su red OCF. Por favor, espere…
Reiniciar el dispositivo
¿Está seguro de que desea eliminar todos los dispositivos vinculados?
+ Certificado Inválido
Desvincular
Error buscando dispositivos
OTM no está disponible para el modo Client
@@ -166,7 +167,7 @@
ID de rol: %1$s, Autoridad de rol: %2$s
ID Credencial: %1$s
Uso: %1$s
- No se puede almacenar el certificado raíz desde la ubicación seleccionada
+ No se puede almacenar el certificado desde la ubicación seleccionada
Error escaneando las redes Wi-Fi
Configurando y conectado el dispositivo mediante Wi-Fi Easy Setup
Wi-Fi Easy Setup ha fallado
@@ -186,7 +187,7 @@
Cancelar
ID de rol
Autoridad de rol
- Certificados de confianza
+ Certificados
Descubrimiento
Ámbito multicast IPv6
Retardo en las peticiones (en segundos)
diff --git a/otgc/src/main/res/values/strings.xml b/otgc/src/main/res/values/strings.xml
index e1c28f3f148fdf9dfdbc6eef91c905e8a5b4f991..86820dfd113df8ee578d177ef72e6a7da46d98f4 100644
--- a/otgc/src/main/res/values/strings.xml
+++ b/otgc/src/main/res/values/strings.xml
@@ -114,10 +114,25 @@
Insert device name
Confirm
Cancel
+ Not Valid Certificate
+ OK
+ Certificate type:
+ Root certificate
+ Intermediate certificate
+ End entity certificate
+ Select certificate
+ Select key
+ Store root certificate has failed
+ Store intermediate certificate has failed
+ Store end entity certificate has failed
+ Credential ID:
+ No selected certificate
+ No selected key
+ New Certificate
Reset
Client mode
OBT mode
- Trust Anchor Management
+ Certificate Management
Show log
Settings
Sign out
@@ -217,7 +232,7 @@
Credential ID: %1$s
Usage: %1$s
Role ID: %1$s, Role Authority: %2$s
- Cannot store the root certificate from the selected location
+ Cannot store the certificate from the selected location
Unnamed
Info
@@ -262,7 +277,7 @@
Role ID
Role authority
- Trust Anchor Management
+ Certificate Management
Settings
@@ -278,7 +293,7 @@
Onboarding Tool and Generic Client
Version %1$s
- © 2019 Open Connectivity Foundation.
+ © 2020 Open Connectivity Foundation.
All rights reserved.
Powered by:
DEKRA Testing and Certification, S.A.U.