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

Configuration with KeyStore does not seem to work #387

Closed
svenfrauen opened this issue Mar 12, 2016 · 6 comments
Closed

Configuration with KeyStore does not seem to work #387

svenfrauen opened this issue Mar 12, 2016 · 6 comments

Comments

@svenfrauen
Copy link

Hi,
I am using ACRA version 4.8.2 and want to connect it to my own Acralyzer backend via a self signed SSL certificate. Therefore, I am configuring a KeyStore with my self signed certificate and building the configuration:

final ConfigurationBuilder configBuilder = new ConfigurationBuilder(app);
configBuilder.setKeyStore(keyStore);
ACRAConfiguration config = configBuilder.build();
ACRA.init(app, config);

However, it seems that the ACRA config does not set the custom KeyStore, as the new config does not include the KeyStore with my certificate. Apparently, the keyStore is not set in the ACRAConfiguration constructor: https://github.com/ACRA/acra/blob/master/src/main/java/org/acra/config/ACRAConfiguration.java#L114

Furthermore, if I try to set the KeyStore directly in the ACRAConfiguration, which is deprecated, I get an exception:

final ConfigurationBuilder configBuilder = new ConfigurationBuilder(app);
ACRAConfiguration config = configBuilder.build();
config.setKeyStore(keyStore);
ACRA.init(app, config);
Caused by: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = org.acra.config.ACRAConfiguration)
                                             at android.os.Parcel.writeSerializable(Parcel.java:1394)
                                             at android.os.Parcel.writeValue(Parcel.java:1341)
                                             at android.os.Parcel.writeArrayMapInternal(Parcel.java:644)
                                             at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313)
                                             at android.os.Bundle.writeToParcel(Bundle.java:1034)
                                             at android.os.Parcel.writeBundle(Parcel.java:669)
                                             at android.content.Intent.writeToParcel(Intent.java:7496)
                                             at android.app.ActivityManagerProxy.startService(ActivityManagerNative.java:3485)
                                             at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1850)
                                             at android.app.ContextImpl.startService(ContextImpl.java:1832)
                                             at android.content.ContextWrapper.startService(ContextWrapper.java:516)
                                             at org.acra.sender.SenderServiceStarter.startService(SenderServiceStarter.java:41)
                                             at org.acra.util.ApplicationStartupProcessor.sendApprovedReports(ApplicationStartupProcessor.java:74)
                                             at org.acra.ACRA.init(ACRA.java:228)
                                             at org.acra.ACRA.init(ACRA.java:155)
                                             at com.demo.utils.ACRADemoConfig.init(ACRADemoConfig.java:47)
                                             at com.demo.DemoApp.enableAcraInProductionOrAcraMode(DemoApp.java:45)
                                             at com.demo.DemoApp.onCreate(DemoApp.java:32)
                                             at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1035)
                                             at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4638)
                                             at android.app.ActivityThread.access$1500(ActivityThread.java:155) 
                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378) 
                                             at android.os.Handler.dispatchMessage(Handler.java:102) 
                                             at android.os.Looper.loop(Looper.java:135) 
                                             at android.app.ActivityThread.main(ActivityThread.java:5343) 
                                             at java.lang.reflect.Method.invoke(Native Method) 
                                             at java.lang.reflect.Method.invoke(Method.java:372) 
                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) 
                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700) 
                                          Caused by: java.io.NotSerializableException: java.security.KeyStore
                                             at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1344)
                                             at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
                                             at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
                                             at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
                                             at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:959)
                                             at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:360)
                                             at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1054)
                                             at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1384)
                                             at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1651)
                                             at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1497)
                                             at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1461)
                                             at android.os.Parcel.writeSerializable(Parcel.java:1389)
                                             at android.os.Parcel.writeValue(Parcel.java:1341) 
                                             at android.os.Parcel.writeArrayMapInternal(Parcel.java:644) 
                                             at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313) 
                                             at android.os.Bundle.writeToParcel(Bundle.java:1034) 
                                             at android.os.Parcel.writeBundle(Parcel.java:669) 
                                             at android.content.Intent.writeToParcel(Intent.java:7496) 
                                             at android.app.ActivityManagerProxy.startService(ActivityManagerNative.java:3485) 
                                             at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1850) 
                                             at android.app.ContextImpl.startService(ContextImpl.java:1832) 
                                             at android.content.ContextWrapper.startService(ContextWrapper.java:516) 
                                             at org.acra.sender.SenderServiceStarter.startService(SenderServiceStarter.java:41) 
                                             at org.acra.util.ApplicationStartupProcessor.sendApprovedReports(ApplicationStartupProcessor.java:74) 
                                             at org.acra.ACRA.init(ACRA.java:228) 
                                             at org.acra.ACRA.init(ACRA.java:155) 
                                             at com.demo.utils.ACRADemoConfig.init(ACRADemoConfig.java:47) 
                                             at com.demo.DemoApp.enableAcraInProductionOrAcraMode(DemoApp.java:45) 
                                             at com.demo.DemoApp.onCreate(DemoApp.java:32) 
                                             at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1035) 
                                             at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4638) 
                                             at android.app.ActivityThread.access$1500(ActivityThread.java:155) 
                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378) 
                                             at android.os.Handler.dispatchMessage(Handler.java:102) 
                                             at android.os.Looper.loop(Looper.java:135) 
                                             at android.app.ActivityThread.main(ActivityThread.java:5343) 
                                             at java.lang.reflect.Method.invoke(Native Method) 
                                             at java.lang.reflect.Method.invoke(Method.java:372)

Is there any other way to set the self signed SSL certificate or is this a problem in ACRA?

Thanks for your time,
Sven!

@william-ferguson-au
Copy link
Member

Hmm, it looks like an oversight that the keyStore is not being transferred across from the ConfigurationBuilder in the ACRAConfiguration constructor.

But the fact that the KeyStore is not serializable may be a bigger problem. We need the KeyStore to be available in the SenderService so we need some way to send it to it.
How are you constructing your KeyStore?
Maybe it's going to require configuring a KeyStoreFactory and configuring that in the ConfigurationBuilder

@svenfrauen
Copy link
Author

Thanks for your fast reply!

Basically, I use a similar approach as Google describes it for constructing the KeyStore: http://developer.android.com/training/articles/security-ssl.html#UnknownCa

Here is my code (the certificate is stored in my asset folder):

CertificateFactory cf = CertificateFactory.getInstance("X.509");
AssetManager am = context.getAssets();
InputStream caInput = new BufferedInputStream(am.open("AcralyzerCA.crt"));
Certificate ca;
try {
     ca = cf.generateCertificate(caInput);
} finally {
     caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);

@william-ferguson-au
Copy link
Member

@svenfrauen Try the change that @F43nd1r has added to master.
He has even provided an out of the box AssetKeyStoreFactory that you can subclass.

@F43nd1r
Copy link
Member

F43nd1r commented Mar 13, 2016

I think in this case AssetKeyStoreFactory can just be instantiated, no need to subclass.

@svenfrauen
Copy link
Author

This is awesome! I just tried the new master code changes and the configuration with AssetKeyStoreFactory and my custom SSL certificate works out of the box. Thanks a lot for the fast and great support!

@william-ferguson-au
Copy link
Member

All thanks go to @F43nd1r on this one :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants