Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
C
cert4android
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Analytics
Analytics
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
e
apps
cert4android
Commits
c342cbd8
Commit
c342cbd8
authored
Sep 01, 2016
by
Ricki Hirner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial commit
parents
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
996 additions
and
0 deletions
+996
-0
.gitignore
.gitignore
+2
-0
build.gradle
build.gradle
+18
-0
project.properties
project.properties
+3
-0
src/main/AndroidManifest.xml
src/main/AndroidManifest.xml
+17
-0
src/main/java/at/bitfire/cert4android/CertUtils.java
src/main/java/at/bitfire/cert4android/CertUtils.java
+48
-0
src/main/java/at/bitfire/cert4android/Constants.java
src/main/java/at/bitfire/cert4android/Constants.java
+19
-0
src/main/java/at/bitfire/cert4android/CustomCertManager.java
src/main/java/at/bitfire/cert4android/CustomCertManager.java
+266
-0
src/main/java/at/bitfire/cert4android/CustomCertService.java
src/main/java/at/bitfire/cert4android/CustomCertService.java
+280
-0
src/main/java/at/bitfire/cert4android/TrustCertificateActivity.java
...ava/at/bitfire/cert4android/TrustCertificateActivity.java
+138
-0
src/main/res/drawable/ic_lock_open_white.xml
src/main/res/drawable/ic_lock_open_white.xml
+17
-0
src/main/res/layout/activity_trust_certificate.xml
src/main/res/layout/activity_trust_certificate.xml
+135
-0
src/main/res/values-de/strings.xml
src/main/res/values-de/strings.xml
+20
-0
src/main/res/values/dimen.xml
src/main/res/values/dimen.xml
+5
-0
src/main/res/values/strings.xml
src/main/res/values/strings.xml
+20
-0
src/main/res/values/styles.xml
src/main/res/values/styles.xml
+8
-0
No files found.
.gitignore
0 → 100644
View file @
c342cbd8
build/
cert4android.iml
build.gradle
0 → 100644
View file @
c342cbd8
apply
plugin:
'com.android.library'
android
{
compileSdkVersion
24
buildToolsVersion
"24.0.1"
defaultConfig
{
minSdkVersion
9
targetSdkVersion
24
}
}
dependencies
{
compile
'com.android.support:appcompat-v7:24.+'
compile
'com.android.support:cardview-v7:24.+'
}
\ No newline at end of file
project.properties
0 → 100644
View file @
c342cbd8
android.library
=
true
src/main/AndroidManifest.xml
0 → 100644
View file @
c342cbd8
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"at.bitfire.cert4android"
>
<application>
<service
android:name=
".CustomCertService"
/>
<activity
android:name=
".TrustCertificateActivity"
android:label=
"@string/certificate_notification_connection_security"
android:launchMode=
"singleInstance"
android:excludeFromRecents=
"true"
/>
</application>
</manifest>
src/main/java/at/bitfire/cert4android/CertUtils.java
0 → 100644
View file @
c342cbd8
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at.bitfire.cert4android
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
java.security.KeyStore
;
import
java.security.KeyStoreException
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.cert.X509Certificate
;
import
java.util.logging.Level
;
import
javax.net.ssl.TrustManager
;
import
javax.net.ssl.TrustManagerFactory
;
import
javax.net.ssl.X509TrustManager
;
public
class
CertUtils
{
@Nullable
public
static
X509TrustManager
getTrustManager
(
@Nullable
KeyStore
keyStore
)
{
try
{
TrustManagerFactory
tmf
=
TrustManagerFactory
.
getInstance
(
"X509"
);
tmf
.
init
(
keyStore
);
for
(
TrustManager
trustManager
:
tmf
.
getTrustManagers
())
if
(
trustManager
instanceof
X509TrustManager
)
return
(
X509TrustManager
)
trustManager
;
}
catch
(
NoSuchAlgorithmException
|
KeyStoreException
e
)
{
Constants
.
log
.
log
(
Level
.
SEVERE
,
"Couldn't initialize trust manager"
,
e
);
}
return
null
;
}
@NonNull
public
static
String
getTag
(
@NonNull
X509Certificate
cert
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
byte
b:
cert
.
getSignature
())
sb
.
append
(
Integer
.
toHexString
(
b
&
0xFF
));
return
sb
.
toString
();
}
}
src/main/java/at/bitfire/cert4android/Constants.java
0 → 100644
View file @
c342cbd8
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at.bitfire.cert4android
;
import
java.util.logging.Logger
;
public
class
Constants
{
public
static
Logger
log
=
Logger
.
getLogger
(
"cert4android"
);
public
static
int
NOTIFICATION_CERT_DECISION
=
88809
;
}
src/main/java/at/bitfire/cert4android/CustomCertManager.java
0 → 100644
View file @
c342cbd8
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at.bitfire.cert4android
;
import
android.content.ComponentName
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.ServiceConnection
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.os.HandlerThread
;
import
android.os.IBinder
;
import
android.os.Looper
;
import
android.os.Message
;
import
android.os.Messenger
;
import
android.os.RemoteException
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.util.SparseArray
;
import
java.io.Closeable
;
import
java.security.cert.Certificate
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.logging.Level
;
import
javax.net.ssl.HostnameVerifier
;
import
javax.net.ssl.SSLPeerUnverifiedException
;
import
javax.net.ssl.SSLSession
;
import
javax.net.ssl.X509TrustManager
;
/**
* TrustManager to handle custom certificates. Communicates with
* {@link CustomCertService} to fetch information about custom certificate
* trustworthiness. The IPC with a service is required when multiple processes,
* each of them with an own {@link CustomCertManager}, want to access a synchronized central
* certificate trust store + UI (for accepting certificates etc.).
*
* @author Ricki Hirner
*/
public
class
CustomCertManager
implements
X509TrustManager
,
Closeable
{
/** how log to wait for a decision from {@link CustomCertService} */
protected
static
final
int
SERVICE_TIMEOUT
=
5
*
60
*
1000
;
final
Context
context
;
/** for sending requests to {@link CustomCertService} */
Messenger
service
;
/** to receive replies from {@link CustomCertService} */
final
Messenger
messenger
;
final
AtomicInteger
nextDecisionID
=
new
AtomicInteger
();
final
SparseArray
<
Boolean
>
decisions
=
new
SparseArray
<>();
final
Object
decisionLock
=
new
Object
();
/** system-default trust store */
final
X509TrustManager
systemTrustManager
;
/** Whether to launch {@link TrustCertificateActivity} directly. The notification will always be shown. */
public
boolean
appInForeground
=
true
;
ServiceConnection
serviceConnection
=
new
ServiceConnection
()
{
@Override
public
void
onServiceConnected
(
ComponentName
className
,
IBinder
binder
)
{
Constants
.
log
.
fine
(
"Connected to service"
);
service
=
new
Messenger
(
binder
);
}
@Override
public
void
onServiceDisconnected
(
ComponentName
className
)
{
service
=
null
;
}
};
/**
* Creates a new instance.
* @param context used to bind to {@link CustomCertService}
* @param trustSystemCerts whether to trust system/user-installed CAs (default trust store)
*/
public
CustomCertManager
(
@NonNull
Context
context
,
boolean
trustSystemCerts
)
{
this
.
context
=
context
;
systemTrustManager
=
trustSystemCerts
?
CertUtils
.
getTrustManager
(
null
)
:
null
;
HandlerThread
thread
=
new
HandlerThread
(
"CustomCertificateManagerMessenger"
);
thread
.
start
();
messenger
=
new
Messenger
(
new
Handler
(
thread
.
getLooper
(),
new
MessageHandler
()));
if
(!
context
.
bindService
(
new
Intent
(
context
,
CustomCertService
.
class
),
serviceConnection
,
Context
.
BIND_AUTO_CREATE
))
throw
new
IllegalArgumentException
(
"Couldn't bind service to this context"
);
}
@Override
public
void
close
()
{
if
(
serviceConnection
!=
null
)
context
.
unbindService
(
serviceConnection
);
}
@Override
public
void
checkClientTrusted
(
X509Certificate
[]
chain
,
String
authType
)
throws
CertificateException
{
throw
new
CertificateException
(
"cert4android doesn't validate client certificates"
);
}
/**
* Checks whether a certificate is trusted. If {@link #systemTrustManager} is null (because
* system certificates are not being trusted or available), the first certificate in the chain
* (which is the lowest one, i.e. the actual server certificate) is passed to
* {@link CustomCertService} for further decision.
* @param chain certificate chain to check
* @param authType authentication type (ignored)
* @throws CertificateException in case of an untrusted or questionable certificate
*/
@Override
public
void
checkServerTrusted
(
X509Certificate
[]
chain
,
String
authType
)
throws
CertificateException
{
boolean
trusted
=
false
;
if
(
systemTrustManager
!=
null
)
try
{
systemTrustManager
.
checkServerTrusted
(
chain
,
authType
);
trusted
=
true
;
}
catch
(
CertificateException
e
)
{
Constants
.
log
.
fine
(
"Certificate not trusted by system"
);
}
if
(!
trusted
)
checkCustomTrusted
(
chain
[
0
]);
}
protected
void
checkCustomTrusted
(
X509Certificate
cert
)
throws
CertificateException
{
Constants
.
log
.
fine
(
"Querying custom certificate trustworthiness"
);
Message
msg
=
Message
.
obtain
();
msg
.
what
=
CustomCertService
.
MSG_CHECK_TRUSTED
;
int
id
=
msg
.
arg1
=
nextDecisionID
.
getAndIncrement
();
msg
.
replyTo
=
messenger
;
Bundle
data
=
new
Bundle
();
data
.
putSerializable
(
CustomCertService
.
MSG_DATA_CERTIFICATE
,
cert
);
data
.
putBoolean
(
CustomCertService
.
MSG_DATA_APP_IN_FOREGROUND
,
appInForeground
);
msg
.
setData
(
data
);
try
{
service
.
send
(
msg
);
}
catch
(
RemoteException
ex
)
{
throw
new
CertificateException
(
"Couldn't query custom certificate trustworthiness"
,
ex
);
}
// wait for a reply
long
startTime
=
System
.
currentTimeMillis
();
synchronized
(
decisionLock
)
{
while
(
System
.
currentTimeMillis
()
<
startTime
+
SERVICE_TIMEOUT
)
{
try
{
decisionLock
.
wait
(
SERVICE_TIMEOUT
);
}
catch
(
InterruptedException
ex
)
{
throw
new
CertificateException
(
"Trustworthiness check interrupted"
,
ex
);
}
Boolean
decision
=
decisions
.
get
(
id
);
if
(
decision
!=
null
)
{
decisions
.
delete
(
id
);
if
(
decision
)
// certificate trusted
return
;
else
throw
new
CertificateException
(
"Certificate not trusted"
);
}
}
// timeout occurred
throw
new
CertificateException
(
"Timeout when waiting for certificate trustworthiness decision"
);
}
}
@Override
public
X509Certificate
[]
getAcceptedIssuers
()
{
return
new
X509Certificate
[
0
];
}
// custom methods
public
HostnameVerifier
hostnameVerifier
(
@Nullable
HostnameVerifier
defaultVerifier
)
{
return
new
CustomHostnameVerifier
(
defaultVerifier
);
}
public
void
resetCertificates
()
{
Intent
intent
=
new
Intent
(
context
,
CustomCertService
.
class
);
intent
.
setAction
(
CustomCertService
.
CMD_RESET_CERTIFICATES
);
context
.
startService
(
intent
);
}
// Messenger for receiving replies from CustomCertificateService
public
static
final
int
MSG_CERTIFICATE_DECISION
=
0
;
// arg1: id
// arg2: 1: trusted, 0: not trusted
private
class
MessageHandler
implements
Handler
.
Callback
{
@Override
public
boolean
handleMessage
(
Message
msg
)
{
Constants
.
log
.
fine
(
"Received reply from CustomCertificateService: "
+
msg
);
switch
(
msg
.
what
)
{
case
MSG_CERTIFICATE_DECISION:
synchronized
(
decisionLock
)
{
decisions
.
put
(
msg
.
arg1
,
msg
.
arg2
!=
0
);
decisionLock
.
notifyAll
();
}
return
true
;
}
return
false
;
}
}
// hostname verifier
protected
class
CustomHostnameVerifier
implements
HostnameVerifier
{
final
HostnameVerifier
defaultVerifier
;
public
CustomHostnameVerifier
(
HostnameVerifier
defaultVerifier
)
{
this
.
defaultVerifier
=
defaultVerifier
;
}
@Override
public
boolean
verify
(
String
host
,
SSLSession
sslSession
)
{
Constants
.
log
.
fine
(
"Verifying certificate for "
+
host
);
if
(
defaultVerifier
!=
null
&&
defaultVerifier
.
verify
(
host
,
sslSession
))
return
true
;
// default hostname verifier couldn't verify the hostname →
// accept the hostname as verified only if the certificate has been accepted be the user
try
{
Certificate
[]
cert
=
sslSession
.
getPeerCertificates
();
if
(
cert
instanceof
X509Certificate
[]
&&
cert
.
length
>
0
)
{
checkCustomTrusted
((
X509Certificate
)
cert
[
0
]);
Constants
.
log
.
fine
(
"Certificate is in custom trust store, accepting"
);
return
true
;
}
}
catch
(
SSLPeerUnverifiedException
e
)
{
Constants
.
log
.
log
(
Level
.
WARNING
,
"Couldn't get certificate for host name verification"
,
e
);
}
catch
(
CertificateException
ignored
)
{
}
return
false
;
}
}
}
src/main/java/at/bitfire/cert4android/CustomCertService.java
0 → 100644
View file @
c342cbd8
/*
* Copyright © Ricki Hirner (bitfire web engineering).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*/
package
at.bitfire.cert4android
;
import
android.app.Notification
;
import
android.app.NotificationManager
;
import
android.app.PendingIntent
;
import
android.app.Service
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.os.IBinder
;
import
android.os.Message
;
import
android.os.Messenger
;
import
android.os.RemoteException
;
import
android.support.v4.app.NotificationManagerCompat
;
import
android.support.v7.app.NotificationCompat
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.lang.ref.WeakReference
;
import
java.security.KeyStore
;
import
java.security.KeyStoreException
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.logging.Level
;
import
javax.net.ssl.X509TrustManager
;
public
class
CustomCertService
extends
Service
{
protected
static
final
String
CMD_CERTIFICATION_DECISION
=
"certDecision"
;
protected
static
final
String
EXTRA_CERTIFICATE
=
"certificate"
;
protected
static
final
String
EXTRA_TRUSTED
=
"trusted"
;
protected
static
final
String
CMD_RESET_CERTIFICATES
=
"resetCertificates"
;
public
static
final
String
KEYSTORE_DIR
=
"KeyStore"
,
KEYSTORE_NAME
=
"KeyStore.bks"
;
File
keyStoreFile
;
KeyStore
trustedKeyStore
;
X509TrustManager
customTrustManager
;
Set
<
X509Certificate
>
untrustedCerts
=
new
HashSet
<>();
final
Map
<
X509Certificate
,
Set
<
ReplyInfo
>>
pendingDecisions
=
new
HashMap
<>();
@Override
public
void
onCreate
()
{
keyStoreFile
=
new
File
(
getDir
(
KEYSTORE_DIR
,
Context
.
MODE_PRIVATE
),
KEYSTORE_NAME
);
try
{
trustedKeyStore
=
KeyStore
.
getInstance
(
KeyStore
.
getDefaultType
());
InputStream
is
;
try
{
is
=
new
FileInputStream
(
keyStoreFile
);
}
catch
(
FileNotFoundException
e
)
{
Constants
.
log
.
fine
(
"No custom keystore found"
);
is
=
null
;
}
trustedKeyStore
.
load
(
is
,
null
);
customTrustManager
=
CertUtils
.
getTrustManager
(
trustedKeyStore
);
}
catch
(
KeyStoreException
|
NoSuchAlgorithmException
|
CertificateException
|
IOException
e
)
{
Constants
.
log
.
log
(
Level
.
SEVERE
,
"Couldn't initialize key store"
,
e
);
}
}
boolean
inTrustStore
(
X509Certificate
cert
)
{
try
{
return
trustedKeyStore
.
getCertificateAlias
(
cert
)
!=
null
;
}
catch
(
KeyStoreException
e
)
{
Constants
.
log
.
log
(
Level
.
WARNING
,
"Couldn't query custom key store"
,
e
);
return
false
;
}
}
// started service
@Override
public
int
onStartCommand
(
Intent
intent
,
int
flags
,
int
id
)
{
Constants
.
log
.
fine
(
"Received command:"
+
intent
);
switch
(
intent
.
getAction
())
{
case
CMD_CERTIFICATION_DECISION:
onReceiveDecision
(
(
X509Certificate
)
intent
.
getSerializableExtra
(
EXTRA_CERTIFICATE
),
intent
.
getBooleanExtra
(
EXTRA_TRUSTED
,
false
)
);
break
;
case
CMD_RESET_CERTIFICATES:
untrustedCerts
.
clear
();
try
{
for
(
String
alias
:
Collections
.
list
(
trustedKeyStore
.
aliases
()))
trustedKeyStore
.
deleteEntry
(
alias
);
saveKeyStore
();
}
catch
(
KeyStoreException
e
)
{
Constants
.
log
.
log
(
Level
.
SEVERE
,
"Couldn't reset custom certificates"
,
e
);
}
}
return
START_NOT_STICKY
;
}
protected
void
onReceiveDecision
(
X509Certificate
cert
,
boolean
trusted
)
{
// remove notification
NotificationManager
nm
=
(
NotificationManager
)
getSystemService
(
NOTIFICATION_SERVICE
);
nm
.
cancel
(
CertUtils
.
getTag
(
cert
),
Constants
.
NOTIFICATION_CERT_DECISION
);
// put into trust store, if trusted
if
(
trusted
)
{
untrustedCerts
.
remove
(
cert
);
try
{
trustedKeyStore
.
setCertificateEntry
(
cert
.
getSubjectDN
().
getName
(),
cert
);
}
catch
(
KeyStoreException
e
)
{
Constants
.
log
.
log
(
Level
.
SEVERE
,
"Couldn't add certificate into key store"
,
e
);
}
saveKeyStore
();
}
else
untrustedCerts
.
add
(
cert
);
// notify receivers which are waiting for a decision
Set
<
ReplyInfo
>
receivers
=
pendingDecisions
.
get
(
cert
);
if
(
receivers
!=
null
)
{
for
(
ReplyInfo
receiver
:
receivers
)
{
Message
message
=
Message
.
obtain
();
message
.
what
=
CustomCertManager
.
MSG_CERTIFICATE_DECISION
;
message
.
arg1
=
receiver
.
id
;
message
.
arg2
=
trusted
?
1
:
0
;
try
{
receiver
.
messenger
.
send
(
message
);
}
catch
(
RemoteException
e
)
{
Constants
.
log
.
log
(
Level
.
WARNING
,
"Couldn't forward decision to CustomCertManager"
,
e
);
}
}
pendingDecisions
.
remove
(
cert
);
}
}
protected
void
saveKeyStore
()
{
try
{
Constants
.
log
.
fine
(
"Saving custom certificate key store to "
+
keyStoreFile
);
OutputStream
os
=
new
FileOutputStream
(
keyStoreFile
);
trustedKeyStore
.
store
(
os
,
null
);
}
catch
(
IOException
|
KeyStoreException
|
NoSuchAlgorithmException
|
CertificateException
e
)
{
Constants
.
log
.
log
(
Level
.
SEVERE
,
"Couldn't save custom certificate key store"
,
e
);
}
}
// bound service; Messenger for IPC
public
static
final
int
MSG_CHECK_TRUSTED
=
1
;
public
static
final
String
MSG_DATA_CERTIFICATE
=
"certificate"
,
MSG_DATA_APP_IN_FOREGROUND
=
"appInForeground"
;
final
Messenger
messenger
=
new
Messenger
(
new
MessageHandler
(
this
));
@Override
public
IBinder
onBind
(
Intent
intent
)
{
return
messenger
.
getBinder
();
}
protected
static
class
MessageHandler
extends
Handler
{
private
final
WeakReference
<
CustomCertService
>
serviceRef
;
MessageHandler
(
CustomCertService
service
)
{
serviceRef
=
new
WeakReference
<
CustomCertService
>(
service
);
}
@Override
public
void
handleMessage
(
Message
msg
)
{
CustomCertService
service
=
serviceRef
.
get
();
if
(
service
==
null
)
{
Constants
.
log
.
warning
(
"Couldn't handle message: service not available"
);
return
;
}
Constants
.
log
.
info
(
"Handling request: "
+
msg
);
int
id
=
msg
.
arg1
;
Bundle
data
=
msg
.
getData
();
ReplyInfo
replyInfo
=
new
ReplyInfo
(
msg
.
replyTo
,
id
);
switch
(
msg
.
what
)
{
case
MSG_CHECK_TRUSTED:
X509Certificate
cert
=
(
X509Certificate
)
data
.
getSerializable
(
MSG_DATA_CERTIFICATE
);
Set
<
ReplyInfo
>
reply
=
service
.
pendingDecisions
.
get
(
cert
);
if
(
reply
!=
null
)
{
// there's already a pending decision for this certificate, just add this reply messenger
reply
.
add
(
replyInfo
);
}
else
{
/* no pending decision for this certificate:
1. check whether it's known as trusted or non-trusted – in this case, send a reply instantly
2. otherwise, create a pending decision
*/
if
(
service
.
untrustedCerts
.
contains
(
cert
))
{
Constants
.
log
.
fine
(
"Certificate is cached as untrusted"
);
try
{
msg
.
replyTo
.
send
(
obtainMessage
(
CustomCertManager
.
MSG_CERTIFICATE_DECISION
,
id
,
0
));
}
catch
(
RemoteException
e
)
{
Constants
.
log
.
log
(
Level
.
WARNING
,
"Couldn't send distrust information to CustomCertManager"
,
e
);
}
}
else
if
(
service
.
inTrustStore
(
cert
))
{
try
{
msg
.
replyTo
.
send
(
obtainMessage
(
CustomCertManager
.
MSG_CERTIFICATE_DECISION
,
id
,
1
));
}
catch
(
RemoteException
e
)
{
Constants
.
log
.
log
(
Level
.
WARNING
,
"Couldn't send trust information to CustomCertManager"
,
e
);
}