22
33import java .io .ByteArrayInputStream ;
44import java .io .File ;
5- import java .math .BigInteger ;
65import java .security .PublicKey ;
76import java .security .cert .CertificateException ;
87import java .security .cert .CertificateFactory ;
2423import javax .naming .directory .SearchControls ;
2524import javax .naming .directory .SearchResult ;
2625import javax .naming .ldap .LdapName ;
26+ import javax .naming .ldap .Rdn ;
27+ import javax .security .auth .x500 .X500Principal ;
2728
2829import org .slf4j .Logger ;
2930import org .slf4j .LoggerFactory ;
3637 * @see <a href=https://www.skidsolutions.eu/repositoorium/ldap/esteid-ldap-kataloogi-kasutamine/>SK LDAP</a>
3738 */
3839public 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
0 commit comments