Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ecsec Public
reqesidta-prototype
client-signer
Commits
17a9ffb8
Commit
17a9ffb8
authored
Oct 22, 2019
by
Michael Rauh
Browse files
Remove obsolete reflection code
parent
150f9daf
Changes
3
Hide whitespace changes
Inline
Side-by-side
ifd/scio-backend/pcsc/src/main/java/org/openecard/scio/PCSCExceptionExtractor.java
View file @
17a9ffb8
/****************************************************************************
* Copyright (C) 2015-201
8
ecsec GmbH.
* Copyright (C) 2015-201
9
ecsec GmbH.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
...
...
@@ -24,9 +24,8 @@ package org.openecard.scio;
import
javax.annotation.Nonnull
;
import
javax.smartcardio.CardException
;
import
jnasmartcardio.Smartcardio.JnaPCSCException
;
import
org.openecard.common.ifd.scio.SCIOErrorCode
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
...
...
@@ -36,50 +35,20 @@ import org.slf4j.LoggerFactory;
*/
public
class
PCSCExceptionExtractor
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
PCSCExceptionExtractor
.
class
);
public
static
SCIOErrorCode
getCode
(
@Nonnull
CardException
mainException
)
{
return
getCode
((
Exception
)
mainException
);
return
getCode
((
JnaPCSC
Exception
)
mainException
);
}
/**
* Gets the actual error code from the given CardException.
* This method uses reflections to access the actual error code which is hidden in the Java SmartcardIO. In case no
* error code can be found, {@link SCIOErrorCode#SCARD_F_UNKNOWN_ERROR} is returned.
* Gets the actual error code from the given JnaPCSCException.
* In case no error code can be found, {@link SCIOErrorCode#SCARD_F_UNKNOWN_ERROR} is returned.
*
* @param mainException The exception coming from the Java SmartcardIO.
* @return The code extracted from the exception, or {@link SCIOErrorCode#SCARD_F_UNKNOWN_ERROR} if no code could be
* extracted.
*/
public
static
SCIOErrorCode
getCode
(
@Nonnull
Exception
mainException
)
{
Throwable
cause
=
getPCSCException
(
mainException
);
// check the type of the cause over reflections because these classes might not be available (sun internal)
if
(
cause
!=
null
)
{
try
{
return
SCIOErrorCode
.
valueOf
(
cause
.
getMessage
());
}
catch
(
IllegalArgumentException
ex
)
{
return
SCIOErrorCode
.
SCARD_F_UNKNOWN_ERROR
;
}
}
else
{
return
SCIOErrorCode
.
SCARD_F_UNKNOWN_ERROR
;
}
}
public
static
boolean
hasPCSCException
(
Exception
mainException
)
{
return
getPCSCException
(
mainException
)
!=
null
;
}
private
static
Throwable
getPCSCException
(
Exception
mainException
)
{
Throwable
cause
=
mainException
.
getCause
();
// check the type of the cause over reflections because these classes might not be available (sun internal)
if
(
cause
!=
null
)
{
Class
<?>
c
=
cause
.
getClass
();
if
(
"sun.security.smartcardio.PCSCException"
.
equals
(
c
.
getName
()))
{
return
cause
;
}
}
return
null
;
public
static
SCIOErrorCode
getCode
(
@Nonnull
JnaPCSCException
mainException
)
{
return
SCIOErrorCode
.
getErrorCode
(
Math
.
toIntExact
(
mainException
.
code
));
}
}
ifd/scio-backend/pcsc/src/main/java/org/openecard/scio/PCSCFactory.java
View file @
17a9ffb8
/****************************************************************************
* Copyright (C) 2012-201
8
ecsec GmbH.
* Copyright (C) 2012-201
9
ecsec GmbH.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
...
...
@@ -24,27 +24,10 @@ package org.openecard.scio;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.CompletableFuture
;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeoutException
;
import
javax.smartcardio.CardTerminals
;
import
javax.smartcardio.TerminalFactory
;
import
org.openecard.common.ifd.scio.NoSuchTerminal
;
import
org.openecard.common.ifd.scio.SCIOErrorCode
;
import
org.openecard.common.ifd.scio.SCIOException
;
import
org.openecard.common.ifd.scio.SCIOTerminal
;
import
jnasmartcardio.Smartcardio
;
import
org.openecard.common.ifd.scio.SCIOTerminals
;
import
org.openecard.common.ifd.scio.TerminalState
;
import
org.openecard.common.ifd.scio.TerminalWatcher
;
import
org.openecard.common.util.LinuxLibraryFinder
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -64,8 +47,6 @@ public class PCSCFactory implements org.openecard.common.ifd.scio.TerminalFactor
private
final
String
osName
;
private
TerminalFactory
terminalFactory
;
private
final
CompletableFuture
<
Void
>
initLock
;
/**
* Default constructor with fixes for the faulty SmartcardIO library.
*
...
...
@@ -79,41 +60,13 @@ public class PCSCFactory implements org.openecard.common.ifd.scio.TerminalFactor
System
.
setProperty
(
"sun.security.smartcardio.library"
,
libFile
.
getAbsolutePath
());
}
this
.
initLock
=
new
CompletableFuture
<>();
try
{
LOG
.
info
(
"Trying to initialize PCSC subsystem."
);
loadPCSC
();
initLock
.
complete
(
null
);
LOG
.
info
(
"Successfully initialized PCSC subsystem"
);
terminalFactory
=
TerminalFactory
.
getInstance
(
ALGORITHM
,
null
,
new
Smartcardio
());
LOG
.
info
(
"Successfully initialized PCSC subsystem."
);
}
catch
(
NoSuchAlgorithmException
ex
)
{
LOG
.
error
(
"Failed to initialize smartcard system."
,
ex
);
if
(
isNoServiceException
(
ex
))
{
new
Thread
(()
->
{
while
(!
initLock
.
isDone
())
{
try
{
LOG
.
debug
(
"Trying to initialize PCSC subsystem again."
);
loadPCSC
();
initLock
.
complete
(
null
);
LOG
.
info
(
"Successfully initialized PCSC subsystem"
);
}
catch
(
NoSuchAlgorithmException
exInner
)
{
if
(
isNoServiceException
(
exInner
))
{
try
{
LOG
.
debug
(
"Retrying PCSC initialization in 5 seconds."
);
Thread
.
sleep
(
5000
);
}
catch
(
InterruptedException
ex2
)
{
return
;
}
}
else
{
LOG
.
error
(
"Failed to initialize smartcard system."
,
exInner
);
throw
new
RuntimeException
(
exInner
);
}
}
}
}).
start
();
}
else
{
throw
ex
;
}
LOG
.
error
(
"Failed to initialize smartcard system."
);
throw
ex
;
}
}
...
...
@@ -128,150 +81,11 @@ public class PCSCFactory implements org.openecard.common.ifd.scio.TerminalFactor
@Override
public
SCIOTerminals
terminals
()
{
if
(
terminalFactory
!=
null
)
{
return
new
PCSCTerminals
(
this
);
}
else
{
// dummy for use while the initialization is not working properly
return
new
SCIOTerminals
()
{
@Override
public
List
<
SCIOTerminal
>
list
(
SCIOTerminals
.
State
state
)
throws
SCIOException
{
return
Collections
.
emptyList
();
}
@Override
public
List
<
SCIOTerminal
>
list
()
throws
SCIOException
{
return
Collections
.
emptyList
();
}
@Override
public
SCIOTerminal
getTerminal
(
String
name
)
throws
NoSuchTerminal
{
throw
new
UnsupportedOperationException
(
"Not supported yet."
);
}
@Override
public
TerminalWatcher
getWatcher
()
throws
SCIOException
{
return
new
TerminalWatcher
()
{
@Override
public
SCIOTerminals
getTerminals
()
{
return
terminals
();
}
@Override
public
List
<
TerminalState
>
start
()
throws
SCIOException
{
return
Collections
.
emptyList
();
}
@Override
public
TerminalWatcher
.
StateChangeEvent
waitForChange
(
long
timeout
)
throws
SCIOException
{
try
{
LOG
.
debug
(
"Fake waiting for terminal changes during PCSC initialization phase."
);
initLock
.
get
(
timeout
,
TimeUnit
.
MILLISECONDS
);
}
catch
(
InterruptedException
|
ExecutionException
|
TimeoutException
ex
)
{
// ignore
}
LOG
.
debug
(
"Returning from fake terminal change wait."
);
return
new
StateChangeEvent
();
}
@Override
public
TerminalWatcher
.
StateChangeEvent
waitForChange
()
throws
SCIOException
{
return
waitForChange
(
Long
.
MAX_VALUE
);
}
};
}
};
}
return
new
PCSCTerminals
(
this
);
}
TerminalFactory
getRawFactory
()
{
return
terminalFactory
;
}
private
static
Integer
versionCompare
(
String
str1
,
String
str2
)
{
// code taken from http://stackoverflow.com/a/6702029
String
[]
vals1
=
str1
.
split
(
"\\."
);
String
[]
vals2
=
str2
.
split
(
"\\."
);
int
i
=
0
;
while
(
i
<
vals1
.
length
&&
i
<
vals2
.
length
&&
vals1
[
i
].
equals
(
vals2
[
i
]))
{
i
++;
}
if
(
i
<
vals1
.
length
&&
i
<
vals2
.
length
)
{
return
Integer
.
signum
(
Integer
.
valueOf
(
vals1
[
i
]).
compareTo
(
Integer
.
valueOf
(
vals2
[
i
])));
}
return
Integer
.
signum
(
vals1
.
length
-
vals2
.
length
);
}
final
void
loadPCSC
()
throws
NoSuchAlgorithmException
{
terminalFactory
=
TerminalFactory
.
getInstance
(
ALGORITHM
,
null
);
}
void
reloadPCSC
()
{
try
{
reloadPCSCInt
();
}
catch
(
NoSuchAlgorithmException
ex
)
{
// if it worked once it will work again
String
msg
=
"PCSC changed it's algorithm. There is something really wrong."
;
LOG
.
error
(
msg
,
ex
);
throw
new
RuntimeException
(
"PCSC changed it's algorithm. There is something really wrong."
);
}
catch
(
ClassNotFoundException
|
IllegalAccessException
|
NoSuchFieldException
|
NoSuchMethodException
|
SecurityException
ex
)
{
LOG
.
error
(
"Failed to perform reflection magic to reload TerminalFactory."
,
ex
);
}
catch
(
InvocationTargetException
ex
)
{
if
(
isNoServiceException
(
ex
))
{
// silent drop after giving the system some time to recover for themselves
try
{
Thread
.
sleep
(
5000
);
}
catch
(
InterruptedException
ignore
)
{
Thread
.
currentThread
().
interrupt
();
}
return
;
}
LOG
.
error
(
"Error while invoking PCSC restart functionality."
);
}
}
private
void
reloadPCSCInt
()
throws
ClassNotFoundException
,
NoSuchFieldException
,
IllegalAccessException
,
NoSuchMethodException
,
InvocationTargetException
,
NoSuchAlgorithmException
{
// code taken from http://stackoverflow.com/questions/16921785/
Class
pcscterminal
=
Class
.
forName
(
"sun.security.smartcardio.PCSCTerminals"
);
Field
contextId
=
pcscterminal
.
getDeclaredField
(
"contextId"
);
contextId
.
setAccessible
(
true
);
if
(
contextId
.
getLong
(
pcscterminal
)
!=
0L
)
{
// First get a new context value
Class
pcsc
=
Class
.
forName
(
"sun.security.smartcardio.PCSC"
);
Method
SCardEstablishContext
=
pcsc
.
getDeclaredMethod
(
"SCardEstablishContext"
,
Integer
.
TYPE
);
SCardEstablishContext
.
setAccessible
(
true
);
Field
SCARD_SCOPE_USER
=
pcsc
.
getDeclaredField
(
"SCARD_SCOPE_USER"
);
SCARD_SCOPE_USER
.
setAccessible
(
true
);
long
newId
=
((
Long
)
SCardEstablishContext
.
invoke
(
pcsc
,
SCARD_SCOPE_USER
.
getInt
(
pcsc
)));
contextId
.
setLong
(
pcscterminal
,
newId
);
loadPCSC
();
// Then clear the terminals in cache
CardTerminals
terminals
=
terminalFactory
.
terminals
();
Field
fieldTerminals
=
pcscterminal
.
getDeclaredField
(
"terminals"
);
fieldTerminals
.
setAccessible
(
true
);
Map
termObj
=
(
Map
)
fieldTerminals
.
get
(
terminals
);
termObj
.
clear
();
}
}
private
boolean
isNoServiceException
(
Exception
mainException
)
{
if
(
PCSCExceptionExtractor
.
hasPCSCException
(
mainException
))
{
SCIOErrorCode
code
=
PCSCExceptionExtractor
.
getCode
(
mainException
);
if
(
code
==
SCIOErrorCode
.
SCARD_E_NO_SERVICE
)
{
return
true
;
}
}
return
false
;
}
}
ifd/scio-backend/pcsc/src/main/java/org/openecard/scio/PCSCTerminals.java
View file @
17a9ffb8
/****************************************************************************
* Copyright (C) 2014-201
5
TU Darmstadt.
* Copyright (C) 2014-201
9
TU Darmstadt.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
...
...
@@ -66,7 +66,6 @@ public class PCSCTerminals implements SCIOTerminals {
}
private
void
reloadFactory
()
{
terminalFactory
.
reloadPCSC
();
loadTerminals
();
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment