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
32 changes: 7 additions & 25 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>authtoken-validation</artifactId>
<groupId>org.webeid.security</groupId>
<version>1.2.0</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>authtoken-validation</name>
<description>Web eID authentication token validation library for Java</description>
Expand All @@ -15,12 +15,11 @@
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<java.version>1.8</java.version>
<jjwt.version>0.11.2</jjwt.version>
<slf4j.version>1.7.30</slf4j.version>
<slf4j.version>1.7.32</slf4j.version>
<bouncycastle.version>1.69</bouncycastle.version>
<caffeine.version>2.8.5</caffeine.version>
<junit-jupiter.version>5.6.2</junit-jupiter.version>
<assertj.version>3.17.2</assertj.version>
<mockito.version>3.12.4</mockito.version>
<junit-jupiter.version>5.8.1</junit-jupiter.version>
<assertj.version>3.21.0</assertj.version>
<mockito.version>4.0.0</mockito.version>
<jacoco.version>0.8.5</jacoco.version>
<sonar.coverage.jacoco.xmlReportPaths>
${project.basedir}/../jacoco-coverage-report/target/site/jacoco-aggregate/jacoco.xml
Expand Down Expand Up @@ -54,11 +53,6 @@
<version>${jjwt.version}</version>
</dependency>

<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
Expand All @@ -67,7 +61,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
<version>31.0.1-jre</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
Expand All @@ -82,7 +76,7 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.0</version>
<version>4.9.2</version>
</dependency>

<dependency>
Expand All @@ -109,18 +103,6 @@
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>jcache</artifactId>
<version>${caffeine.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 The Web eID Project
* Copyright (c) 2020-2021 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 @@ -20,38 +20,48 @@
* SOFTWARE.
*/

package org.webeid.security.nonce;
package eu.webeid.security.authtoken;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.webeid.security.testutil.AbstractTestWithCache;
@JsonIgnoreProperties(ignoreUnknown = true)
public class WebEidAuthToken {

import static org.assertj.core.api.Assertions.assertThat;
private String unverifiedCertificate;
private String signature;
private String algorithm;
private String format;

class NonceGeneratorTest extends AbstractTestWithCache {
public String getUnverifiedCertificate() {
return unverifiedCertificate;
}

private NonceGenerator nonceGenerator;
public void setUnverifiedCertificate(String unverifiedCertificate) {
this.unverifiedCertificate = unverifiedCertificate;
}

@Override
@BeforeEach
protected void setup() {
super.setup();
nonceGenerator = new NonceGeneratorBuilder()
.withNonceCache(cache)
.build();
public String getSignature() {
return signature;
}

@Test
void validateNonceGeneration() {
final String nonce1 = nonceGenerator.generateAndStoreNonce();
final String nonce2 = nonceGenerator.generateAndStoreNonce();
public void setSignature(String signature) {
this.signature = signature;
}

public String getAlgorithm() {
return algorithm;
}

public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}

public String getFormat() {
return format;
}

assertThat(nonce1)
.hasSize(44) // Base64-encoded 32 bytes
.isNotEqualTo(nonce2);
// It might be possible to add an entropy test by compressing the nonce bytes
// and verifying that the result is longer than for non-random strings.
public void setFormat(String format) {
this.format = format;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 The Web eID Project
* Copyright (c) 2020-2021 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 @@ -20,7 +20,7 @@
* SOFTWARE.
*/

package org.webeid.security.certificate;
package eu.webeid.security.certificate;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.RDN;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 The Web eID Project
* Copyright (c) 2020-2021 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 @@ -20,7 +20,9 @@
* SOFTWARE.
*/

package org.webeid.security.certificate;
package eu.webeid.security.certificate;

import eu.webeid.security.exceptions.CertificateDecodingException;

import java.io.ByteArrayInputStream;
import java.io.IOException;
Expand All @@ -29,8 +31,10 @@
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Objects;

import static eu.webeid.security.util.Base64Decoder.decodeBase64;

public final class CertificateLoader {

Expand All @@ -48,11 +52,14 @@ public static X509Certificate[] loadCertificatesFromResources(String... resource
return caCertificates.toArray(new X509Certificate[0]);
}

public static X509Certificate loadCertificateFromBase64String(String certificate) throws CertificateException, IOException {
try (final InputStream targetStream = new ByteArrayInputStream(Base64.getDecoder().decode(certificate))) {
public static X509Certificate decodeCertificateFromBase64(String certificateInBase64) throws CertificateDecodingException {
Objects.requireNonNull(certificateInBase64, "certificateInBase64");
try (final InputStream targetStream = new ByteArrayInputStream(decodeBase64(certificateInBase64))) {
return (X509Certificate) CertificateFactory
.getInstance("X509")
.generateCertificate(targetStream);
} catch (IOException | CertificateException | IllegalArgumentException e) {
throw new CertificateDecodingException(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
* SOFTWARE.
*/

package org.webeid.security.certificate;
package eu.webeid.security.certificate;

import org.webeid.security.exceptions.CertificateNotTrustedException;
import org.webeid.security.exceptions.JceException;
import org.webeid.security.exceptions.CertificateExpiredException;
import org.webeid.security.exceptions.CertificateNotYetValidException;
import eu.webeid.security.exceptions.CertificateExpiredException;
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 @@ -65,13 +65,15 @@ public static void trustedCACertificatesAreValidOnDate(Set<TrustAnchor> trustedC

public static X509Certificate validateIsSignedByTrustedCA(X509Certificate certificate,
Set<TrustAnchor> trustedCACertificateAnchors,
CertStore trustedCACertificateCertStore) throws CertificateNotTrustedException, JceException {
CertStore trustedCACertificateCertStore,
Date date) throws CertificateNotTrustedException, JceException {
final X509CertSelector selector = new X509CertSelector();
selector.setCertificate(certificate);

try {
final PKIXBuilderParameters pkixBuilderParameters = new PKIXBuilderParameters(trustedCACertificateAnchors, selector);
pkixBuilderParameters.setRevocationEnabled(false);
pkixBuilderParameters.setDate(date);
pkixBuilderParameters.addCertStore(trustedCACertificateCertStore);

// See the comment in buildCertStoreFromCertificates() below why we use the default JCE provider.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 The Web eID Project
* Copyright (c) 2021 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 @@ -20,21 +20,26 @@
* SOFTWARE.
*/

package org.webeid.security.exceptions;
package eu.webeid.security.challenge;

/**
* Thrown when the origin URL from the token {@code aud} field does not match the configured origin,
* i.e. the URL that the site is running on.
*/
public class OriginMismatchException extends TokenValidationException {
import java.time.ZonedDateTime;

public class ChallengeNonce {

private static final String MESSAGE = "Origin from the token does not match the configured origin";
private final String base64EncodedNonce;
private final ZonedDateTime expirationTime;

public OriginMismatchException() {
super(MESSAGE);
public ChallengeNonce(String base64EncodedNonce, ZonedDateTime expirationTime) {
this.base64EncodedNonce = base64EncodedNonce;
this.expirationTime = expirationTime;
}

public OriginMismatchException(Throwable cause) {
super(MESSAGE, cause);
public ZonedDateTime getExpirationTime() {
return expirationTime;
}

public String getBase64EncodedNonce() {
return base64EncodedNonce;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 The Web eID Project
* Copyright (c) 2020-2021 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 @@ -20,20 +20,20 @@
* SOFTWARE.
*/

package org.webeid.security.nonce;
package eu.webeid.security.challenge;

/**
* Generates cryptographic nonces.
* Generates challenge nonces, cryptographically strong random bytestrings that must be used only once.
*/
public interface NonceGenerator {
public interface ChallengeNonceGenerator {

int NONCE_LENGTH = 32;

/**
* Generates a cryptographic nonce, a large random number that can be used only once,
* and stores it in cache.
* and stores it in a {@link ChallengeNonceStore}.
*
* @return Base64-encoded nonce
* @return a {@link ChallengeNonce} that contains the Base64-encoded nonce and its expiry time
*/
String generateAndStoreNonce();
ChallengeNonce generateAndStoreNonce();
}
Loading