Skip to content

Commit

Permalink
Better support for AES key for put/replace key
Browse files Browse the repository at this point in the history
  • Loading branch information
martinpaljak committed Sep 29, 2024
1 parent d3a5a72 commit 7373fca
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 15 deletions.
11 changes: 10 additions & 1 deletion library/src/main/java/pro/javacard/gp/GPSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -1061,14 +1061,23 @@ public void putKey(Key key, int version, boolean replace) throws IOException, GP
} else if (key instanceof SecretKey) {
SecretKey sk = (SecretKey) key;
if (sk.getAlgorithm().equals("DESede")) {
logger.info("PUT KEY KCV: {}", HexUtils.bin2hex(GPCrypto.kcv_3des(sk.getEncoded())));
bo.write(encodeKey(cardKeys, Arrays.copyOf(sk.getEncoded(), 16), GPKey.DES3));
} if (sk.getAlgorithm().equals("AES")) {
logger.info("PUT KEY KCV: {}", HexUtils.bin2hex(GPCrypto.kcv_aes(sk.getEncoded())));
bo.write(encodeKey(cardKeys, sk.getEncoded(), GPKey.AES));
} else
throw new IllegalArgumentException("Only 3DES symmetric keys are supported: " + sk.getAlgorithm());
throw new IllegalArgumentException("Only 3DES and AES symmetric keys are supported: " + sk.getAlgorithm());
}

CommandAPDU command = new CommandAPDU(CLA_GP, INS_PUT_KEY, replace ? version : 0x00, 0x01, bo.toByteArray(), 256);
ResponseAPDU response = transmit(command);
GPException.check(response, "PUT KEY failed");
if (response.getData().length == 4) {
int kv = response.getData()[0] & 0xFF;
byte[] kcv = Arrays.copyOfRange(response.getData(), 1, 4);
logger.info("Card stored key {} with KCV {}", GPUtils.intString(kv), HexUtils.bin2hex(kcv));
}
}


Expand Down
7 changes: 2 additions & 5 deletions tool/src/main/java/pro/javacard/gptool/GPTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -479,11 +479,8 @@ public int run(BIBO bibo, String[] argv) {
if (kv.getPublic().isPresent()) {
gp.putKey(kv.getPublic().get(), keyVersion, replace);
} else if (kv.getSymmetric().isPresent()) {
byte[] k = kv.getSymmetric().get();
if (k.length != 16)
throw new IllegalArgumentException("Invalid key length: " + k.length);
// FIXME: implicit DES currently
gp.putKey(GPCrypto.des3key(k), keyVersion, replace);
java.security.Key k = kv.getSymmetric().get();
gp.putKey(k, keyVersion, replace);
} else {
throw new IllegalArgumentException("Only public and symmetric keys are supported for put-key");
}
Expand Down
37 changes: 28 additions & 9 deletions tool/src/main/java/pro/javacard/gptool/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import pro.javacard.gp.GPCrypto;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -41,22 +42,24 @@
import java.security.cert.CertificateException;
import java.util.Optional;

// Helper to convert command line parameters to meaningful key objects.
// XXX: unfortunate name and unfortunate implementation.
public class Key {
byte[] key;
java.security.Key symmetricKey;
PublicKey publicKey;
PrivateKey privateKey;

String s;

private Key(String s, byte[] sym, PublicKey publicKey, PrivateKey privateKey) {
this.key = sym;
private Key(String s, java.security.Key sym, PublicKey publicKey, PrivateKey privateKey) {
this.symmetricKey = sym;
this.publicKey = publicKey;
this.privateKey = privateKey;
this.s = s;
}

public Optional<byte[]> getSymmetric() {
return Optional.ofNullable(key);
public Optional<java.security.Key> getSymmetric() {
return Optional.ofNullable(symmetricKey);
}

public Optional<PublicKey> getPublic() {
Expand Down Expand Up @@ -94,11 +97,27 @@ public static Key valueOf(String v) {
throw new IllegalArgumentException("Could not read PEM: " + e.getMessage(), e);
}
} else {
byte[] k = HexUtils.hex2bin(v);
if (v.startsWith("aes:")) {
byte[] bv = HexUtils.hex2bin(v.substring(4));
if (bv.length == 16 || bv.length == 24 || bv.length == 32) {
return new Key(v, GPCrypto.aeskey(bv), null, null);
} else throw new IllegalArgumentException("Invalid key length: " + bv.length);

} else if (v.startsWith("3des:")) {
byte[] bv = HexUtils.hex2bin(v.substring(5));
if (bv.length == 16) {
return new Key(v, GPCrypto.des3key(bv), null, null);
} else throw new IllegalArgumentException("Invalid key length: " + bv.length);
} else {
byte[] k = HexUtils.hex2bin(v);
if (k.length == 24 || k.length == 32) {
return new Key(v, GPCrypto.aeskey(k), null, null);
} else if (k.length == 16) {
return new Key(v, GPCrypto.des3key(k), null, null);

} else throw new IllegalArgumentException("Invalid key length: " + k.length);
}
// TODO: public keys as curve points.
if (k.length == 16 || k.length == 24 || k.length == 32) {
return new Key(v, k, null, null);
} else throw new IllegalArgumentException("Invalid key length: " + k.length);
}
}

Expand Down

0 comments on commit 7373fca

Please sign in to comment.