Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
portal-sc
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
portal
portal-sc
Commits
4232b0a6
Commit
4232b0a6
authored
14 years ago
by
da1l6
Browse files
Options
Downloads
Patches
Plain Diff
Update Javacard source provided by Martin + Fixes by da1l6
parent
cc81ba57
Branches
master
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ZonenTuereAppletHash/src/ms/warpzone/tuer/applet/TuereApplet.java
+215
-225
215 additions, 225 deletions
...reAppletHash/src/ms/warpzone/tuer/applet/TuereApplet.java
with
215 additions
and
225 deletions
ZonenTuereAppletHash/src/ms/warpzone/tuer/applet/TuereApplet.java
+
215
−
225
View file @
4232b0a6
/**
*
*/
package
ms.warpzone.tuer.applet
;
import
javacard.framework.APDU
;
import
javacard.framework.ISO7816
;
import
javacard.framework.Applet
;
import
javacard.framework.ISOException
;
import
javacard.framework.JCSystem
;
import
javacard.framework.Util
;
import
javacard.security.MessageDigest
;
import
javacard.security.RandomData
;
/**
* @author warpzone
*
*/
public
class
TuereApplet
extends
Applet
{
static
final
byte
CURRENT_VERSION
=
1
;
static
final
byte
CHAL_LEN
=
32
;
// Warnung: Alignment beachten (Vielfaches von 64 Bytes) oder SHA-Code anpassen.
static
final
byte
SECRET_LEN
=
64
;
MessageDigest
md_sha
=
MessageDigest
.
getInstance
(
MessageDigest
.
ALG_SHA
,
false
);
RandomData
devurandom
=
RandomData
.
getInstance
(
RandomData
.
ALG_SECURE_RANDOM
);
// Backup-Secret wird fr trseitigen Fehler vorgehalten. secretBackup wird verwendet gdw. secretBackupActive==true
byte
[]
secret
=
new
byte
[
SECRET_LEN
];
byte
[]
secretBackup
=
new
byte
[
SECRET_LEN
];
// Backupsecret fr trseitigen Schlssel-Aktualisierungsfehler.
boolean
[]
secretBackupActive
=
JCSystem
.
makeTransientBooleanArray
((
short
)
1
,
JCSystem
.
CLEAR_ON_DESELECT
);
// Hlt das Challenge, das wir in 0x02 an die Tr gestellt haben.
byte
[]
challenge
=
JCSystem
.
makeTransientByteArray
(
CHAL_LEN
,
JCSystem
.
CLEAR_ON_DESELECT
);
public
TuereApplet
()
{
for
(
byte
i
=
0
;
i
<
SECRET_LEN
;
i
++){
secret
[
i
]
=
0x00
;
secretBackup
[
i
]
=
0x00
;
}
}
public
static
void
install
(
byte
[]
bArray
,
short
bOffset
,
byte
bLength
)
{
new
TuereApplet
().
register
(
bArray
,
(
short
)
(
bOffset
+
1
),
bArray
[
bOffset
]);
}
public
boolean
select
()
{
secretBackupActive
[
0
]
=
true
;
return
super
.
select
();
}
public
void
process
(
APDU
apdu
)
{
// Good practice: Return 9000 on SELECT
if
(
selectingApplet
())
{
return
;
}
byte
[]
buf
=
apdu
.
getBuffer
();
short
recv
;
short
responseApduStartOffset
;
short
hashSize
;
// Schlssel alternieren bei Misserfolg.
byte
[]
currentSecret
=
secretBackupActive
[
0
]
?
secretBackup
:
secret
;
switch
(
buf
[
ISO7816
.
OFFSET_INS
])
{
/**
* Out = Versionsnummer dieses Applets
* #Out = 1
*/
case
(
byte
)
0x00
:
buf
[
0
]
=
CURRENT_VERSION
;
apdu
.
setOutgoingAndSend
((
short
)
0
,
(
short
)
1
);
break
;
/**
* In = Neues Secret
* #In = 64
*
* Die Karte wird mit dem neuen bergebenen Secret initialisiert.
* Dieser Vorgang wird genau einmal zugelassen.
*/
case
(
byte
)
0x01
:
for
(
byte
i
=
0
;
i
<
SECRET_LEN
;
i
++){
if
(
secret
[
i
]
!=
0x00
){
ISOException
.
throwIt
(
ISO7816
.
SW_CONDITIONS_NOT_SATISFIED
);
}
}
if
(
buf
[
ISO7816
.
OFFSET_LC
]
!=
SECRET_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
recv
=
apdu
.
setIncomingAndReceive
();
if
(
recv
!=
SECRET_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
// Voraussetzungen erfllt.
JCSystem
.
beginTransaction
();
Util
.
arrayCopy
(
buf
,
ISO7816
.
OFFSET_CDATA
,
secret
,
(
short
)
0
,
SECRET_LEN
);
JCSystem
.
commitTransaction
();
break
;
/**
* In = Challenge fr Auth der Karte
* #In = 32
* Out = sha(secret+salt) + Challenge fr Auth der Tr
* #Out = 20 32 = 52
*/
case
(
byte
)
0x02
:
if
(
buf
[
ISO7816
.
OFFSET_LC
]
!=
CHAL_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
recv
=
apdu
.
setIncomingAndReceive
();
if
(
recv
!=
CHAL_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
short
le
=
(
short
)((
short
)
buf
[
ISO7816
.
OFFSET_CDATA
+
CHAL_LEN
]
&
0x00FF
);
if
(
le
<
md_sha
.
getLength
()){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_DATA
);
}
// Voraussetzungen erfllt.
// Schlssel alternieren bei Misserfolg.
secretBackupActive
[
0
]
=
!
secretBackupActive
[
0
];
currentSecret
=
secretBackupActive
[
0
]
?
secretBackup
:
secret
;
md_sha
.
reset
();
md_sha
.
update
(
currentSecret
,
(
short
)
0
,
SECRET_LEN
);
responseApduStartOffset
=
ISO7816
.
OFFSET_CDATA
+
CHAL_LEN
+
1
;
// Wir werden hier gleich Platz im APDU-Puffer brauchen. Ist der da?
if
(
buf
.
length
-
responseApduStartOffset
<
md_sha
.
getLength
()
+
CHAL_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_BYTES_REMAINING_00
);
}
hashSize
=
md_sha
.
doFinal
(
buf
,
ISO7816
.
OFFSET_CDATA
,
CHAL_LEN
,
buf
,
responseApduStartOffset
);
devurandom
.
generateData
(
challenge
,
(
short
)
0
,
CHAL_LEN
);
Util
.
arrayCopyNonAtomic
(
challenge
,
(
short
)
0
,
buf
,
(
short
)(
responseApduStartOffset
+
hashSize
),
CHAL_LEN
);
apdu
.
setOutgoingAndSend
(
responseApduStartOffset
,
(
short
)(
hashSize
+
CHAL_LEN
));
break
;
/**
* In = Neues Secret gexored mit altem + Antwort auf Challenge aus 0x02
* #In = 64 20 = 84
*
* Bei Erfolg: secret := CDATA xor secret
*/
case
(
byte
)
0x03
:
if
(
buf
[
ISO7816
.
OFFSET_LC
]
!=
SECRET_LEN
+
md_sha
.
getLength
()){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
recv
=
apdu
.
setIncomingAndReceive
();
if
(
recv
!=
SECRET_LEN
+
md_sha
.
getLength
()){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
responseApduStartOffset
=
(
short
)(
ISO7816
.
OFFSET_CDATA
+
SECRET_LEN
+
md_sha
.
getLength
());
md_sha
.
reset
();
md_sha
.
update
(
currentSecret
,
(
short
)
0
,
SECRET_LEN
);
md_sha
.
doFinal
(
challenge
,
(
short
)
0
,
CHAL_LEN
,
buf
,
responseApduStartOffset
);
if
(
Util
.
arrayCompare
(
buf
,
(
short
)(
ISO7816
.
OFFSET_CDATA
+
SECRET_LEN
),
buf
,
responseApduStartOffset
,
md_sha
.
getLength
())
!=
0
)
{
ISOException
.
throwIt
(
ISO7816
.
SW_SECURITY_STATUS_NOT_SATISFIED
);
}
//Response passt; Tr authentifiziert.
for
(
byte
i
=
0
;
i
<
SECRET_LEN
;
i
++){
buf
[
responseApduStartOffset
+
i
]
=
(
byte
)(
currentSecret
[
i
]
^
buf
[
ISO7816
.
OFFSET_CDATA
+
i
]);
}
JCSystem
.
beginTransaction
();
Util
.
arrayCopy
(
currentSecret
,
(
short
)
0
,
secretBackup
,
(
short
)
0
,
SECRET_LEN
);
Util
.
arrayCopy
(
buf
,
responseApduStartOffset
,
secret
,
(
short
)
0
,
SECRET_LEN
);
secretBackupActive
[
0
]
=
true
;
JCSystem
.
commitTransaction
();
break
;
/**
* Keyausgabe fr Debugzwecke.
*
* Out = Secret + Backup-Secret
*/
case
(
byte
)
0xFE
:
responseApduStartOffset
=
ISO7816
.
OFFSET_CDATA
;
Util
.
arrayCopyNonAtomic
(
secret
,
(
short
)
0
,
buf
,
responseApduStartOffset
,
SECRET_LEN
);
Util
.
arrayCopyNonAtomic
(
secretBackup
,
(
short
)
0
,
buf
,
(
short
)(
responseApduStartOffset
+
SECRET_LEN
),
SECRET_LEN
);
apdu
.
setOutgoingAndSend
(
responseApduStartOffset
,
(
short
)(
2
*
SECRET_LEN
));
break
;
/**
* Secrets nullen fr Debugzwecke.
*/
case
(
byte
)
0xFF
:
JCSystem
.
beginTransaction
();
for
(
byte
i
=
0
;
i
<
SECRET_LEN
;
i
++){
secret
[
i
]
=
0x00
;
secretBackup
[
i
]
=
0x00
;
}
JCSystem
.
commitTransaction
();
break
;
/**
* Unbekannte Instruktion (INS).
*/
default
:
ISOException
.
throwIt
(
ISO7816
.
SW_INS_NOT_SUPPORTED
);
}
}
/**
*
*/
package
ms.warpzone.tuer.applet
;
import
javacard.framework.APDU
;
import
javacard.framework.ISO7816
;
import
javacard.framework.Applet
;
import
javacard.framework.ISOException
;
import
javacard.framework.JCSystem
;
import
javacard.framework.Util
;
import
javacard.security.MessageDigest
;
import
javacard.security.RandomData
;
public
class
TuereApplet
extends
Applet
{
static
final
byte
CURRENT_VERSION
=
1
;
static
final
byte
CHAL_LEN
=
32
;
// Warnung: Alignment beachten (Vielfaches von 64 Bytes) oder SHA-Code anpassen.
static
final
byte
SECRET_LEN
=
64
;
MessageDigest
md_sha
=
MessageDigest
.
getInstance
(
MessageDigest
.
ALG_SHA
,
false
);
RandomData
devurandom
=
RandomData
.
getInstance
(
RandomData
.
ALG_SECURE_RANDOM
);
static
byte
[]
store
=
new
byte
[
2
*
SECRET_LEN
];
// Backup-Secret wird für türseitigen Fehler vorgehalten. secretBackup wird verwendet gdw. secretBackupActive==true
boolean
[]
secretBackupActive
=
JCSystem
.
makeTransientBooleanArray
((
short
)
1
,
JCSystem
.
CLEAR_ON_DESELECT
);
// Hält das Challenge, das wir in 0x02 an die Tür gestellt haben.
byte
[]
challenge
=
JCSystem
.
makeTransientByteArray
(
CHAL_LEN
,
JCSystem
.
CLEAR_ON_DESELECT
);
public
TuereApplet
()
{
//Initialisierung erfolgt oben und im KeyStore.
}
public
static
void
install
(
byte
[]
bArray
,
short
bOffset
,
byte
bLength
)
{
new
TuereApplet
().
register
(
bArray
,
(
short
)
(
bOffset
+
1
),
bArray
[
bOffset
]);
}
public
boolean
select
()
{
secretBackupActive
[
0
]
=
true
;
return
super
.
select
();
}
public
void
process
(
APDU
apdu
)
{
// Good practice: Return 9000 on SELECT
if
(
selectingApplet
())
{
return
;
}
byte
[]
buf
=
apdu
.
getBuffer
();
short
recv
;
short
responseApduStartOffset
;
short
hashSize
;
// Schlüssel alternieren bei Misserfolg.
// byte[] currentSecret = secretBackupActive[0] ? secretBackup : secret;
short
secretOffset
=
secretBackupActive
[
0
]
?
SECRET_LEN
:
0
;
switch
(
buf
[
ISO7816
.
OFFSET_INS
])
{
/**
* Out = Versionsnummer dieses Applets
* #Out = 1
*/
case
(
byte
)
0x00
:
buf
[
0
]
=
CURRENT_VERSION
;
apdu
.
setOutgoingAndSend
((
short
)
0
,
(
short
)
1
);
break
;
/**
* In = Neues Secret
* #In = 64
*
* Die Karte wird mit dem neuen übergebenen Secret initialisiert.
* Dieser Vorgang wird genau einmal zugelassen.
*/
case
(
byte
)
0x01
:
for
(
short
i
=
0
;
i
<
store
.
length
;
i
++){
if
(
store
[
i
]
!=
0x00
){
ISOException
.
throwIt
(
ISO7816
.
SW_CONDITIONS_NOT_SATISFIED
);
}
}
if
(
buf
[
ISO7816
.
OFFSET_LC
]
!=
SECRET_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
recv
=
apdu
.
setIncomingAndReceive
();
if
(
recv
!=
SECRET_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
// Voraussetzungen erfüllt.
JCSystem
.
beginTransaction
();
Util
.
arrayCopy
(
buf
,
ISO7816
.
OFFSET_CDATA
,
store
,
(
short
)
0
,
SECRET_LEN
);
JCSystem
.
commitTransaction
();
break
;
/**
* In = Challenge für Auth der Karte
* #In = 32
* Out = sha(secret+salt) + Challenge für Auth der Tür
* #Out = 20 32 = 52
*/
case
(
byte
)
0x02
:
if
(
buf
[
ISO7816
.
OFFSET_LC
]
!=
CHAL_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
recv
=
apdu
.
setIncomingAndReceive
();
if
(
recv
!=
CHAL_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
short
le
=
(
short
)((
short
)
buf
[
ISO7816
.
OFFSET_CDATA
+
CHAL_LEN
]
&
0x00FF
);
if
(
le
<
md_sha
.
getLength
()){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_DATA
);
}
// Voraussetzungen erfüllt.
// Schlüssel alternieren bei Misserfolg.
secretBackupActive
[
0
]
=
!
secretBackupActive
[
0
];
secretOffset
=
secretBackupActive
[
0
]
?
SECRET_LEN
:
0
;
md_sha
.
reset
();
md_sha
.
update
(
store
,
(
short
)
secretOffset
,
SECRET_LEN
);
responseApduStartOffset
=
ISO7816
.
OFFSET_CDATA
+
CHAL_LEN
+
1
;
// Wir werden hier gleich Platz im APDU-Puffer brauchen. Ist der da?
if
(
buf
.
length
-
responseApduStartOffset
<
md_sha
.
getLength
()
+
CHAL_LEN
){
ISOException
.
throwIt
(
ISO7816
.
SW_BYTES_REMAINING_00
);
}
hashSize
=
md_sha
.
doFinal
(
buf
,
ISO7816
.
OFFSET_CDATA
,
CHAL_LEN
,
buf
,
responseApduStartOffset
);
devurandom
.
generateData
(
challenge
,
(
short
)
0
,
CHAL_LEN
);
Util
.
arrayCopyNonAtomic
(
challenge
,
(
short
)
0
,
buf
,
(
short
)(
responseApduStartOffset
+
hashSize
),
CHAL_LEN
);
apdu
.
setOutgoingAndSend
(
responseApduStartOffset
,
(
short
)(
hashSize
+
CHAL_LEN
));
break
;
/**
* In = Neues Secret gexored mit altem + Antwort auf Challenge aus 0x02
* #In = 64 20 = 84
*
* Bei Erfolg: secret := CDATA xor secret
*/
case
(
byte
)
0x03
:
if
(
buf
[
ISO7816
.
OFFSET_LC
]
!=
SECRET_LEN
+
md_sha
.
getLength
()){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
recv
=
apdu
.
setIncomingAndReceive
();
if
(
recv
!=
SECRET_LEN
+
md_sha
.
getLength
()){
ISOException
.
throwIt
(
ISO7816
.
SW_WRONG_LENGTH
);
}
responseApduStartOffset
=
(
short
)(
ISO7816
.
OFFSET_CDATA
+
SECRET_LEN
+
md_sha
.
getLength
());
md_sha
.
reset
();
md_sha
.
update
(
store
,
(
short
)
secretOffset
,
SECRET_LEN
);
md_sha
.
doFinal
(
challenge
,
(
short
)
0
,
CHAL_LEN
,
buf
,
responseApduStartOffset
);
if
(
Util
.
arrayCompare
(
buf
,
(
short
)(
ISO7816
.
OFFSET_CDATA
+
SECRET_LEN
),
buf
,
responseApduStartOffset
,
md_sha
.
getLength
())
!=
0
)
{
ISOException
.
throwIt
(
ISO7816
.
SW_SECURITY_STATUS_NOT_SATISFIED
);
}
//Response passt; Tür authentifiziert.
for
(
byte
i
=
0
;
i
<
SECRET_LEN
;
i
++){
buf
[
responseApduStartOffset
+
i
]
=
(
byte
)(
store
[
i
+
secretOffset
]
^
buf
[
ISO7816
.
OFFSET_CDATA
+
i
]);
}
JCSystem
.
beginTransaction
();
Util
.
arrayCopy
(
store
,
(
short
)
secretOffset
,
store
,
secretOffset
==
SECRET_LEN
?
0
:
SECRET_LEN
,
SECRET_LEN
);
Util
.
arrayCopy
(
buf
,
responseApduStartOffset
,
store
,
(
short
)
0
,
SECRET_LEN
);
//hier wird auf jeden Fall ins erste Secret kopiert.
secretBackupActive
[
0
]
=
true
;
JCSystem
.
commitTransaction
();
break
;
/**
* Keyausgabe für Debugzwecke.
*
* Out = Secret + Backup-Secret
*/
case
(
byte
)
0xFE
:
responseApduStartOffset
=
ISO7816
.
OFFSET_CDATA
;
Util
.
arrayCopyNonAtomic
(
store
,
(
short
)
0
,
buf
,
responseApduStartOffset
,
(
short
)(
2
*
SECRET_LEN
));
apdu
.
setOutgoingAndSend
(
responseApduStartOffset
,
(
short
)(
2
*
SECRET_LEN
));
break
;
/**
* Secrets nullen für Debugzwecke.
*/
case
(
byte
)
0xFF
:
JCSystem
.
beginTransaction
();
Util
.
arrayFillNonAtomic
(
store
,
(
short
)
0
,
(
short
)
store
.
length
,
(
byte
)
0
);
JCSystem
.
commitTransaction
();
break
;
/**
* Unbekannte Instruktion (INS).
*/
default
:
ISOException
.
throwIt
(
ISO7816
.
SW_INS_NOT_SUPPORTED
);
}
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment