Skip to content
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
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 file=@upload.tgz \
--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</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