Skip to content

Commit 608934e

Browse files
author
Olesja Aarma
committed
Merge branch 'RM-4957' into 'master'
RM-4957: unencode serial_number field in keylabel See merge request cdoc2/cdoc2-java-ref-impl!109
2 parents 945cdd1 + 61c4cb4 commit 608934e

File tree

3 files changed

+51
-16
lines changed

3 files changed

+51
-16
lines changed

cdoc2-lib/src/main/java/ee/cyber/cdoc2/crypto/KeyLabelTools.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import jakarta.annotation.Nullable;
44

55
import java.io.File;
6-
import java.math.BigInteger;
76
import java.net.URLDecoder;
87
import java.net.URLEncoder;
98
import java.nio.charset.StandardCharsets;
@@ -167,12 +166,12 @@ public static KeyLabelParams createCertKeyLabelParams(
167166
/**
168167
* Create eID key label parameters for data section of formatted key label.
169168
* @param keyLabel key label as common name from certificate
170-
* @param serialNumber serial number from certificate
169+
* @param serialNumber serial number, parsed from certificate field 'subjectDn'
171170
* @param keyLabelType key label type from certificate
172171
* @return KeyLabelParams key label parameters required for data section
173172
*/
174173
public static KeyLabelParams createEIdKeyLabelParams(
175-
String keyLabel, BigInteger serialNumber, String keyLabelType
174+
String keyLabel, String serialNumber, String keyLabelType
176175
) {
177176
Map<String, String> keyLabelParamsMap = createKeyLabelParamsMap();
178177
keyLabelParamsMap.put(
@@ -190,7 +189,7 @@ public static KeyLabelParams createEIdKeyLabelParams(
190189
= new KeyLabelParams(EncryptionKeyOrigin.ID_CARD, keyLabelParamsMap);
191190

192191
keyLabelParams.addParam(KeyLabelDataFields.CN.name(), keyLabel);
193-
keyLabelParams.addParam(KeyLabelDataFields.SERIAL_NUMBER.name(), String.valueOf(serialNumber));
192+
keyLabelParams.addParam(KeyLabelDataFields.SERIAL_NUMBER.name(), serialNumber);
194193

195194
int endAfterLastName = keyLabel.indexOf(",");
196195
int endAfterFirstName = keyLabel.indexOf(",", endAfterLastName + 1);

cdoc2-lib/src/main/java/ee/cyber/cdoc2/util/SkLdapUtil.java

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.io.ByteArrayInputStream;
44
import java.io.File;
5-
import java.math.BigInteger;
65
import java.security.PublicKey;
76
import java.security.cert.CertificateException;
87
import java.security.cert.CertificateFactory;
@@ -24,6 +23,8 @@
2423
import javax.naming.directory.SearchControls;
2524
import javax.naming.directory.SearchResult;
2625
import javax.naming.ldap.LdapName;
26+
import javax.naming.ldap.Rdn;
27+
import javax.security.auth.x500.X500Principal;
2728

2829
import org.slf4j.Logger;
2930
import org.slf4j.LoggerFactory;
@@ -36,8 +37,8 @@
3637
* @see <a href=https://www.skidsolutions.eu/repositoorium/ldap/esteid-ldap-kataloogi-kasutamine/>SK LDAP</a>
3738
*/
3839
public final class SkLdapUtil {
39-
private SkLdapUtil() {
4040

41+
private SkLdapUtil() {
4142
}
4243

4344
private static final Logger log = LoggerFactory.getLogger(SkLdapUtil.class);
@@ -155,15 +156,15 @@ public static List<SkLdapUtil.CertificateData> getPublicKeysWithLabels(String[]
155156
for (String id: ids) {
156157
Map<X509Certificate, String> certs = findAuthenticationEstEidCertificates(ctx, id);
157158
if (certs.isEmpty()) {
158-
throw new CertificateException("Identity code " + id + "is not found at server");
159+
throw new CertificateException("Identity code " + id + " is not found at server");
159160
}
160161

161162
for (var certNameEntry: certs.entrySet()) {
162163
X509Certificate cert = certNameEntry.getKey();
163164
String distinguishedName = certNameEntry.getValue();
164165
CertificateData certificateData = getKeyLabel(cert, distinguishedName);
165166
certificateData.setPublicKey(cert.getPublicKey());
166-
certificateData.setSerialNumber(cert.getSerialNumber());
167+
certificateData.setSerialNumber(getSemanticsIdentifier(cert));
167168

168169
log.debug("Adding certificate data {}", certificateData);
169170
certDatas.add(certificateData);
@@ -253,6 +254,39 @@ private static CertificateData getKeyLabel(X509Certificate cert, @Nullable Strin
253254
}
254255
}
255256

257+
/**
258+
* Parse serialNumber from certificate subjectDN serialNumber
259+
* (example subjectDN='SERIALNUMBER=PNOEE-30303039914, GIVENNAME=OK, SURNAME=TESTNUMBER, CN="TESTNUMBER,OK", C=EE')
260+
* @param cert certificate
261+
* @return semanticsIdentifier as String (for example PNOEE-30303039914)
262+
*/
263+
@Nullable
264+
private static String getSemanticsIdentifier(X509Certificate cert) {
265+
X500Principal subjectX500Principal = cert.getSubjectX500Principal();
266+
var knownOids = Map.of(
267+
"2.5.4.5", "serialNumber",
268+
"2.5.4.42", "givenName",
269+
"2.5.4.4", "surname");
270+
271+
// X500Principal in Java 17 doesn't know about knowOids, although deprecated getSubjectDN is able to parse those
272+
// subjectDN='SERIALNUMBER=PNOEE-30303039914, GIVENNAME=OK, SURNAME=TESTNUMBER, CN="TESTNUMBER,OK", C=EE'
273+
String subjectDN = subjectX500Principal.getName(X500Principal.RFC2253, knownOids);
274+
275+
try {
276+
LdapName ln = new LdapName(subjectDN);
277+
278+
for (Rdn rdn : ln.getRdns()) {
279+
if (rdn.getType().equalsIgnoreCase("serialNumber")) {
280+
return rdn.getValue().toString();
281+
}
282+
}
283+
log.info("serialNumber not found from subjectDN {}", subjectDN);
284+
} catch (InvalidNameException ine) {
285+
log.info("Failed to get serialNumber from invalid certificate subjectDN field");
286+
}
287+
return null;
288+
}
289+
256290
public static class CertificateData {
257291
private PublicKey publicKey;
258292
private String keyLabel;
@@ -261,7 +295,7 @@ public static class CertificateData {
261295
@Nullable
262296
private String fingerprint;
263297
@Nullable
264-
private BigInteger serialNumber;
298+
private String serialNumber;
265299
private String keyLabelType;
266300

267301
public CertificateData() {
@@ -276,15 +310,18 @@ public String getKeyLabel() {
276310
return this.keyLabel;
277311
}
278312

313+
@Nullable
279314
public File getFile() {
280315
return this.file;
281316
}
282317

318+
@Nullable
283319
public String getFingerprint() {
284320
return this.fingerprint;
285321
}
286322

287-
public BigInteger getSerialNumber() {
323+
@Nullable
324+
public String getSerialNumber() {
288325
return this.serialNumber;
289326
}
290327

@@ -300,15 +337,15 @@ public void setKeyLabel(String keyLabel) {
300337
this.keyLabel = keyLabel;
301338
}
302339

303-
public void setFile(File file) {
340+
public void setFile(@Nullable File file) {
304341
this.file = file;
305342
}
306343

307-
public void setFingerprint(String fingerprint) {
344+
public void setFingerprint(@Nullable String fingerprint) {
308345
this.fingerprint = fingerprint;
309346
}
310347

311-
public void setSerialNumber(BigInteger serialNumber) {
348+
public void setSerialNumber(@Nullable String serialNumber) {
312349
this.serialNumber = serialNumber;
313350
}
314351

cdoc2-lib/src/test/java/ee/cyber/cdoc2/KeyLabelToolsTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.junit.jupiter.api.Test;
1212

1313
import java.io.File;
14-
import java.math.BigInteger;
1514
import java.nio.charset.StandardCharsets;
1615
import java.util.Map;
1716
import java.util.TreeMap;
@@ -238,7 +237,7 @@ null, null, new File("file_name")
238237
void testEIdLabelParamsCreation() {
239238
KeyLabelParams keyLabelParams = createEIdKeyLabelParams(
240239
"Common,Name,IdentityCode",
241-
BigInteger.valueOf(123456),
240+
"PNOEE-30303039914",
242241
KeyLabelTools.KeyLabelType.CERT.getName()
243242
);
244243

@@ -250,7 +249,7 @@ void testEIdLabelParamsCreation() {
250249
)
251250
);
252251
assertEquals(
253-
"123456",
252+
"PNOEE-30303039914",
254253
getDecodedKeyLabelParamValue(
255254
keyLabelParams.keyLabelParams(),
256255
KeyLabelTools.KeyLabelDataFields.SERIAL_NUMBER

0 commit comments

Comments
 (0)