Skip to content

Commit

Permalink
Fixes for dump flow in GPData & GPKeyInfo (#264)
Browse files Browse the repository at this point in the history
* Fixed issue, for invalid dates in CPLC, and printing the card recognition data, allowin Format 2 from 2.3 Spec
* Added parsing for ECC keys
  • Loading branch information
xavo95 authored Dec 31, 2021
1 parent a009664 commit 86ebbda
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
53 changes: 37 additions & 16 deletions library/src/main/java/pro/javacard/gp/GPData.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,35 +94,51 @@ public static void pretty_print_card_data(byte[] data) {
if (isdd != null) {
// Loop all sub-values
for (BerTlv vt : isdd.getValues()) {
BerTlv ot = vt.find(new BerTag(0x06));
if (ot != null) {
String oid = oid2string(ot.getBytesValue());
System.out.println("Tag " + new BigInteger(1, vt.getTag().bytes).toString(16) + ": " + oid);

if(vt.isTag(new BerTag(0x06))) {
String oid = logAndGetOidFromByteArray(vt.getTag().bytes, vt.getBytesValue());
if (oid.equals("1.2.840.114283.1")) {
System.out.println("-> Global Platform card");
}
} else if (vt.isTag(new BerTag(0x60))) {
String oid = logAndGetOidFromByteArray(vt.getTag().bytes,
vt.getValues().get(0).getBytesValue()); // 6X are constructed tags
if (oid.startsWith("1.2.840.114283.2")) {
String[] p = oid.substring("1.2.840.114283.2.".length()).split("\\.");
System.out.println("-> GP Version: " + String.join(".", p));
}

if (oid.startsWith("1.2.840.114283.4")) {
String[] p = oid.substring("1.2.840.114283.4.".length()).split("\\.");
if (p.length == 2) {
System.out.println("-> GP SCP0" + p[0] + " i=" + String.format("%02x", Integer.valueOf(p[1])));
} else {
if (oid.equals("1.2.840.114283.4.0")) {
System.out.println("-> GP SCP80 i=00");
} else if (vt.isTag(new BerTag(0x63))) {
String oid = logAndGetOidFromByteArray(vt.getTag().bytes,
vt.getValues().get(0).getBytesValue()); // 6X are constructed tags
if (oid.startsWith("1.2.840.114283.3")) {
System.out.println("-> GP card is uniquely identified by the Issuer Identification Number (IIN) and Card Image Number (CIN)");
}
} else if (vt.isTag(new BerTag(0x64))) {
// Format 1 and Format 2 support
for (BerTlv ot : vt.getValues()) {
byte[] oidBytes = ot.getBytesValue();
String oid = logAndGetOidFromByteArray(ot.getTag().bytes, oidBytes);
if (oid.startsWith("1.2.840.114283.4")) {
byte[] scp = Arrays.copyOfRange(oidBytes, oidBytes.length - 2, oidBytes.length);
if (scp.length == 2) {
System.out.printf("-> GP SCP%02x i=%02x%n", scp[0], scp[1]);
}
}
}
} else if (vt.isTag(new BerTag(0x65))) {
// TODO: No format defined yet?
} else if (vt.isTag(new BerTag(0x66))) {
String oid = logAndGetOidFromByteArray(vt.getTag().bytes,
vt.getValues().get(0).getBytesValue()); // 6X are constructed tags
if (oid.startsWith("1.3.6.1.4.1.42.2.110.1")) {
String p = oid.substring("1.3.6.1.4.1.42.2.110.1.".length());
if (p.length() == 1) {
System.out.println("-> JavaCard v" + p);
}
}
} else if (vt.isTag(new BerTag(0x67))) {
// TODO: SCP10 parsing, is it worth it?
} else if (vt.isTag(new BerTag(0x68))) {
// TODO: SCP10 parsing, is it worth it?
}
}
}
Expand Down Expand Up @@ -376,6 +392,12 @@ public static String oid2string(byte[] oid) {
}
}

private static String logAndGetOidFromByteArray(byte[] tag, byte[] tlv) {
String oid = oid2string(tlv);
System.out.println("Tag " + new BigInteger(1, tag).toString(16) + ": " + oid);
return oid;
}

public static String oid2version(byte[] bytes) throws GPDataException {
String oid = oid2string(bytes);
return oid.substring("1.2.840.114283.2.".length());
Expand Down Expand Up @@ -460,9 +482,8 @@ public enum Field {
}

public static Optional<LocalDate> toRelativeDate(byte[] v, LocalDate now) throws GPDataException {
// 0xFFFF is caught below.
if (v[0] == 0 && v[1] == 0) {
logger.debug("0x0000 does not represent a valid date");
if ((v[0] == 0 && v[1] == 0) || (v[0] == (byte) 0xFF && v[1] == (byte) 0xFF)) {
logger.debug("0x0000/0xFFFF does not represent a valid date");
return Optional.empty();
}
String sv = HexUtils.bin2hex(v);
Expand Down
6 changes: 6 additions & 0 deletions library/src/main/java/pro/javacard/gp/GPKeyInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,15 @@ public GPKeyInfo(int version, int id, List<GPKeyInfoElement> elements, int acces
} else {
// FIXME: reduce here RSA to a single public key
Optional<GPKeyInfoElement> rsa = valid.stream().filter(e -> e.key == GPKey.RSA_PUB_N).findFirst();
Optional<GPKeyInfoElement> ecc = valid.stream().filter(e ->
(e.key == GPKey.EC_PRIV) || (e.key == GPKey.EC_PUB)).findFirst();
if (rsa.isPresent()) {
this.length = rsa.get().keyLength;
this.type = GPKey.RSA_PUB_N;
} else if (ecc.isPresent()) {
// TODO: If ecc, shall we use the CRT parameter on the second element EC_PARAM_REF, to know the exact curve?
this.length = ecc.get().keyLength;
GPKey.get(ecc.get().key.getType()).ifPresent(gpKey -> this.type = gpKey);
} else {
logger.error("Multiple unsupported elements in key info: {} ", elements);
throw new GPDataException("Multiple unsupported elements in key info template");
Expand Down

0 comments on commit 86ebbda

Please sign in to comment.