Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v0.13.2] [proguard] fixed issues with dropped themis symbols ==> develop #9

Merged
merged 11 commits into from
Oct 9, 2020
Merged
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# This repository is experimental and is not supported by [cossacklabs](https://www.cossacklabs.com/), authors of [themis](https://github.com/cossacklabs/themis/)

The project depends on `themis` library binaries.
The version has been pinned to `v0.13.2`.

Expand Down Expand Up @@ -35,9 +37,46 @@ Do not commit binaries and artefacts to your repo
* Carthage directory binary contents
* *.aar packages

## Known issues

Build artefact optimizer of Xamarin.Forms or Xamarin.Android might strip native Java classes from the binding lib.
This happens when `Link SDK assemblies only` option is selected for the `Linker Behaviour` settings entry.
See the logs example below.

### TL;DR; Add `proguard.cfg` file to your android app project with the following text:
```
-keep class com.cossacklabs.themis.**
-keep class com.cossacklabs.themis.** {*;}
```
Make sure that it has a `ProguardConfiguration` build step.


The issue could not be reproduced on this demo project yet. However, a larger commercial project had it for the same `.cproj` settings of both themis bindings and android app project.
For example:
```
Java.Lang.IncompatibleClassChangeError: no non-static method "Lcom/cossacklabs/themis/SecureCellSeal;.decrypt([B[B)[B"
[orion.mobile] at Java.Interop.JniEnvironment+InstanceMethods.GetMethodID (Java.Interop.JniObjectReference type, System.String name, System.String signature) [0x0005b] in <42d2b7086f0a46efb99253c5db1ecca9>:0
[orion.mobile] at Android.Runtime.JNIEnv.GetMethodID (System.IntPtr kls, System.String name, System.String signature) [0x00007] in <3080427739614e60a939a88bf3f838d5>:0
[orion.mobile] at Com.Cossacklabs.Themis.SecureCell+ISealInvoker.Decrypt (System.Byte[] p0, System.Byte[] p1) [0x00017] in <cd618986d1ce4194b63cdd3366dad291>:0
[orion.mobile] at Themis.Droid.CellSealDroid.UnwrapData (Themis.ISecureCellData cipherTextData, System.Byte[] context) [0x0007e] in <a492e7118e094c3296442a386fe5d80e>:0
[orion.mobile] --- End of inner exception stack trace ---
```

**More info** can be found in the following **github issue** of the `cossacklabs/themis` repository:
https://github.com/cossacklabs/themis/issues/716


Useful articles that helped troubleshooting:
* https://gist.github.com/JonDouglas/dda6d8ace7d071b0e8cb
* https://stackoverflow.com/questions/38967851/missing-methods-and-classes-in-jar-after-building-xamarin-app
* https://medium.com/androiddevelopers/troubleshooting-proguard-issues-on-android-bce9de4f8a74
* https://blog.mindorks.com/things-to-care-while-using-proguard-in-android-application
* https://blog.mindorks.com/r8-vs-proguard-in-android
* https://www.jon-douglas.com/2017/04/13/linker-bitdiffer/


---

☕ Buy me a coffee <br>
With ETH 🔸: 0xD961220f3C356Bee7E7905377fE9Da95DE6F978E <br>
With BTC ₿: bc1qte94s9smlzy8k0jxlfzp7pzkdx9xzztnngcg4n
With BTC ₿: bc1qhjm5d62rysuh5rmylpstuvpgtat67v9xv0edtm
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidLinkMode>None</AndroidLinkMode>
<MandroidI18n>cjk;mideast;other;rare;west</MandroidI18n>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -105,5 +105,8 @@
<Name>themis.droid.wrapper</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ProguardConfiguration Include="proguard.cfg" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
</Project>
8 changes: 8 additions & 0 deletions app/ThemisDemoXamarin.Android/proguard.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

-dontwarn com.samsung.**
-keep class com.samsung.** {*;}


-keep class com.cossacklabs.themis.**
-keep class com.cossacklabs.themis.** {*;}

12 changes: 8 additions & 4 deletions lib-bindings/themis/themis.droid.wrapper/CellSealBuilderDroid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public ICellSeal BuildCellSealForMasterKey(byte[] masterKeyData)
{
throw new ThemisXamarinBridgeException(
message: "[FAIL] [droid] CellSealBuilderDroid.BuildCellSealForMasterKey()",
dataAsHex: null,
contextAsHex: null,
dataAsBase64: null,
contextAsBase64: null,
inner: ex);
}
}
Expand All @@ -51,8 +55,8 @@ public ISecureCellData BuildCipherTextFromStream(Stream cipherTextStream)

var wrappedStreamData =
new SecureCellData(
protectedData: cipherTextStreamBytes,
additionalData: null);
/*protectedData:*/ cipherTextStreamBytes,
/*additionalData:*/ null);

var result = new SecureCellDataDroid(cipherTextHandle: null);
return result;
Expand All @@ -64,8 +68,8 @@ public ISecureCellData BuildCipherText(byte[] cipherTextData)

var wrappedStreamData =
new SecureCellData(
protectedData: cipherTextData,
additionalData: null);
/*protectedData:*/ cipherTextData,
/*additionalData:*/ null);

var result = new SecureCellDataDroid(cipherTextHandle: wrappedStreamData);
return result;
Expand Down
12 changes: 12 additions & 0 deletions lib-bindings/themis/themis.droid.wrapper/CellSealDroid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public CellSealDroid(byte[] masterKeyData)
{
throw new ThemisXamarinBridgeException(
message: "[FAIL] [droid] SecureCell java constructor failed",
dataAsHex: null,
contextAsHex: null,
dataAsBase64: null,
contextAsBase64: null,
inner: ex);
}
}
Expand Down Expand Up @@ -78,6 +82,10 @@ public byte[] UnwrapData(
{
throw new ThemisXamarinBridgeException(
message: "[FAIL] [droid] SecureCell.Unprotect() java method failed",
dataAsHex: ConvertUtilsPortable.ByteArrayToHexString(cipherTextBytes),
contextAsHex: ConvertUtilsPortable.ByteArrayToHexString(context),
dataAsBase64: Convert.ToBase64String(cipherTextBytes),
contextAsBase64: Convert.ToBase64String(context),
inner: ex);
}
}
Expand All @@ -100,6 +108,10 @@ public ISecureCellData WrapData(
{
throw new ThemisXamarinBridgeException(
message: "[FAIL] [droid] SecureCell.Protect() java method failed",
dataAsHex: null, // avoid leaking plain text in logs
contextAsHex: ConvertUtilsPortable.ByteArrayToHexString(context), // seems ok to log context
dataAsBase64: null, // avoid leaking plain text in logs
contextAsBase64: Convert.ToBase64String(context),
inner: ex);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public byte[] GetEncryptedData()
{
throw new ThemisXamarinBridgeException(
message: "[FAIL] [droid] SecureCellData.GetProtectedData() java method failed",
dataAsHex: null,
contextAsHex: null,
dataAsBase64: null,
contextAsBase64: null,
inner: ex);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ public byte[] DeriveKey(byte[] fromData, byte[] context = null)
{
throw new ThemisXamarinBridgeException(
message: "[FAILED] TSCellContextImprint.WrapData()",
dataAsHex: null,
contextAsHex: null,
dataAsBase64: null,
contextAsBase64: null,
inner: ex);
}

Expand Down
4 changes: 4 additions & 0 deletions lib-bindings/themis/themis.ios.wrapper/CellSealBuilderIos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public ICellSeal BuildCellSealForMasterKey(byte[] masterKeyData)
{
throw new ThemisXamarinBridgeException(
message: "[FAIL] [iOS] CellSealBuilderIos.BuildCellSealForMasterKey()",
dataAsHex: null,
contextAsHex: null,
dataAsBase64: null,
contextAsBase64: null,
inner: ex);
}
}
Expand Down
14 changes: 13 additions & 1 deletion lib-bindings/themis/themis.ios.wrapper/CellSealIos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public CellSealIos(NSData masterKeyData)
{
throw new ThemisXamarinBridgeException(
message: "TSCellSeal constructor has failed",
dataAsHex: null,
contextAsHex: null,
dataAsBase64: null,
contextAsBase64: null,
inner: ex);
}
}
Expand Down Expand Up @@ -67,14 +71,18 @@ public byte[] UnwrapData(
{
plainTextData =
_implCellSeal.UnwrapData(
message: castedCipherTextData.cipherText,
message: castedCipherTextData.CipherText,
context: nsContextData,
error: out themisError);
}
catch (Exception ex)
{
throw new ThemisXamarinBridgeException(
message: "TSCellSeal.UnwrapData() has failed",
dataAsHex: ConvertUtilsPortable.ByteArrayToHexString(cipherTextData.GetEncryptedData()),
contextAsHex: ConvertUtilsPortable.ByteArrayToHexString(context),
dataAsBase64: Convert.ToBase64String(cipherTextData.GetEncryptedData()),
contextAsBase64: Convert.ToBase64String(context),
inner: ex);
}

Expand Down Expand Up @@ -114,6 +122,10 @@ public ISecureCellData WrapData(
{
throw new ThemisXamarinBridgeException(
message: "TSCellSeal.WrapData() has failed",
dataAsHex: null, // to avoid leaking plain text
contextAsHex: ConvertUtilsPortable.ByteArrayToHexString(context),
dataAsBase64: null, // to avoid leaking plain text
contextAsBase64: Convert.ToBase64String(context),
inner: ex);
}

Expand Down
14 changes: 13 additions & 1 deletion lib-bindings/themis/themis.pcl/ConvertUtilsPortable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.IO;


Expand Down Expand Up @@ -82,5 +83,16 @@ public static string ByteArrayToString(byte[] stringAsTextData)

return result;
}

public static string ByteArrayToHexString(byte[] data)
{
if (data == null)
{
return null;
}

string result = BitConverter.ToString(data).Replace("-", string.Empty);
return result;
}
}
}
15 changes: 15 additions & 0 deletions lib-bindings/themis/themis.pcl/ThemisXamarinBridgeException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ namespace Themis
{
public class ThemisXamarinBridgeException: PlatformNotSupportedException
{
public string DataAsHex { get; private set; }
public string ContextAsHex { get; private set; }

public string DataAsBase64 { get; private set; }
public string ContextAsBase64 { get; private set; }

public ThemisXamarinBridgeException(): base()
{
}
Expand All @@ -22,9 +28,18 @@ public ThemisXamarinBridgeException(string message): base(message)

public ThemisXamarinBridgeException(
string message,
string dataAsHex,
string contextAsHex,
string dataAsBase64,
string contextAsBase64,
Exception inner)
: base(message, inner)
{
DataAsHex = dataAsHex;
ContextAsHex = contextAsHex;

DataAsBase64 = dataAsBase64;
ContextAsBase64 = contextAsBase64;
}
}

Expand Down
5 changes: 5 additions & 0 deletions lib-bindings/themis/themis.pcl/themis.pcl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
</PropertyGroup>

</Project>