Skip to content

Commit

Permalink
v7.0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Gematik-Entwicklung authored and RStaeber committed Nov 21, 2024
1 parent 502a285 commit 999f66a
Show file tree
Hide file tree
Showing 25 changed files with 288 additions and 107 deletions.
7 changes: 7 additions & 0 deletions ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Release 7.0.6

- fix expiry date validation of entity statement (fixes caching issue)
- adapt server and testsuite to set/expect amr as array
- add test identities
- update dependencies

# Release 7.0.4

- add documentation for key rotation
Expand Down
2 changes: 1 addition & 1 deletion gsi-coverage-report/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>de.gematik.idp</groupId>
<artifactId>gemSekIdp-global</artifactId>
<version>7.0.4</version>
<version>7.0.6</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
6 changes: 3 additions & 3 deletions gsi-fedmaster/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
<parent>
<groupId>de.gematik.idp</groupId>
<artifactId>gemSekIdp-global</artifactId>
<version>7.0.4</version>
<version>7.0.6</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>gsi-fedmaster</artifactId>
<version>7.0.4</version>
<version>7.0.6</version>
<packaging>jar</packaging>

<name>gsi-fedmaster</name>
Expand Down Expand Up @@ -95,7 +95,7 @@
<dependency>
<groupId>org.jmdns</groupId>
<artifactId>jmdns</artifactId>
<version>3.5.12</version>
<version>3.6.0</version>
</dependency>
</dependencies>

Expand Down
6 changes: 3 additions & 3 deletions gsi-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
<parent>
<groupId>de.gematik.idp</groupId>
<artifactId>gemSekIdp-global</artifactId>
<version>7.0.4</version>
<version>7.0.6</version>
<relativePath>../pom.xml</relativePath>
</parent>

<artifactId>gsi-server</artifactId>
<version>7.0.4</version>
<version>7.0.6</version>
<packaging>jar</packaging>

<name>gsi-server</name>
Expand Down Expand Up @@ -137,7 +137,7 @@
<dependency>
<groupId>org.jmdns</groupId>
<artifactId>jmdns</artifactId>
<version>3.5.12</version>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import static de.gematik.idp.IdpConstants.FED_AUTH_ENDPOINT;
import static de.gematik.idp.IdpConstants.TOKEN_ENDPOINT;
import static de.gematik.idp.data.Oauth2ErrorCode.INVALID_REQUEST;
import static de.gematik.idp.gsi.server.data.GsiConstants.*;
import static de.gematik.idp.gsi.server.data.GsiConstants.FEDIDP_PAR_AUTH_ENDPOINT;
import static de.gematik.idp.gsi.server.data.GsiConstants.FED_SIGNED_JWKS_ENDPOINT;
import static de.gematik.idp.gsi.server.data.GsiConstants.TLS_CLIENT_CERT_HEADER_NAME;
import static de.gematik.idp.gsi.server.util.ClaimHelper.getClaimsForScopeSet;

import com.fasterxml.jackson.databind.ObjectMapper;
Expand All @@ -32,7 +34,11 @@
import de.gematik.idp.data.ParResponse;
import de.gematik.idp.data.TokenResponse;
import de.gematik.idp.gsi.server.configuration.GsiConfiguration;
import de.gematik.idp.gsi.server.data.*;
import de.gematik.idp.gsi.server.data.ClaimsInfo;
import de.gematik.idp.gsi.server.data.ClaimsResponse;
import de.gematik.idp.gsi.server.data.FedIdpAuthSession;
import de.gematik.idp.gsi.server.data.QRCodeGenerator;
import de.gematik.idp.gsi.server.data.RpToken;
import de.gematik.idp.gsi.server.exceptions.GsiException;
import de.gematik.idp.gsi.server.services.AuthenticationService;
import de.gematik.idp.gsi.server.services.EntityStatementBuilder;
Expand All @@ -42,6 +48,7 @@
import de.gematik.idp.gsi.server.services.ServerUrlService;
import de.gematik.idp.gsi.server.services.TokenRepositoryRp;
import de.gematik.idp.gsi.server.token.IdTokenBuilder;
import de.gematik.idp.token.JsonWebToken;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Pattern;
Expand All @@ -50,8 +57,14 @@
import java.nio.charset.StandardCharsets;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -169,7 +182,7 @@ public ParResponse postPar(
regexp =
"urn:telematik:auth:eGK|urn:telematik:auth:eID|urn:telematik:auth:sso|urn:telematik:auth:mEW|urn:telematik:auth:guest:eGK|urn:telematik:auth:other")
final String amr,
@RequestParam(name = "claims", defaultValue = "") ClaimsInfo claimsInfo,
@RequestParam(name = "claims", defaultValue = "") final ClaimsInfo claimsInfo,
@RequestHeader(name = TLS_CLIENT_CERT_HEADER_NAME, required = false) final String clientCert,
final HttpServletResponse respMsgNr3) {

Expand Down Expand Up @@ -357,16 +370,17 @@ public TokenResponse getTokensForCode(

final String idToken;
try {
idToken =
final JsonWebToken idTokenPlain =
new IdTokenBuilder(
jwtProcessorTokenSigPrivKey,
serverUrlService.determineServerUrl(),
session.getFachdienstNonce(),
clientId,
session.getUserData())
.buildIdToken()
.encryptAsJwt(token.getRpEncKey())
.getRawString();
.buildIdToken();
log.info("id-token: {}", idTokenPlain.getRawString());

idToken = idTokenPlain.encryptAsJwt(token.getRpEncKey()).getRawString();
} catch (final JoseException e) {
throw new GsiException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@
@RequiredArgsConstructor
public class InsuredPersonsService {
private final String insuredPersonsJsonFilePath;
private Map<String, Map<String, String>> persons;
private Map<String, Map<String, Object>> persons;

public Map<String, String> getPerson(final String kvnr) {
public Map<String, Object> getPerson(final String kvnr) {
return Optional.ofNullable(getPersons().get(kvnr)).orElse(getPersonFallback());
}

private Map<String, String> getPersonFallback() {
private Map<String, Object> getPersonFallback() {
return getPersons().get("X110411675");
}

public Map<String, Map<String, String>> getPersons() {
public Map<String, Map<String, Object>> getPersons() {
initPersons();
return persons;
}
Expand All @@ -55,16 +55,16 @@ private void initPersons() {
}
}

private Map<String, Map<String, String>> readInsuredPersons(final String filePath) {
private Map<String, Map<String, Object>> readInsuredPersons(final String filePath) {
try {
final List<Map<String, String>> dataList = readJsonFileToList(filePath);
final List<Map<String, Object>> dataList = readJsonFileToList(filePath);
return convertListToKvnrMap(dataList);
} catch (final IOException e) {
throw new GsiException("Could not read insured persons from file.", e);
}
}

private static List<Map<String, String>> readJsonFileToList(final String filePath)
private static List<Map<String, Object>> readJsonFileToList(final String filePath)
throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();

Expand All @@ -77,15 +77,15 @@ private static List<Map<String, String>> readJsonFileToList(final String filePat
}

// Read the JSON file into a List of Map<String, String>
return objectMapper.readValue(inputStream, new TypeReference<List<Map<String, String>>>() {});
return objectMapper.readValue(inputStream, new TypeReference<List<Map<String, Object>>>() {});
}

private static Map<String, Map<String, String>> convertListToKvnrMap(
final List<Map<String, String>> dataList) {
final Map<String, Map<String, String>> resultMap = new HashMap<>();
private static Map<String, Map<String, Object>> convertListToKvnrMap(
final List<Map<String, Object>> dataList) {
final Map<String, Map<String, Object>> resultMap = new HashMap<>();

for (final Map<String, String> dataMap : dataList) {
final String id = dataMap.get(TELEMATIK_ID.getJoseName());
for (final Map<String, Object> dataMap : dataList) {
final String id = (String) dataMap.get(TELEMATIK_ID.getJoseName());
if (id != null) {
resultMap.put(id, dataMap);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 gematik GmbH
* Copyright 2024 gematik GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,7 +20,6 @@
import de.gematik.idp.gsi.server.services.EntityStatementRpVerifier;
import de.gematik.idp.token.JsonWebToken;
import java.security.cert.X509Certificate;
import java.time.ZonedDateTime;
import java.util.List;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
Expand All @@ -35,7 +34,7 @@ public class RpToken {
private final JsonWebToken token;

public boolean isExpired() {
return !token.getExpiresAt().isBefore(ZonedDateTime.now());
return token.isExpired();
}

public void verify(final JsonWebKeySet jwks) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void doAuthentication(
final Map<String, Object> userData,
final String userId,
final Set<String> selectedClaimsSet) {
final Map<String, String> user = insuredPersonsService.getPerson(userId);
final Map<String, Object> user = insuredPersonsService.getPerson(userId);

selectedClaimsSet.forEach(claim -> userData.put(claim, user.get(claim)));
userData.put(
Expand All @@ -51,6 +51,6 @@ public void doAuthentication(
AUTHENTICATION_METHODS_REFERENCE.getJoseName(),
user.containsKey(AUTHENTICATION_METHODS_REFERENCE.getJoseName())
? user.get(AUTHENTICATION_METHODS_REFERENCE.getJoseName())
: "urn:telematik:auth:eGK");
: new String[] {"urn:telematik:auth:eGK"});
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 gematik GmbH
* Copyright 2024 gematik GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -185,15 +185,15 @@ private static Optional<PublicJsonWebKey> getEncKeyFromKeyList(
if (encKeyAsMap.isPresent()) {
return Optional.of(PublicJsonWebKey.Factory.newPublicJwk(encKeyAsMap.get()));
}
} catch (JoseException e) {
} catch (final JoseException e) {
return Optional.empty();
}
}
return Optional.empty();
}

private static X509Certificate extractX5cValueFromCert(Map<String, Object> certKey) {
List<String> x5cValues = (List<String>) certKey.get("x5c");
private static X509Certificate extractX5cValueFromCert(final Map<String, Object> certKey) {
final List<String> x5cValues = (List<String>) certKey.get("x5c");
if (x5cValues.isEmpty()) {
throw new GsiException(
INVALID_REQUEST, "No x5c certificate found in jwk", HttpStatus.UNAUTHORIZED);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 gematik GmbH
* Copyright 2024 gematik GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 gematik GmbH
* Copyright 2024 gematik GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 gematik GmbH
* Copyright 2024 gematik GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,8 +16,15 @@

package de.gematik.idp.gsi.server.services;

import static de.gematik.idp.data.Oauth2ErrorCode.*;
import static de.gematik.idp.gsi.server.data.GsiConstants.*;
import static de.gematik.idp.data.Oauth2ErrorCode.INVALID_REQUEST;
import static de.gematik.idp.data.Oauth2ErrorCode.INVALID_SCOPE;
import static de.gematik.idp.data.Oauth2ErrorCode.UNAUTHORIZED_CLIENT;
import static de.gematik.idp.gsi.server.data.GsiConstants.ACR_HIGH;
import static de.gematik.idp.gsi.server.data.GsiConstants.ACR_SUBSTANTIAL;
import static de.gematik.idp.gsi.server.data.GsiConstants.ACR_VALUES;
import static de.gematik.idp.gsi.server.data.GsiConstants.AMR_VALUES;
import static de.gematik.idp.gsi.server.data.GsiConstants.AMR_VALUES_HIGH;
import static de.gematik.idp.gsi.server.data.GsiConstants.AMR_VALUES_SUBSTANTIAL;

import de.gematik.idp.crypto.CryptoLoader;
import de.gematik.idp.crypto.exceptions.IdpCryptoException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 gematik GmbH
* Copyright 2024 gematik GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,7 +20,6 @@
import de.gematik.idp.token.JsonWebToken;
import de.gematik.idp.token.TokenClaimExtraction;
import java.security.PublicKey;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -69,7 +68,7 @@ private void updateStatementRpIfExpiredAndNewIsAvailable(final String issuer) {

private void updateStatementAboutRpIfExpiredAndNewIsAvailable(final String sub) {
if (entityStmtsAboutRp.containsKey(sub)) {
if (!entityStmtsAboutRp.get(sub).getExpiresAt().isBefore(ZonedDateTime.now())) {
if (entityStmtsAboutRp.get(sub).isExpired()) {
log.debug("Entitystatement about RP [{}] is in storage but expired. Fetching...", sub);
fetchAndStoreEntityStmntAboutRp(sub);
} else {
Expand Down
Loading

0 comments on commit 999f66a

Please sign in to comment.