Skip to content

Commit be7f697

Browse files
authored
Merge pull request #150 from SK-EID/legacy-signature-algorithms
Restore legacy signature algorithms for signing
2 parents 6447d43 + 5a8f496 commit be7f697

48 files changed

Lines changed: 1478 additions & 403 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,34 @@
33
All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
55

6-
## [3.1-?] - TBD
6+
## [3.2] - TBD
7+
8+
### Changes
9+
10+
- Added legacy signing algorithms (`SHA256_WITH_RSA_ENCRYPTION`, `SHA384_WITH_RSA_ENCRYPTION`, `SHA512_WITH_RSA_ENCRYPTION`) for RSASSA-PKCS#1 v1.5.
11+
- Compatible with DigiDoc4j library which does not support RSASSA-PSS.
12+
- Use `SigningSignatureAlgorithm` enum and `withSignatureAlgorithm()` on signature session builders.
13+
- Use `SigningSignatureAlgorithm.getHashAlgorithmForLegacy()` when creating `SignableData` for legacy algorithms.
14+
- Legacy algorithms do not use `signatureAlgorithmParameters` in requests or responses.
15+
- Split `SignatureAlgorithm` into `AuthenticationSignatureAlgorithm` (authentication) and `SigningSignatureAlgorithm` (signing).
16+
- Only allowed `AuthenticationSignatureAlgorithm` is `RSASSA_PSS`; default `SigningSignatureAlgorithm` is `RSASSA_PSS`.
17+
- Added `SignatureFactory` interface for creating `java.security.Signature` instance for verifying signature and added its implementations:
18+
- `RsaSsaPssSignatureFactory`
19+
- `RsaSsaPkcs1SignatureFactory`
20+
- Changed `SignatureValueValidator.validate` last parameter from `RsaSsaPssParameters` to `SignatureFactory`:
21+
- The following classes are moved from `ee.sk.smartid` to `ee.sk.smartid.signature`:
22+
- `AuthenticationSignatureAlgorithm`
23+
- `DigestInput`
24+
- `MaskGenAlgorithm`
25+
- `RsaSsaPssParameters`
26+
- `SignableData`
27+
- `SignableHash`
28+
- `SignatureValueValidator`
29+
- `SignatureValueValidatorImpl`
30+
- `SigningSignatureAlgorithm`
31+
- `TrailerField`
32+
33+
## [3.1] - 2025-10-15
734

835
### Structural changes
936

MIGRATION_GUIDE.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,43 @@ Library v3.1 supports only Smart-ID v3 API.
44
All the previous v2 related code has been removed and all the code necessary for Smart-ID API v3 is under package smartid.
55
Some classes could also be used in v3 and for those classes the package did not change.
66

7+
# Migrating from library v3.1 to v3.2
8+
9+
For signing flows are restored legacy RSASSA-PKCS#1 v1.5 algorithms (`SHA256_WITH_RSA_ENCRYPTION`, `SHA384_WITH_RSA_ENCRYPTION`, `SHA512_WITH_RSA_ENCRYPTION`) which are compatible with DigiDoc4j's signing support.
10+
For that reason:
11+
- `SignatureAlgorithm` class is split into `AuthenticationSignatureAlgorithm` and `SigningSignatureAlgorithm`.
12+
- `SignatureValueValidator.validate` last parameter changed from `RsaSsaPssParameters` to `SignatureFactory`
13+
14+
Changes needed in authentication flows:
15+
- change `SignatureAlgorithm` to `AuthenticationSignatureAlgorithm`
16+
- change `SignatureValueValidator.validate` last parameter from `RsaSsaPssParameters` to `new RsaSsaPssSignatureFactory(RsaSsaPssParameters)`
17+
18+
Changes needed in signing flows:
19+
- change `SignatureAlgorithm` to `SigningSignatureAlgorithm`
20+
- suggestion for `SignatureValueValidator.validate` last parameter changes:
21+
- when using only signature algorithm RSASSA_PSS then use `new RsaSsaPssSignatureFactory(RsaSsaPssParameters)`
22+
- when using only legacy signature algorithms (`SHA256_WITH_RSA_ENCRYPTION`, `SHA384_WITH_RSA_ENCRYPTION`, `SHA512_WITH_RSA_ENCRYPTION`) then use `new RsaSsaPkcs1SignatureFactory(SigningSignatureAlgorithm)`
23+
- when both RSASSA_PSS and legacy RSA algorithms are used then possible solution is:
24+
```java
25+
SignatureFactory signatureFactory = signatureResponse.getSignatureAlgorithm().isLegacyRsa()
26+
? new RsaSsaPkcs1SignatureFactory(signatureResponse.getSignatureAlgorithm())
27+
: new RsaSsaPssSignatureFactory(signatureResponse.getRsaSsaPssParameters());
28+
```
29+
30+
The following classes are moved from `ee.sk.smartid` to `ee.sk.smartid.signature` so when used then imports need to be adjusted:
31+
- `AuthenticationSignatureAlgorithm`
32+
- `DigestInput`
33+
- `MaskGenAlgorithm`
34+
- `RsaSsaPssParameters`
35+
- `SignableData`
36+
- `SignableHash`
37+
- `SignatureValueValidator`
38+
- `SignatureValueValidatorImpl`
39+
- `SigningSignatureAlgorithm`
40+
- `TrailerField`
41+
42+
For legacy RSA with DigiDoc4j there is new chapter in README.md: [Legacy algorithms for signing with DigiDoc4j](./README.md#legacy-algorithms-for-signing-with-digidoc4j)
43+
744
# Migrating from Smart-ID v2 to Smart-ID v3 API
845

946
## Migrating authentication

README.md

Lines changed: 122 additions & 20 deletions
Large diffs are not rendered by default.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<groupId>ee.sk.smartid</groupId>
88
<artifactId>smart-id-java-client</artifactId>
99
<packaging>jar</packaging>
10-
<version>3.0-SNAPSHOT</version>
10+
<version>3.2-SNAPSHOT</version>
1111

1212
<name>Smart-ID Java client</name>
1313
<description>Smart-ID Java client is a Java library that can be used for easy integration of the Smart-ID solution to information systems or e-services</description>

src/main/java/ee/sk/smartid/AuthenticationResponse.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* #%L
55
* Smart ID sample Java client
66
* %%
7-
* Copyright (C) 2018 - 2025 SK ID Solutions AS
7+
* Copyright (C) 2018 - 2026 SK ID Solutions AS
88
* %%
99
* Permission is hereby granted, free of charge, to any person obtaining a copy
1010
* of this software and associated documentation files (the "Software"), to deal
@@ -31,6 +31,7 @@
3131
import java.util.Base64;
3232

3333
import ee.sk.smartid.exception.UnprocessableSmartIdResponseException;
34+
import ee.sk.smartid.signature.RsaSsaPssParameters;
3435

3536
/**
3637
* The authentication response after a successful authentication session status response was received.

src/main/java/ee/sk/smartid/AuthenticationResponseMapperImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
import ee.sk.smartid.rest.dao.SessionResult;
4040
import ee.sk.smartid.rest.dao.SessionSignature;
4141
import ee.sk.smartid.rest.dao.SessionStatus;
42+
import ee.sk.smartid.signature.AuthenticationSignatureAlgorithm;
43+
import ee.sk.smartid.signature.MaskGenAlgorithm;
44+
import ee.sk.smartid.signature.RsaSsaPssParameters;
45+
import ee.sk.smartid.signature.TrailerField;
4246
import ee.sk.smartid.util.StringUtil;
4347

4448
/**
@@ -177,7 +181,7 @@ private static void validateSignature(SessionSignature sessionSignature) {
177181
if (StringUtil.isEmpty(sessionSignature.getSignatureAlgorithm())) {
178182
throw new UnprocessableSmartIdResponseException("Authentication session status field 'signature.signatureAlgorithm' is empty");
179183
}
180-
if (!SignatureAlgorithm.isSupported(sessionSignature.getSignatureAlgorithm())) {
184+
if (!AuthenticationSignatureAlgorithm.isSupported(sessionSignature.getSignatureAlgorithm())) {
181185
logger.error("Authentication session status field 'signature.signatureAlgorithm' has invalid value: {}", sessionSignature.getSignatureAlgorithm());
182186
throw new UnprocessableSmartIdResponseException("Authentication session status field 'signature.signatureAlgorithm' has unsupported value");
183187
}

src/main/java/ee/sk/smartid/DeviceLinkAuthenticationResponseValidator.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* #%L
55
* Smart ID sample Java client
66
* %%
7-
* Copyright (C) 2018 - 2025 SK ID Solutions AS
7+
* Copyright (C) 2018 - 2026 SK ID Solutions AS
88
* %%
99
* Permission is hereby granted, free of charge, to any person obtaining a copy
1010
* of this software and associated documentation files (the "Software"), to deal
@@ -37,6 +37,9 @@
3737
import ee.sk.smartid.exception.useraccount.CertificateLevelMismatchException;
3838
import ee.sk.smartid.rest.dao.DeviceLinkAuthenticationSessionRequest;
3939
import ee.sk.smartid.rest.dao.SessionStatus;
40+
import ee.sk.smartid.signature.RsaSsaPssSignatureFactory;
41+
import ee.sk.smartid.signature.SignatureValueValidator;
42+
import ee.sk.smartid.signature.SignatureValueValidatorImpl;
4043
import ee.sk.smartid.util.InteractionUtil;
4144
import ee.sk.smartid.util.StringUtil;
4245

@@ -159,7 +162,7 @@ private void validateSignature(AuthenticationResponse authenticationResponse,
159162
signatureValueValidator.validate(authenticationResponse.getSignatureValue(),
160163
payload,
161164
authenticationResponse.getCertificate(),
162-
authenticationResponse.getRsaSsaPssSignatureParameters());
165+
new RsaSsaPssSignatureFactory(authenticationResponse.getRsaSsaPssSignatureParameters()));
163166
}
164167

165168
private byte[] constructPayload(AuthenticationResponse authenticationResponse,

src/main/java/ee/sk/smartid/DeviceLinkAuthenticationSessionRequestBuilder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* #%L
55
* Smart ID sample Java client
66
* %%
7-
* Copyright (C) 2018 - 2025 SK ID Solutions AS
7+
* Copyright (C) 2018 - 2026 SK ID Solutions AS
88
* %%
99
* Permission is hereby granted, free of charge, to any person obtaining a copy
1010
* of this software and associated documentation files (the "Software"), to deal
@@ -42,6 +42,7 @@
4242
import ee.sk.smartid.rest.dao.RequestProperties;
4343
import ee.sk.smartid.rest.dao.SemanticsIdentifier;
4444
import ee.sk.smartid.rest.dao.SignatureAlgorithmParameters;
45+
import ee.sk.smartid.signature.AuthenticationSignatureAlgorithm;
4546
import ee.sk.smartid.util.InteractionUtil;
4647
import ee.sk.smartid.util.SetUtil;
4748
import ee.sk.smartid.util.StringUtil;
@@ -59,7 +60,7 @@ public class DeviceLinkAuthenticationSessionRequestBuilder {
5960
private String relyingPartyName;
6061
private AuthenticationCertificateLevel certificateLevel = AuthenticationCertificateLevel.QUALIFIED;
6162
private String rpChallenge;
62-
private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RSASSA_PSS;
63+
private AuthenticationSignatureAlgorithm signatureAlgorithm = AuthenticationSignatureAlgorithm.RSASSA_PSS;
6364
private HashAlgorithm hashAlgorithm = HashAlgorithm.SHA3_512;
6465
private List<DeviceLinkInteraction> interactions;
6566
private Boolean shareMdClientIpAddress;
@@ -136,7 +137,7 @@ public DeviceLinkAuthenticationSessionRequestBuilder withRpChallenge(String rpCh
136137
* @param signatureAlgorithm the signature algorithm
137138
* @return this builder
138139
*/
139-
public DeviceLinkAuthenticationSessionRequestBuilder withSignatureAlgorithm(SignatureAlgorithm signatureAlgorithm) {
140+
public DeviceLinkAuthenticationSessionRequestBuilder withSignatureAlgorithm(AuthenticationSignatureAlgorithm signatureAlgorithm) {
140141
this.signatureAlgorithm = signatureAlgorithm;
141142
return this;
142143
}

src/main/java/ee/sk/smartid/DeviceLinkSignatureSessionRequestBuilder.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* #%L
55
* Smart ID sample Java client
66
* %%
7-
* Copyright (C) 2018 - 2025 SK ID Solutions AS
7+
* Copyright (C) 2018 - 2026 SK ID Solutions AS
88
* %%
99
* Permission is hereby granted, free of charge, to any person obtaining a copy
1010
* of this software and associated documentation files (the "Software"), to deal
@@ -41,6 +41,10 @@
4141
import ee.sk.smartid.rest.dao.SemanticsIdentifier;
4242
import ee.sk.smartid.rest.dao.SignatureAlgorithmParameters;
4343
import ee.sk.smartid.rest.dao.DeviceLinkSignatureSessionRequest;
44+
import ee.sk.smartid.signature.DigestInput;
45+
import ee.sk.smartid.signature.SignableData;
46+
import ee.sk.smartid.signature.SignableHash;
47+
import ee.sk.smartid.signature.SigningSignatureAlgorithm;
4448
import ee.sk.smartid.util.InteractionUtil;
4549
import ee.sk.smartid.util.SetUtil;
4650
import ee.sk.smartid.util.StringUtil;
@@ -63,7 +67,7 @@ public class DeviceLinkSignatureSessionRequestBuilder {
6367
private Set<String> capabilities;
6468
private List<DeviceLinkInteraction> interactions;
6569
private Boolean shareMdClientIpAddress;
66-
private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RSASSA_PSS;
70+
private SigningSignatureAlgorithm signatureAlgorithm = SigningSignatureAlgorithm.RSASSA_PSS;
6771
private String initialCallbackUrl;
6872
private DigestInput digestInput;
6973

@@ -183,7 +187,7 @@ public DeviceLinkSignatureSessionRequestBuilder withShareMdClientIpAddress(boole
183187
* @param signatureAlgorithm the signature algorithm
184188
* @return this builder
185189
*/
186-
public DeviceLinkSignatureSessionRequestBuilder withSignatureAlgorithm(SignatureAlgorithm signatureAlgorithm) {
190+
public DeviceLinkSignatureSessionRequestBuilder withSignatureAlgorithm(SigningSignatureAlgorithm signatureAlgorithm) {
187191
this.signatureAlgorithm = signatureAlgorithm;
188192
return this;
189193
}
@@ -287,9 +291,12 @@ private DeviceLinkSessionResponse initSignatureSession(DeviceLinkSignatureSessio
287291
}
288292

289293
private DeviceLinkSignatureSessionRequest createSignatureSessionRequest() {
294+
SignatureAlgorithmParameters algorithmParams = signatureAlgorithm.isLegacyRsa()
295+
? null
296+
: new SignatureAlgorithmParameters(digestInput.hashAlgorithm().getAlgorithmName());
290297
var signatureProtocolParameters = new RawDigestSignatureProtocolParameters(digestInput.getDigestInBase64(),
291298
signatureAlgorithm.getAlgorithmName(),
292-
new SignatureAlgorithmParameters(digestInput.hashAlgorithm().getAlgorithmName()));
299+
algorithmParams);
293300
return new DeviceLinkSignatureSessionRequest(relyingPartyUUID,
294301
relyingPartyName,
295302
certificateLevel != null ? certificateLevel.name() : null,

src/main/java/ee/sk/smartid/LinkedNotificationSignatureSessionRequestBuilder.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* #%L
55
* Smart ID sample Java client
66
* %%
7-
* Copyright (C) 2018 - 2025 SK ID Solutions AS
7+
* Copyright (C) 2018 - 2026 SK ID Solutions AS
88
* %%
99
* Permission is hereby granted, free of charge, to any person obtaining a copy
1010
* of this software and associated documentation files (the "Software"), to deal
@@ -39,6 +39,10 @@
3939
import ee.sk.smartid.rest.dao.RawDigestSignatureProtocolParameters;
4040
import ee.sk.smartid.rest.dao.RequestProperties;
4141
import ee.sk.smartid.rest.dao.SignatureAlgorithmParameters;
42+
import ee.sk.smartid.signature.DigestInput;
43+
import ee.sk.smartid.signature.SignableData;
44+
import ee.sk.smartid.signature.SignableHash;
45+
import ee.sk.smartid.signature.SigningSignatureAlgorithm;
4246
import ee.sk.smartid.util.SetUtil;
4347
import ee.sk.smartid.util.InteractionUtil;
4448
import ee.sk.smartid.util.StringUtil;
@@ -54,7 +58,7 @@ public class LinkedNotificationSignatureSessionRequestBuilder {
5458
private String relyingPartyName;
5559
private String documentNumber;
5660
private DigestInput digestInput;
57-
private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RSASSA_PSS;
61+
private SigningSignatureAlgorithm signatureAlgorithm = SigningSignatureAlgorithm.RSASSA_PSS;
5862
private String linkedSessionID;
5963
private List<DeviceLinkInteraction> interactions;
6064
private CertificateLevel certificateLevel;
@@ -151,7 +155,7 @@ public LinkedNotificationSignatureSessionRequestBuilder withSignableHash(Signabl
151155
* @param signatureAlgorithm The signature algorithm
152156
* @return this builder
153157
*/
154-
public LinkedNotificationSignatureSessionRequestBuilder withSignatureAlgorithm(SignatureAlgorithm signatureAlgorithm) {
158+
public LinkedNotificationSignatureSessionRequestBuilder withSignatureAlgorithm(SigningSignatureAlgorithm signatureAlgorithm) {
155159
this.signatureAlgorithm = signatureAlgorithm;
156160
return this;
157161
}
@@ -257,9 +261,12 @@ private void validateRequestParameters() {
257261
}
258262

259263
private LinkedSignatureSessionRequest createSessionRequest() {
264+
SignatureAlgorithmParameters algorithmParams = signatureAlgorithm.isLegacyRsa()
265+
? null
266+
: new SignatureAlgorithmParameters(digestInput.hashAlgorithm().getAlgorithmName());
260267
var rawDigestParams = new RawDigestSignatureProtocolParameters(digestInput.getDigestInBase64(),
261268
signatureAlgorithm.getAlgorithmName(),
262-
new SignatureAlgorithmParameters(digestInput.hashAlgorithm().getAlgorithmName()));
269+
algorithmParams);
263270
return new LinkedSignatureSessionRequest(relyingPartyUUID,
264271
relyingPartyName,
265272
certificateLevel != null ? certificateLevel.name() : null,

0 commit comments

Comments
 (0)