Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
8 changes: 4 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: java
queries: +security-and-quality

- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
8 changes: 4 additions & 4 deletions .github/workflows/coverity-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ jobs:
PROJECTNAME: 'web-eid/web-eid-authtoken-validation-java'

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: zulu
java-version: 8

- name: Cache Maven packages
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-v8-${{ hashFiles('**/pom.xml') }}
Expand All @@ -50,4 +50,4 @@ jobs:
--form [email protected] \
--form version=master \
--form description="Github Actions CI build" \
https://scan.coverity.com/builds?project=$PROJECTNAME
https://scan.coverity.com/builds?project=$PROJECTNAME
6 changes: 3 additions & 3 deletions .github/workflows/maven-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: zulu
java-version: 8

- name: Cache Maven packages
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-v8-${{ hashFiles('**/pom.xml') }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/maven-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: zulu
java-version: 8

- name: Cache Maven packages
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-v8-${{ hashFiles('**/pom.xml') }}
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/sonarcloud-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Set up JDK 11
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: zulu
java-version: 11
- name: Cache SonarCloud packages
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Cache Maven packages
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.m2
key: ${{ runner.os }}-m2-v11-${{ hashFiles('**/pom.xml') }}
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020-2023 Estonian Information System Authority
Copyright (c) 2020-2025 Estonian Information System Authority

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
34 changes: 17 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>authtoken-validation</artifactId>
<groupId>org.webeid.security</groupId>
<version>2.1.2</version>
<groupId>eu.webeid.security</groupId>
<version>2.2.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>authtoken-validation</name>
<description>Web eID authentication token validation library for Java</description>

<properties>
<maven.version>3.3.9</maven.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<maven-surefire-plugin.version>3.5.4</maven-surefire-plugin.version>
<java.version>1.8</java.version>
<jjwt.version>0.11.5</jjwt.version>
<jackson.version>2.13.4.2</jackson.version>
<slf4j.version>1.7.36</slf4j.version>
<bouncycastle.version>1.70</bouncycastle.version>
<okhttp.version>4.10.0</okhttp.version>
<junit-jupiter.version>5.8.2</junit-jupiter.version>
<assertj.version>3.23.1</assertj.version>
<mockito.version>4.6.1</mockito.version>
<jacoco.version>0.8.5</jacoco.version>
<jjwt.version>0.13.0</jjwt.version>
<jackson.version>2.18.5</jackson.version>
<slf4j.version>2.0.17</slf4j.version>
<bouncycastle.version>1.82</bouncycastle.version>
<okhttp.version>5.3.0</okhttp.version>
<junit-jupiter.version>5.12.0</junit-jupiter.version>
<assertj.version>3.27.3</assertj.version>
<mockito.version>4.11.0</mockito.version>
<jacoco.version>0.8.12</jacoco.version>
<sonar.coverage.jacoco.xmlReportPaths>
${project.basedir}/../jacoco-coverage-report/target/site/jacoco-aggregate/jacoco.xml
</sonar.coverage.jacoco.xmlReportPaths>
Expand Down Expand Up @@ -56,17 +56,17 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<artifactId>bcprov-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<artifactId>bcpkix-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<artifactId>okhttp-jvm</artifactId>
<version>${okhttp.version}</version>
</dependency>

Expand All @@ -84,7 +84,7 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<artifactId>mockito-inline</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
Expand Down Expand Up @@ -129,7 +129,7 @@

<!-- For publishing the library to GitHub Packages/GitLab Package Repository -->
<distributionManagement>
<!-- Github Packages does not currently support public access, so disabled until it does.
<!-- GitHub Packages does not currently support public access, so disabled until it does.
See https://github.community/t/download-from-github-package-registry-without-authentication/14407
<repository>
<id>github</id>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
23 changes: 12 additions & 11 deletions src/main/java/eu/webeid/security/certificate/CertificateData.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -32,43 +32,44 @@
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;

public final class CertificateData {

public static String getSubjectCN(X509Certificate certificate) throws CertificateEncodingException {
public static Optional<String> getSubjectCN(X509Certificate certificate) throws CertificateEncodingException {
return getSubjectField(certificate, BCStyle.CN);
}

public static String getSubjectSurname(X509Certificate certificate) throws CertificateEncodingException {
public static Optional<String> getSubjectSurname(X509Certificate certificate) throws CertificateEncodingException {
return getSubjectField(certificate, BCStyle.SURNAME);
}

public static String getSubjectGivenName(X509Certificate certificate) throws CertificateEncodingException {
public static Optional<String> getSubjectGivenName(X509Certificate certificate) throws CertificateEncodingException {
return getSubjectField(certificate, BCStyle.GIVENNAME);
}

public static String getSubjectIdCode(X509Certificate certificate) throws CertificateEncodingException {
public static Optional<String> getSubjectIdCode(X509Certificate certificate) throws CertificateEncodingException {
return getSubjectField(certificate, BCStyle.SERIALNUMBER);
}

public static String getSubjectCountryCode(X509Certificate certificate) throws CertificateEncodingException {
public static Optional<String> getSubjectCountryCode(X509Certificate certificate) throws CertificateEncodingException {
return getSubjectField(certificate, BCStyle.C);
}

private static String getSubjectField(X509Certificate certificate, ASN1ObjectIdentifier fieldId) throws CertificateEncodingException {
private static Optional<String> getSubjectField(X509Certificate certificate, ASN1ObjectIdentifier fieldId) throws CertificateEncodingException {
return getField(new JcaX509CertificateHolder(certificate).getSubject(), fieldId);
}

private static String getField(X500Name x500Name, ASN1ObjectIdentifier fieldId) throws CertificateEncodingException {
private static Optional<String> getField(X500Name x500Name, ASN1ObjectIdentifier fieldId) {
// Example value: [C=EE, CN=JÕEORG\,JAAK-KRISTJAN\,38001085718, 2.5.4.4=#0c074ac395454f5247, 2.5.4.42=#0c0d4a41414b2d4b524953544a414e, 2.5.4.5=#1311504e4f45452d3338303031303835373138]
final RDN[] rdns = x500Name.getRDNs(fieldId);
if (rdns.length == 0 || rdns[0].getFirst() == null) {
throw new CertificateEncodingException("X500 name RDNs empty or first element is null");
return Optional.empty();
}
return Arrays.stream(rdns)
return Optional.of(Arrays.stream(rdns)
.map(rdn -> IETFUtils.valueToString(rdn.getFirst().getValue()))
.collect(Collectors.joining(", "));
.collect(Collectors.joining(", ")));
}

private CertificateData() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -23,9 +23,9 @@
package eu.webeid.security.certificate;

import eu.webeid.security.exceptions.CertificateExpiredException;
import eu.webeid.security.exceptions.CertificateNotTrustedException;
import eu.webeid.security.exceptions.CertificateNotYetValidException;
import eu.webeid.security.exceptions.JceException;
import eu.webeid.security.exceptions.CertificateNotTrustedException;

import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
Expand Down Expand Up @@ -57,31 +57,32 @@ public static void certificateIsValidOnDate(X509Certificate cert, Date date, Str
}
}

public static void trustedCACertificatesAreValidOnDate(Set<TrustAnchor> trustedCACertificateAnchors, Date date) throws CertificateNotYetValidException, CertificateExpiredException {
for (TrustAnchor cert : trustedCACertificateAnchors) {
certificateIsValidOnDate(cert.getTrustedCert(), date, "Trusted CA");
}
}

public static X509Certificate validateIsSignedByTrustedCA(X509Certificate certificate,
Set<TrustAnchor> trustedCACertificateAnchors,
CertStore trustedCACertificateCertStore,
Date date) throws CertificateNotTrustedException, JceException {
Date now) throws CertificateNotTrustedException, JceException, CertificateNotYetValidException, CertificateExpiredException {
certificateIsValidOnDate(certificate, now, "User");

final X509CertSelector selector = new X509CertSelector();
selector.setCertificate(certificate);

try {
final PKIXBuilderParameters pkixBuilderParameters = new PKIXBuilderParameters(trustedCACertificateAnchors, selector);
// Certificate revocation check is intentionally disabled as we do the OCSP check with SubjectCertificateNotRevokedValidator ourselves.
pkixBuilderParameters.setRevocationEnabled(false);
pkixBuilderParameters.setDate(date);
pkixBuilderParameters.setDate(now);
pkixBuilderParameters.addCertStore(trustedCACertificateCertStore);

// See the comment in buildCertStoreFromCertificates() below why we use the default JCE provider.
final CertPathBuilder certPathBuilder = CertPathBuilder.getInstance(CertPathBuilder.getDefaultType());
final PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) certPathBuilder.build(pkixBuilderParameters);

return result.getTrustAnchor().getTrustedCert();
final X509Certificate trustedCACert = result.getTrustAnchor().getTrustedCert();

// Verify that the trusted CA cert is presently valid before returning the result.
certificateIsValidOnDate(trustedCACert, now, "Trusted CA");

return trustedCACert;

} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
throw new JceException(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023 Estonian Information System Authority
* Copyright (c) 2020-2025 Estonian Information System Authority
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading