Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<properties>
<java.version>17</java.version>
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version>
<webeid.version>3.0.1</webeid.version>
<webeid.version>3.0.2-SNAPSHOT</webeid.version>
<digidoc4j.version>5.3.0</digidoc4j.version>
<jmockit.version>1.44</jmockit.version>
<jib.version>3.4.2</jib.version>
Expand Down
19 changes: 12 additions & 7 deletions src/main/java/eu/webeid/example/security/WebEidAuthentication.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,25 @@

package eu.webeid.example.security;

import eu.webeid.security.certificate.CertificateData;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import eu.webeid.security.certificate.CertificateData;

import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

public class WebEidAuthentication extends PreAuthenticatedAuthenticationToken implements Authentication {

private final String idCode;

public static Authentication fromCertificate(X509Certificate userCertificate, List<GrantedAuthority> authorities) throws CertificateEncodingException {
final String principalName = getPrincipalNameFromCertificate(userCertificate);
final String idCode = Objects.requireNonNull(CertificateData.getSubjectIdCode(userCertificate));
final String idCode = CertificateData.getSubjectIdCode(userCertificate)
.orElseThrow(() -> new CertificateEncodingException("Certificate does not contain subject ID code"));
return new WebEidAuthentication(principalName, idCode, authorities);
}

Expand All @@ -52,12 +54,15 @@ private WebEidAuthentication(String principalName, String idCode, List<GrantedAu
}

private static String getPrincipalNameFromCertificate(X509Certificate userCertificate) throws CertificateEncodingException {
try {
return Objects.requireNonNull(CertificateData.getSubjectGivenName(userCertificate)) + ' ' +
Objects.requireNonNull(CertificateData.getSubjectSurname(userCertificate));
} catch (CertificateEncodingException e) {
final Optional<String> givenName = CertificateData.getSubjectGivenName(userCertificate);
final Optional<String> surname = CertificateData.getSubjectSurname(userCertificate);

if (givenName.isPresent() && surname.isPresent()) {
return givenName.get() + ' ' + surname.get();
} else {
// Organization certificates do not have given name and surname fields.
return Objects.requireNonNull(CertificateData.getSubjectCN(userCertificate));
return CertificateData.getSubjectCN(userCertificate)
.orElseThrow(() -> new CertificateEncodingException("Certificate does not contain subject CN"));
}
}

Expand Down
16 changes: 9 additions & 7 deletions src/main/java/eu/webeid/example/service/SigningService.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,17 @@ private HttpSession currentSession() {
* @return data to be signed
*/
public DigestDTO prepareContainer(CertificateDTO certificateDTO, WebEidAuthentication authentication) throws CertificateException, NoSuchAlgorithmException, IOException {
X509Certificate certificate = certificateDTO.toX509Certificate();
if (!authentication.getIdCode().equals(CertificateData.getSubjectIdCode(certificate))) {
final X509Certificate certificate = certificateDTO.toX509Certificate();
final String signingIdCode = CertificateData.getSubjectIdCode(certificate)
.orElseThrow(() -> new RuntimeException("Certificate does not contain subject ID code"));
if (!signingIdCode.equals(authentication.getIdCode())) {
throw new IllegalArgumentException("Authenticated subject ID code differs from " +
"signing certificate subject ID code");
}

FileDTO fileDTO = FileDTO.getExampleForSigningFromResources();
Container containerToSign = getContainerToSign(fileDTO);
String containerName = generateContainerName(fileDTO.getName());
final FileDTO fileDTO = FileDTO.getExampleForSigningFromResources();
final Container containerToSign = getContainerToSign(fileDTO);
final String containerName = generateContainerName(fileDTO.getName());

currentSession().setAttribute(SESSION_ATTR_CONTAINER, containerToSign);
currentSession().setAttribute(SESSION_ATTR_FILE, fileDTO);
Expand All @@ -113,7 +115,7 @@ public DigestDTO prepareContainer(CertificateDTO certificateDTO, WebEidAuthentic
"' is not supported. Supported algorithms are: " + String.join(", ", certificateDTO.getSupportedHashFunctionNames()));
}

DataToSign dataToSign = SignatureBuilder
final DataToSign dataToSign = SignatureBuilder
.aSignature(containerToSign)
.withSignatureProfile(SignatureProfile.LT) // AIA OCSP is supported for signatures with LT or LTA profile.
.withSigningCertificate(certificate)
Expand All @@ -127,7 +129,7 @@ public DigestDTO prepareContainer(CertificateDTO certificateDTO, WebEidAuthentic
final byte[] digest = signatureDigestAlgorithm.getDssDigestAlgorithm().getMessageDigest()
.digest(dataToSign.getDataToSign());

DigestDTO digestDTO = new DigestDTO();
final DigestDTO digestDTO = new DigestDTO();
digestDTO.setHash(DatatypeConverter.printBase64Binary(digest));
digestDTO.setHashFunction(digestAlgorithmName);

Expand Down