Skip to content

Commit bdcbb1f

Browse files
author
Olesja Aarma
committed
Merge branch 'RM-4475' into 'SID'
RM-4475: Fix keyLabel EID fields names See merge request cdoc2/cdoc2-java-ref-impl!84
2 parents d1f4e1a + 25cad84 commit bdcbb1f

File tree

7 files changed

+100
-41
lines changed

7 files changed

+100
-41
lines changed

cdoc2-cli/src/main/java/ee/cyber/cdoc2/cli/commands/CDocDecryptCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public Void call() throws Exception {
102102
}
103103

104104
private void addKeySharesIfAny(CDocDecrypter cDocDecrypter) throws GeneralSecurityException {
105-
if (this.exclusive.isWithSid() || this.exclusive.isWithMid()) {
105+
if (null != this.exclusive && (this.exclusive.isWithSid() || this.exclusive.isWithMid())) {
106106
cDocDecrypter.withKeyShares(initKeyShareClientFactory());
107107
}
108108
}

cdoc2-cli/src/main/java/ee/cyber/cdoc2/cli/commands/CDocReEncryptCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ private File getDestinationFile() {
153153
private void addKeySharesIfAny(CDocReEncrypter cDocReEncrypter)
154154
throws GeneralSecurityException {
155155

156-
if (this.exclusive.isWithSid() || this.exclusive.isWithMid()) {
156+
if (null != this.exclusive && (this.exclusive.isWithSid() || this.exclusive.isWithMid())) {
157157
cDocReEncrypter.addKeyShareClientFactory(initKeyShareClientFactory());
158158
}
159159
}

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

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,28 @@ public static KeyLabelParams createCertKeyLabelParams(
167167
/**
168168
* Create eID key label parameters for data section of formatted key label.
169169
* @param keyLabel key label as common name from certificate
170-
* @param serialNumber serial number from LDAP server
170+
* @param serialNumber serial number from certificate
171+
* @param keyLabelType key label type from certificate
171172
* @return KeyLabelParams key label parameters required for data section
172173
*/
173174
public static KeyLabelParams createEIdKeyLabelParams(
174-
String keyLabel, BigInteger serialNumber
175+
String keyLabel, BigInteger serialNumber, String keyLabelType
175176
) {
176-
KeyLabelParams keyLabelParams = createKeyLabelCommonParams(
177-
EncryptionKeyOrigin.ID_CARD, KeyLabelDataVersion.V_1
177+
Map<String, String> keyLabelParamsMap = createKeyLabelParamsMap();
178+
keyLabelParamsMap.put(
179+
KeyLabelDataFields.V.name(),
180+
urlEncodeValue(toNumbericString(KeyLabelDataVersion.V_1))
181+
);
182+
183+
KeyLabelType klType = KeyLabelType.ofType(keyLabelType);
184+
keyLabelParamsMap.put(
185+
KeyLabelDataFields.TYPE.name(),
186+
urlEncodeValue(null != klType ? klType.getName() : "")
178187
);
188+
189+
KeyLabelParams keyLabelParams
190+
= new KeyLabelParams(EncryptionKeyOrigin.ID_CARD, keyLabelParamsMap);
191+
179192
keyLabelParams.addParam(KeyLabelDataFields.CN.name(), keyLabel);
180193
keyLabelParams.addParam(KeyLabelDataFields.SERIAL_NUMBER.name(), String.valueOf(serialNumber));
181194

@@ -255,19 +268,23 @@ public static String keyLabelParamsForDisplaying(Map<String, String> keyLabelPar
255268
.collect(Collectors.joining(", "));
256269
}
257270

271+
private static Map<String, String> createKeyLabelParamsMap() {
272+
return new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
273+
}
274+
258275
private static KeyLabelParams createKeyLabelCommonParams(
259276
EncryptionKeyOrigin encryptionKeyOrigin,
260277
KeyLabelTools.KeyLabelDataVersion version
261278
) {
262-
Map<String, String> keyLabelParams = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
279+
Map<String, String> keyLabelParams = createKeyLabelParamsMap();
263280
keyLabelParams.put(
264281
KeyLabelDataFields.V.name(),
265282
urlEncodeValue(toNumbericString(version))
266283
);
267284
KeyLabelType type = getKeyLabelType(encryptionKeyOrigin);
268285
keyLabelParams.put(
269286
KeyLabelDataFields.TYPE.name(),
270-
urlEncodeValue(KeyLabelType.ofType(type))
287+
urlEncodeValue(type.getName())
271288
);
272289

273290
return new KeyLabelParams(encryptionKeyOrigin, keyLabelParams);
@@ -279,7 +296,7 @@ public static KeyLabelType getKeyLabelType(EncryptionKeyOrigin encryptionKeyOrig
279296
return KeyLabelType.CERT;
280297
}
281298
case ID_CARD -> {
282-
return KeyLabelType.ID_CARD;
299+
return KeyLabelType.ID_CARD_DEFAULT;
283300
}
284301
case KEY_SHARE -> {
285302
return KeyLabelType.AUTH;
@@ -396,7 +413,7 @@ public static String convertKeyLabelParamsMapToString(Map<String, String> map) {
396413
}
397414

398415
private static Map<String, String> convertStringToKeyLabelParamsMap(String data) {
399-
Map<String, String> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
416+
Map<String, String> result = createKeyLabelParamsMap();
400417
if (data.isBlank()) {
401418
return result;
402419
}
@@ -431,28 +448,43 @@ public enum KeyLabelDataFields {
431448
* Key label data types
432449
*/
433450
public enum KeyLabelType {
434-
AUTH,
435-
CERT,
436-
ID_CARD,
437-
PUB_KEY,
438-
PW,
439-
SECRET;
440-
441-
public static String ofType(KeyLabelType type) {
442-
return type.name().toLowerCase(Locale.ROOT);
451+
AUTH("auth"),
452+
CERT("cert"),
453+
ID_CARD_DEFAULT("ID-card"),
454+
ID_CARD_DIGI_ID("Digi-ID"),
455+
ID_CARD_E_RESIDENT("Digi-ID E-RESIDENT"),
456+
PUB_KEY("pub_key"),
457+
PW("pw"),
458+
SECRET("secret");
459+
460+
public final String typeName;
461+
462+
KeyLabelType(String name) {
463+
this.typeName = name;
464+
}
465+
466+
public String getName() {
467+
if (typeName.equals("ID-card")
468+
|| typeName.equals("Digi-ID")
469+
|| typeName.equals("Digi-ID E-RESIDENT")) {
470+
return typeName;
471+
}
472+
return typeName.toLowerCase(Locale.ROOT);
443473
}
444474

445-
public static KeyLabelType fromParams(String type) {
446-
return KeyLabelType.getName(type);
475+
private static KeyLabelType fromParams(String type) {
476+
return KeyLabelType.ofType(type);
447477
}
448478

449-
public static KeyLabelType getName(String keyLabelType) {
479+
private static KeyLabelType ofType(String keyLabelType) {
450480
for (var type : KeyLabelType.values()) {
451-
if (null != keyLabelType && type.name().compareToIgnoreCase(keyLabelType) == 0) {
481+
if (null != keyLabelType && type.getName().compareToIgnoreCase(keyLabelType) == 0) {
452482
return type;
453483
}
454484
}
455485

486+
// key label cannot be missing, but according to the specification
487+
// encryption/decryption should not fail
456488
return null;
457489
}
458490
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,11 @@ public static SkLdapUtil.CertificateData loadCertKeyWithLabel(InputStream certIs
264264

265265
var cert = loadCertificate(certIs);
266266
PublicKey publicKey = cert.getPublicKey();
267-
String keyLabel = SkLdapUtil.getKeyLabel(cert);
267+
SkLdapUtil.CertificateData certificateData = SkLdapUtil.getKeyLabel(cert);
268268

269269
String certFingerprint = getCertFingerprint(cert);
270270

271-
SkLdapUtil.CertificateData certificateData = new SkLdapUtil.CertificateData();
272271
certificateData.setPublicKey(publicKey);
273-
certificateData.setKeyLabel(keyLabel);
274272
certificateData.setFingerprint(certFingerprint);
275273

276274
return certificateData;

cdoc2-lib/src/main/java/ee/cyber/cdoc2/crypto/keymaterial/encrypt/EtsiIdentifierEncKeyMaterialBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public EtsiIdentifierEncKeyMaterialBuilder forEId(boolean forEId)
5353
.filter(entry -> EllipticCurve.isSupported(entry.getPublicKey()))
5454
.map(cd -> {
5555
KeyLabelParams keyLabelParams = createEIdKeyLabelParams(
56-
cd.getKeyLabel(), cd.getSerialNumber()
56+
cd.getKeyLabel(), cd.getSerialNumber(), cd.getKeyLabelType()
5757
);
5858
return EncryptionKeyMaterial.fromPublicKey(cd.getPublicKey(), keyLabelParams);
5959
})

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

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.slf4j.Logger;
2929
import org.slf4j.LoggerFactory;
3030

31+
import ee.cyber.cdoc2.crypto.KeyLabelTools;
32+
3133

3234
/**
3335
* Utility class to downloading and parsing certificates from SK LDAP server
@@ -159,11 +161,8 @@ public static List<SkLdapUtil.CertificateData> getPublicKeysWithLabels(String[]
159161
for (var certNameEntry: certs.entrySet()) {
160162
X509Certificate cert = certNameEntry.getKey();
161163
String distinguishedName = certNameEntry.getValue();
162-
String keyLabel = getKeyLabel(cert, distinguishedName);
163-
164-
CertificateData certificateData = new CertificateData();
164+
CertificateData certificateData = getKeyLabel(cert, distinguishedName);
165165
certificateData.setPublicKey(cert.getPublicKey());
166-
certificateData.setKeyLabel(keyLabel);
167166
certificateData.setSerialNumber(cert.getSerialNumber());
168167

169168
log.debug("Adding certificate data {}", certificateData);
@@ -178,23 +177,24 @@ public static List<SkLdapUtil.CertificateData> getPublicKeysWithLabels(String[]
178177
}
179178

180179
/**
181-
* Get label value from certificate. Used as KeyLabel value in FBS header. For SK issued certificates,
182-
* use CN part of Subject as label, for other certs use x509 Subject
180+
* Prepare key label data from certificate. Used as KeyLabel value in FBS header. For SK issued
181+
* certificates, use CN part of Subject as label, for other certs use x509 Subject.
183182
* @param cert certificate to be used for label creation
184183
* @return label parsed from cert
185184
*/
186-
public static String getKeyLabel(X509Certificate cert) {
185+
public static CertificateData getKeyLabel(X509Certificate cert) {
187186
return getKeyLabel(cert, null);
188187
}
189188

190189
/**
191-
* Get label value from certificate. Used as KeyLabel value in FBS header. For SK issued certificates,
192-
* use CN part of Subject as label, for other certs use x509 Subject
190+
* Prepare key label data from certificate. Used as KeyLabel value in FBS header. For SK
191+
* issued certificates, use CN part of Subject as label, for other certs use x509 Subject.
193192
* @param cert certificate to be used for label creation
194193
* @param dName the distinguished name (optional) - used to add certificate type to the label
195194
* @return label parsed from cert
196195
*/
197-
private static String getKeyLabel(X509Certificate cert, @Nullable String dName) {
196+
private static CertificateData getKeyLabel(X509Certificate cert, @Nullable String dName) {
197+
CertificateData certificateData = new SkLdapUtil.CertificateData();
198198
// KeyLabel is UI specific field, so its value is not specified in the Spec.
199199
// DigiDoc4-Client uses this field to hint user what type of eID was used for encryption
200200
// https://github.com
@@ -219,19 +219,37 @@ private static String getKeyLabel(X509Certificate cert, @Nullable String dName)
219219
if (dName != null) {
220220
if (dName.contains(DIGI_ID)) {
221221
keyLabel += " (digi-id)";
222+
certificateData.setKeyLabelType(
223+
KeyLabelTools.KeyLabelType.ID_CARD_DIGI_ID.getName()
224+
);
222225
} else if (dName.contains(ID_CARD)) {
223226
keyLabel += " (id-card)";
227+
certificateData.setKeyLabelType(
228+
KeyLabelTools.KeyLabelType.ID_CARD_DEFAULT.getName()
229+
);
224230
} else if (dName.contains(E_RESIDENT_DIGI_ID)) {
225231
keyLabel += " (e-resident digi-id)";
232+
certificateData.setKeyLabelType(
233+
KeyLabelTools.KeyLabelType.ID_CARD_E_RESIDENT.getName()
234+
);
226235
}
227236
}
228-
return keyLabel;
237+
certificateData.setKeyLabel(keyLabel);
238+
return certificateData;
229239
} else {
230240
log.warn("Unexpected certificate cn values {}", cn);
231-
return cert.getSubjectX500Principal().getName();
241+
certificateData.setKeyLabel(cert.getSubjectX500Principal().getName());
242+
certificateData.setKeyLabelType(
243+
KeyLabelTools.KeyLabelType.ID_CARD_DEFAULT.getName()
244+
);
245+
return certificateData;
232246
}
233247
} catch (InvalidNameException e) {
234-
return cert.getSubjectX500Principal().getName();
248+
certificateData.setKeyLabel(cert.getSubjectX500Principal().getName());
249+
certificateData.setKeyLabelType(
250+
KeyLabelTools.KeyLabelType.ID_CARD_DEFAULT.getName()
251+
);
252+
return certificateData;
235253
}
236254
}
237255

@@ -244,6 +262,7 @@ public static class CertificateData {
244262
private String fingerprint;
245263
@Nullable
246264
private BigInteger serialNumber;
265+
private String keyLabelType;
247266

248267
public CertificateData() {
249268
// utility class
@@ -269,6 +288,10 @@ public BigInteger getSerialNumber() {
269288
return this.serialNumber;
270289
}
271290

291+
public String getKeyLabelType() {
292+
return this.keyLabelType;
293+
}
294+
272295
public void setPublicKey(PublicKey publicKey) {
273296
this.publicKey = publicKey;
274297
}
@@ -288,6 +311,10 @@ public void setFingerprint(String fingerprint) {
288311
public void setSerialNumber(BigInteger serialNumber) {
289312
this.serialNumber = serialNumber;
290313
}
314+
315+
public void setKeyLabelType(String keyLabelType) {
316+
this.keyLabelType = keyLabelType;
317+
}
291318
}
292319

293320
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ null, null, new File("file_name")
228228
@Test
229229
void testEIdLabelParamsCreation() {
230230
KeyLabelParams keyLabelParams = createEIdKeyLabelParams(
231-
"Common,Name,IdentityCode", BigInteger.valueOf(123456)
231+
"Common,Name,IdentityCode",
232+
BigInteger.valueOf(123456),
233+
KeyLabelTools.KeyLabelType.CERT.getName()
232234
);
233235

234236
assertEquals(

0 commit comments

Comments
 (0)