CryptoCertumCardTest.java
/*
* Copyright 2025 Emmanuel Bourg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.jsign.jca;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.List;
import javax.crypto.Cipher;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.DigestInfo;
import org.junit.Before;
import org.junit.Test;
import net.jsign.DigestAlgorithm;
import static org.junit.Assert.*;
import static org.junit.Assume.*;
public class CryptoCertumCardTest {
public static void assumeCardPresent() {
try {
CardChannel channel = SmartCard.openChannel(CryptoCertumCard.ESIGN_COMMON_PROFILE_AID);
assumeTrue("CryptoCertum card not found", channel != null);
channel.getCard().disconnect(false);
} catch (CardException e) {
assumeNoException("CryptoCertum card not found", e);
}
}
@Before
public void setUp() throws Exception {
assumeCardPresent();
}
@Test
public void testGetCard() throws Exception {
assertNotNull("card not found", CryptoCertumCard.getCard());
}
@Test
public void testGetChallenge() throws Exception {
CryptoCertumCard card = CryptoCertumCard.getCard();
assertNotNull("card not found", card);
byte[] challenge = card.getChallenge(8);
assertNotNull(challenge);
}
@Test
public void testGetEntries() throws Exception {
CryptoCertumCard card = CryptoCertumCard.getCard();
assertNotNull("card not found", card);
List<CryptoCertumCard.Entry> entries = card.getEntries();
assertNotNull(entries);
assertFalse(entries.isEmpty());
}
@Test
public void testGetName() throws Exception {
CryptoCertumCard card = CryptoCertumCard.getCard();
assertNotNull("card not found", card);
List<CryptoCertumCard.Entry> entries = card.getEntries();
for (CryptoCertumCard.Entry entry : entries) {
assertNotNull("name is null for entry " + entry.fid(), entry.name());
}
}
@Test
public void testGetCertificate() throws Exception {
CryptoCertumCard card = CryptoCertumCard.getCard();
assertNotNull("card not found", card);
List<CryptoCertumCard.Entry> entries = card.getEntries();
for (CryptoCertumCard.Entry entry : entries) {
if (entry instanceof CryptoCertumCard.Certificate) {
X509Certificate certificate = ((CryptoCertumCard.Certificate) entry).getCertificate();
assertNotNull("certificate is null for entry " + entry.fid(), certificate);
}
}
}
@Test
public void testGetKeyData() throws Exception {
CryptoCertumCard card = CryptoCertumCard.getCard();
assertNotNull("card not found", card);
card.verify("123456");
byte[] data = card.getKeyData(0x22);
assertNotNull("key data", data);
}
@Test
public void testSign() throws Exception {
CryptoCertumCard card = CryptoCertumCard.getCard();
assertNotNull("card not found", card);
card.verify("123456");
CryptoCertumCard.Key key = (CryptoCertumCard.Key) card.getEntries().stream()
.filter(entry -> entry instanceof CryptoCertumCard.Key).findFirst().orElse(null);
assertNotNull("no key found on the card", key);
byte[] hash = DigestAlgorithm.SHA256.getMessageDigest().digest("Hello CryptoCertum card".getBytes());
byte[] result = card.sign(key, hash);
assertNotNull("result", result);
assertEquals("result length (bits)", key.size, result.length * 8);
// decrypt the message with the public key
CryptoCertumCard.Certificate certificate = card.getCertificate(key.name());
assertNotNull("no certificate found on the card", certificate);
PublicKey publicKey = certificate.getCertificate().getPublicKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
cipher.update(result);
byte[] decrypted = cipher.doFinal();
DigestInfo digestInfo = new DigestInfo(new AlgorithmIdentifier(DigestAlgorithm.SHA256.oid, DERNull.INSTANCE), hash);
byte[] digest = digestInfo.getEncoded(ASN1Encoding.DER);
assertArrayEquals("encrypted message", digest, decrypted);
}
}