Skip to content

Commit

Permalink
Merge pull request #539 from martenrebane/MOPPAND-1358
Browse files Browse the repository at this point in the history
Update user-agent when signing
  • Loading branch information
Counter178 authored Aug 15, 2024
2 parents 062a3a5 + 6a087b0 commit adae5e0
Show file tree
Hide file tree
Showing 20 changed files with 60 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
import ee.ria.DigiDoc.configuration.ConfigurationProvider;
import ee.ria.DigiDoc.configuration.loader.CachedConfigurationHandler;
import ee.ria.DigiDoc.configuration.util.FileUtils;
import ee.ria.DigiDoc.configuration.util.UserAgentUtil;
import ee.ria.DigiDoc.common.UserAgentUtil;
import ee.ria.DigiDoc.crypto.RecipientRepository;
import ee.ria.DigiDoc.sign.SignLib;
import ee.ria.DigiDoc.smartcardreader.SmartCardReaderManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import ee.ria.DigiDoc.common.ProxySetting;
import ee.ria.DigiDoc.common.ProxyUtil;
import ee.ria.DigiDoc.common.exception.NoInternetConnectionException;
import ee.ria.DigiDoc.configuration.util.UserAgentUtil;
import ee.ria.DigiDoc.common.UserAgentUtil;
import ee.ria.DigiDoc.sign.SignLib;
import okhttp3.Call;
import okhttp3.OkHttpClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static ee.ria.DigiDoc.android.utils.Predicates.duplicates;

import android.content.Context;

import androidx.annotation.Nullable;

import com.google.common.collect.ImmutableList;
Expand Down Expand Up @@ -67,12 +69,12 @@ public final Observable<IdCardDataResponse> data() {
.observeOn(AndroidSchedulers.mainThread());
}

public Single<SignedContainer> sign(Token token, SignedContainer container,
public Single<SignedContainer> sign(Context context, Token token, SignedContainer container,
byte[] pin2, @Nullable RoleData roleData) {
return Single
.fromCallable(() -> {
IdCardData data = data(token);
return container.sign(data.signCertificate().data(),
return container.sign(context, data.signCertificate().data(),
signData -> ByteString.of(token.calculateSignature(pin2,
signData.toByteArray(),
data.signCertificate().ellipticCurve())), roleData);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package ee.ria.DigiDoc.android.signature.update;

import android.content.Context;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import androidx.annotation.Nullable;

import java.io.File;
import java.util.Arrays;

import javax.inject.Inject;

Expand Down Expand Up @@ -184,7 +184,7 @@ Observable<? extends SignatureAddResponse> sign(File containerFile,
idCardService.data()
.filter(dataResponse -> dataResponse.token() != null)
.switchMapSingle(dataResponse ->
idCardService.sign(dataResponse.token(), container,
idCardService.sign(navigator.activity(), dataResponse.token(), container,
idCardRequest.pin2(), roleData)).firstOrError())
.map(IdCardResponse::success)
.toObservable()
Expand Down Expand Up @@ -215,11 +215,11 @@ Observable<? extends SignatureAddResponse> sign(File containerFile,
}
}

public Single<SignedContainer> sign(String signatureValue, byte[] dataToSign,
public Single<SignedContainer> sign(Context context, String signatureValue, byte[] dataToSign,
SignedContainer container,
@Nullable RoleData roleData) {
return Single
.fromCallable(() -> container.sign(ByteString.of(dataToSign),
.fromCallable(() -> container.sign(context, ByteString.of(dataToSign),
signData -> ByteString.encodeUtf8(signatureValue), roleData))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private NFCResponse onTagDiscovered(NfcAdapter adapter, Tag tag) {
r = nfc.communicateSecure(CMD_SET_ENV_SIGN, SET_ENV_SIGN);
Timber.log(Log.DEBUG, "Set ENV:%x %s", r.code, Hex.toHexString(r.data));

container.sign(cert.data(),
container.sign(navigator.activity(), cert.data(),
signData -> ByteString.of(nfc.calculateSignature(signData.toByteArray())), role);
} catch (TagLostException exc) {
Timber.log(Log.ERROR, exc.getMessage());
Expand Down
Binary file modified common-lib/libs/libdigidocpp.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
package ee.ria.DigiDoc.common;

import android.content.Context;

import androidx.annotation.Nullable;

import org.bouncycastle.util.encoders.Base64;
Expand All @@ -26,17 +28,21 @@
import java.security.cert.CertificateException;

import ee.ria.libdigidocpp.Container;
import ee.ria.libdigidocpp.ExternalSigner;
import ee.ria.libdigidocpp.Signature;
import ee.ria.libdigidocpp.StringVector;

public class ContainerWrapper {

private static final String SIGNATURE_PROFILE_TS = "time-stamp";

private final Context context;
private final Container container;
private Signature signature;
private ExternalSigner signer;

public ContainerWrapper(String containerPath) {
public ContainerWrapper(Context context, String containerPath) {
this.context = context;
this.container = Container.open(containerPath, new DigidocContainerOpenCB(false));
}

Expand All @@ -45,13 +51,17 @@ public Container getContainer() {
}

public String prepareSignature(String cert, @Nullable RoleData roleData) throws CertificateException {
signer = new ExternalSigner(CertificateUtil.x509Certificate(cert).getEncoded());
signer.setProfile(SIGNATURE_PROFILE_TS);
signer.setUserAgent(UserAgentUtil.getUserAgent(context));
if (roleData != null) {
signature = container.prepareWebSignature(CertificateUtil.x509Certificate(cert).getEncoded(), SIGNATURE_PROFILE_TS,
new StringVector(TextUtil.removeEmptyStrings(roleData.getRoles())), roleData.getCity(),
roleData.getState(), roleData.getZip(), roleData.getCountry());
} else {
signature = container.prepareWebSignature(CertificateUtil.x509Certificate(cert).getEncoded(), SIGNATURE_PROFILE_TS);
signer.setSignerRoles(new StringVector(TextUtil.removeEmptyStrings(roleData.getRoles())));
signer.setSignatureProductionPlace(roleData.getCity(), roleData.getState(),
roleData.getZip(), roleData.getCountry());
}

signature = container.prepareSignature(signer);

if (signature != null) {
byte[] dataToSignBytes = Base64.encode(signature.dataToSign());
String dataToSign = new String(dataToSignBytes, StandardCharsets.UTF_8);
Expand All @@ -65,9 +75,14 @@ public void finalizeSignature(String signatureValue) {
if (signature == null) {
throw new IllegalStateException("Cannot finalize uninitialized signature");
}

if (signer == null) {
throw new IllegalStateException("Cannot finalize uninitialized signer");
}

byte[] signatureValueBytes = Base64.decode(signatureValue);
signature.setSignatureValue(signatureValueBytes);
signature.extendSignatureProfile(SIGNATURE_PROFILE_TS);
signature.extendSignatureProfile(signer);
container.save();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package ee.ria.DigiDoc.configuration.util;
package ee.ria.DigiDoc.common;

import static android.content.Context.USB_SERVICE;

import android.content.Context;
import android.content.pm.PackageInfo;
Expand All @@ -16,12 +18,10 @@
import java.util.Map;
import java.util.stream.Collectors;

import timber.log.Timber;

import static android.content.Context.USB_SERVICE;

public final class UserAgentUtil {

private static final String LOG_TAG = "UserAgentUtil";

private static final List<String> deviceNameFilters = List.of("Smart", "Reader", "Card");

private UserAgentUtil() {}
Expand All @@ -39,7 +39,7 @@ public static String getUserAgent(Context context) {
initializingMessage.append("riadigidoc/").append(getAppVersion(context));
initializingMessage.append(" (Android ").append(Build.VERSION.RELEASE).append(")");
initializingMessage.append(" Lang: ").append(Locale.getDefault().getLanguage());
if (deviceProductNames.size() > 0) {
if (!deviceProductNames.isEmpty()) {
initializingMessage.append(" Devices: ").append(TextUtils.join(", ", deviceProductNames));
}
}
Expand Down Expand Up @@ -73,7 +73,8 @@ private static StringBuilder getAppVersion(Context context) {
.append(".")
.append(getPackageInfo(context).getLongVersionCode());
} catch (PackageManager.NameNotFoundException e) {
Timber.log(Log.ERROR, e, "Failed getting app version from package info");
Log.e(LOG_TAG, String.format("Failed getting app version from package info. %s",
e.getLocalizedMessage()));
}

return versionName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.util.Properties;

import ee.ria.DigiDoc.configuration.loader.CachedConfigurationHandler;
import ee.ria.DigiDoc.configuration.util.UserAgentUtil;
import ee.ria.DigiDoc.common.UserAgentUtil;

public final class ConfigurationManagerTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.Date;

import ee.ria.DigiDoc.configuration.loader.CachedConfigurationHandler;
import ee.ria.DigiDoc.configuration.util.UserAgentUtil;
import ee.ria.DigiDoc.common.UserAgentUtil;
import timber.log.Timber;

public class ConfigurationManagerService extends PatchedJobIntentService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ public Result doWork() {
if (isResponseError(responseWrapper, response, MobileCreateSignatureCertificateResponse.class)) {
return Result.failure();
}
containerWrapper = new ContainerWrapper(request.getContainerPath());
containerWrapper = new ContainerWrapper(getApplicationContext(), request.getContainerPath());
String base64Hash = containerWrapper.prepareSignature(getCertificatePem(response.getCert()), roleDataRequest);
if (base64Hash != null && !base64Hash.isEmpty()) {
Timber.log(Log.DEBUG, "Broadcasting create signature response");
Expand Down
Binary file modified sign-lib/src/debug/jniLibs/arm64-v8a/libdigidoc_java.so
Binary file not shown.
Binary file modified sign-lib/src/debug/jniLibs/armeabi-v7a/libdigidoc_java.so
Binary file not shown.
Binary file modified sign-lib/src/debug/jniLibs/x86_64/libdigidoc_java.so
Binary file not shown.
25 changes: 15 additions & 10 deletions sign-lib/src/main/java/ee/ria/DigiDoc/sign/SignedContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteSource;
import com.google.common.io.Files;
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader;
import com.tom_roush.pdfbox.pdmodel.PDDocument;
import com.tom_roush.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
Expand Down Expand Up @@ -64,6 +63,7 @@
import ee.ria.DigiDoc.common.FileUtil;
import ee.ria.DigiDoc.common.RoleData;
import ee.ria.DigiDoc.common.TextUtil;
import ee.ria.DigiDoc.common.UserAgentUtil;
import ee.ria.DigiDoc.common.exception.InvalidProxySettingsException;
import ee.ria.DigiDoc.common.exception.NoInternetConnectionException;
import ee.ria.DigiDoc.common.exception.SSLHandshakeException;
Expand All @@ -72,6 +72,7 @@
import ee.ria.DigiDoc.sign.utils.Function;
import ee.ria.libdigidocpp.Container;
import ee.ria.libdigidocpp.DataFiles;
import ee.ria.libdigidocpp.ExternalSigner;
import ee.ria.libdigidocpp.Signature.Validator;
import ee.ria.libdigidocpp.Signatures;
import ee.ria.libdigidocpp.StringVector;
Expand Down Expand Up @@ -206,24 +207,28 @@ public final SignedContainer addAdEsSignature(byte[] adEsSignature) throws Excep
return open(file(), false);
}

public final SignedContainer sign(ByteString certificate,
public final SignedContainer sign(Context context, ByteString certificate,
Function<ByteString, ByteString> signFunction,
@Nullable RoleData roleData) throws Exception {
try {
Container container = container(file(), false);

ee.ria.libdigidocpp.Signature signature;

ExternalSigner signer = new ExternalSigner(certificate.toByteArray());
signer.setProfile(signatureProfile());
signer.setUserAgent(UserAgentUtil.getUserAgent(context));

if (roleData != null) {
signature = container.prepareWebSignature(certificate.toByteArray(), signatureProfile(),
new StringVector(TextUtil.removeEmptyStrings(roleData.getRoles())), roleData.getCity(),
roleData.getState(), roleData.getZip(), roleData.getCountry());
} else {
signature = container.prepareWebSignature(certificate.toByteArray(), signatureProfile());
signer.setSignerRoles(new StringVector(TextUtil.removeEmptyStrings(roleData.getRoles())));
signer.setSignatureProductionPlace(roleData.getCity(), roleData.getState(),
roleData.getZip(), roleData.getCountry());
}

ee.ria.libdigidocpp.Signature signature = container.prepareSignature(signer);

if (signature != null) {
ByteString signatureData = signFunction.apply(ByteString.of(signature.dataToSign()));
signature.setSignatureValue(signatureData.toByteArray());
signature.extendSignatureProfile(signatureProfile());
signature.extendSignatureProfile(signer);
container.save();
return open(file(), false);
}
Expand Down
Binary file modified sign-lib/src/main/jniLibs/arm64-v8a/libdigidoc_java.so
Binary file not shown.
Binary file modified sign-lib/src/main/jniLibs/armeabi-v7a/libdigidoc_java.so
Binary file not shown.
Binary file modified sign-lib/src/main/jniLibs/x86_64/libdigidoc_java.so
Binary file not shown.
Binary file modified sign-lib/src/main/res/raw/schema.zip
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public Result doWork() {

Timber.log(Log.DEBUG, "Session status response: %s", sessionStatusResponse.toString());

ContainerWrapper containerWrapper = new ContainerWrapper(request.getContainerPath());
ContainerWrapper containerWrapper = new ContainerWrapper(getApplicationContext(), request.getContainerPath());
String base64Hash = containerWrapper.prepareSignature(getCertificatePem(sessionStatusResponse.getCert().getValue()), roleDataRequest);
if (base64Hash != null && !base64Hash.isEmpty()) {
Timber.log(Log.DEBUG, "Broadcasting signature challenge response");
Expand Down

0 comments on commit adae5e0

Please sign in to comment.