Skip to content

Commit

Permalink
v26.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Gematik-Entwicklung authored and RStaeber committed Jan 26, 2024
1 parent 0281fb9 commit 2dc5d51
Show file tree
Hide file tree
Showing 53 changed files with 1,097 additions and 766 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ or use docker compose:

```console
$ mvn clean install -pl idp-server -am -Dskip.unittests -Dskip.inttests
$ export appVersion=25.1.1
$ export appVersion=26.0.0
$ export serverLoglevel=info (default)
$ docker-compose --project-name myidp -f docker-compose-ref.yml up -d
```
Expand Down
5 changes: 5 additions & 0 deletions ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Release 26.0.0

- Refactoring Key handling
- update dependencies

# Release 25.1.1

- IdpJwtProcessor can be instantiated without X509Certificate
Expand Down
340 changes: 170 additions & 170 deletions doc/tokenFlowEgk.html

Large diffs are not rendered by default.

322 changes: 161 additions & 161 deletions doc/tokenFlowPs.html

Large diffs are not rendered by default.

588 changes: 294 additions & 294 deletions doc/tokenFlowSso.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions idp-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
<parent>
<groupId>de.gematik.idp</groupId>
<artifactId>idp-global</artifactId>
<version>25.1.1</version>
<version>26.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>de.gematik.idp</groupId>
<artifactId>idp-client</artifactId>

<version>25.1.1</version>
<version>26.0.0</version>
<packaging>jar</packaging>

<dependencies>
Expand Down
4 changes: 2 additions & 2 deletions idp-commons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<parent>
<groupId>de.gematik.idp</groupId>
<artifactId>idp-global</artifactId>
<version>25.1.1</version>
<version>26.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>idp-commons</artifactId>

<version>25.1.1</version>
<version>26.0.0</version>

<dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@

import static de.gematik.idp.brainPoolExtension.BrainpoolAlgorithmSuiteIdentifiers.BRAINPOOL256_USING_SHA256;

import de.gematik.idp.crypto.model.PkiIdentity;
import de.gematik.idp.exceptions.ChallengeExpiredException;
import de.gematik.idp.exceptions.ChallengeSignatureInvalidException;
import de.gematik.idp.exceptions.IdpJoseException;
import de.gematik.idp.exceptions.NoNestedJwtFoundException;
import de.gematik.idp.field.ClaimName;
import de.gematik.idp.token.JsonWebToken;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.time.ZonedDateTime;
import java.util.Map;
Expand All @@ -43,7 +43,7 @@
@AllArgsConstructor
public class AuthenticationChallengeVerifier {

private PkiIdentity serverIdentity;
private PublicKey serverPublicKey;

public void verifyResponseAndThrowExceptionIfFail(final JsonWebToken authenticationResponse) {
final X509Certificate clientCertificate =
Expand Down Expand Up @@ -93,7 +93,7 @@ private void performServerSignatureValidationOfNjwt(final JsonWebToken authentic
throw new ChallengeExpiredException();
}
try {
serverChallenge.verify(serverIdentity.getCertificate().getPublicKey());
serverChallenge.verify(serverPublicKey);
} catch (final Exception e) {
throw new ChallengeSignatureInvalidException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class IdpJwtProcessor {

private final X509Certificate certificate;
private final String algorithm;
private Optional<String> keyId;
private Optional<String> keyId = Optional.empty();
private PrivateKey privateKey;

public IdpJwtProcessor(final PrivateKey privKey, final String keyId) {
Expand Down Expand Up @@ -72,16 +72,13 @@ public IdpJwtProcessor(@NonNull final PkiIdentity identity, final Optional<Strin
public IdpJwtProcessor(@NonNull final PkiIdentity identity) {
this(identity.getCertificate());
privateKey = identity.getPrivateKey();
this.keyId = Optional.empty();
}

public IdpJwtProcessor(@NonNull final X509Certificate certificate) {
this.certificate = certificate;
if (certificate.getPublicKey() instanceof ECPublicKey) {
if (((ECPublicKey) certificate.getPublicKey()).getParams() instanceof ECNamedCurveSpec
&& ((ECNamedCurveSpec) ((ECPublicKey) certificate.getPublicKey()).getParams())
.getName()
.equals("prime256v1")) {
if (certificate.getPublicKey() instanceof final ECPublicKey ecpublickey) {
if (ecpublickey.getParams() instanceof final ECNamedCurveSpec ecNamedCurveSpec
&& ecNamedCurveSpec.getName().equals("prime256v1")) {
algorithm = "ES256";
} else {
algorithm = BRAINPOOL256_USING_SHA256;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,9 @@ public JsonWebToken buildJwt() {
}

private String determineAlgorithm() {
if (signerKey instanceof ECPrivateKey) {
if (((ECPrivateKey) signerKey).getParams() instanceof ECNamedCurveSpec
&& ((ECNamedCurveSpec) ((ECPrivateKey) signerKey).getParams())
.getName()
.equals("prime256v1")) {
if (signerKey instanceof final ECPrivateKey ecPrivateKey) {
if (ecPrivateKey.getParams() instanceof final ECNamedCurveSpec ecNamedCurveSpec
&& ecNamedCurveSpec.getName().equals("prime256v1")) {
return AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256;
} else {
return BRAINPOOL256_USING_SHA256;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class FederationPrivKey {

private final PkiIdentity identity;
private Optional<Boolean> addX5c;
private Optional<String> keyId;
private String keyId;
private Optional<String> use;

public IdpKeyDescriptor buildJwk() {
Expand Down
40 changes: 26 additions & 14 deletions idp-commons/src/main/java/de/gematik/idp/data/FederationPubKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,43 @@

package de.gematik.idp.data;

import de.gematik.idp.crypto.model.PkiIdentity;
import de.gematik.idp.crypto.exceptions.IdpCryptoException;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;

@Setter
@AllArgsConstructor
@RequiredArgsConstructor
@Getter
public class FederationPubKey {

private final PkiIdentity identity;
private final String issuer;
private final String type;
@Setter private Optional<Boolean> addX5c;
@Setter private Optional<String> keyId;
@Setter private Optional<String> use;
@Setter private String url;
private Optional<X509Certificate> certificate = Optional.empty();
private Optional<PublicKey> publicKey = Optional.empty();
private String keyId;
private Optional<String> use = Optional.empty();

public IdpKeyDescriptor buildJwk() {
final IdpKeyDescriptor keyDesc =
IdpKeyDescriptor.constructFromX509Certificate(
identity.getCertificate(), keyId, addX5c.orElse(false));
keyDesc.setPublicKeyUse(use.orElse(null));
return keyDesc;
public IdpKeyDescriptor buildJwkWithX5c() {
return IdpKeyDescriptor.constructFromX509Certificate(certificate.orElseThrow(), keyId, true);
}

public IdpKeyDescriptor buildJwkWithoutX5c() {
if (publicKey.isPresent()) {
final IdpKeyDescriptor keyDesc = IdpKeyDescriptor.createFromPublicKey(publicKey.get(), keyId);
use.ifPresent(keyDesc::setPublicKeyUse);
return keyDesc;
} else if (certificate.isPresent()) {
final IdpKeyDescriptor keyDesc =
IdpKeyDescriptor.constructFromX509Certificate(certificate.get(), keyId, false);
use.ifPresent(keyDesc::setPublicKeyUse);
return keyDesc;
} else {
throw new IdpCryptoException(
"FederationPubKey invalid. No PublicKey or certificate present.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.gematik.idp.crypto.exceptions.IdpCryptoException;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down Expand Up @@ -48,6 +49,9 @@ public class IdpEccKeyDescriptor extends IdpKeyDescriptor {
@JsonProperty("alg")
private String alg;

// added for javadoc plugin
public static class IdpEccKeyDescriptorBuilder {}

@Builder
public IdpEccKeyDescriptor(
final String[] x5c,
Expand All @@ -67,14 +71,25 @@ public IdpEccKeyDescriptor(

public static IdpKeyDescriptor constructFromX509Certificate(
final X509Certificate certificate, final String keyId, final boolean addX5C) {
try {
final IdpEccKeyDescriptor.IdpEccKeyDescriptorBuilder descriptorBuilder =
IdpEccKeyDescriptor.builder().keyId(keyId).keyType(getKeyType(certificate));
if (addX5C) {
descriptorBuilder.x5c(getCertArray(certificate));
}
final IdpEccKeyDescriptor.IdpEccKeyDescriptorBuilder descriptorBuilder =
IdpEccKeyDescriptor.builder().keyId(keyId).keyType(getKeyType(certificate));
if (addX5C) {
descriptorBuilder.x5c(getCertArray(certificate));
}
return getIdpEccKeyDescriptor(certificate.getPublicKey(), descriptorBuilder);
}

public static IdpKeyDescriptor createFromPublicKey(
final PublicKey publicKey, final String keyId) {
final IdpEccKeyDescriptor.IdpEccKeyDescriptorBuilder descriptorBuilder =
IdpEccKeyDescriptor.builder().keyId(keyId).keyType(getKeyType(publicKey));
return getIdpEccKeyDescriptor(publicKey, descriptorBuilder);
}

final BCECPublicKey bcecPublicKey = (BCECPublicKey) (certificate.getPublicKey());
private static IdpEccKeyDescriptor getIdpEccKeyDescriptor(
final PublicKey publicKey, final IdpEccKeyDescriptorBuilder descriptorBuilder) {
try {
final BCECPublicKey bcecPublicKey = (BCECPublicKey) publicKey;
String eccCurveName = "";
String alg = null;
if (((ECNamedCurveParameterSpec) bcecPublicKey.getParameters())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import de.gematik.idp.crypto.exceptions.IdpCryptoException;
import de.gematik.idp.exceptions.IdpJoseException;
import java.security.PublicKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
Expand Down Expand Up @@ -66,23 +66,36 @@ public static String[] getCertArray(final X509Certificate certificate) {
}
}

public static IdpKeyDescriptor constructFromX509Certificate(final X509Certificate certificate) {
return constructFromX509Certificate(certificate, Optional.empty(), true);
public static IdpKeyDescriptor constructFromX509Certificate(
final X509Certificate certificate, final String keyId) {
return constructFromX509Certificate(certificate, keyId, true);
}

public static IdpKeyDescriptor constructFromX509Certificate(
final X509Certificate certificate, final Optional<String> keyId, final boolean addX5C) {
final X509Certificate certificate, final String keyId, final boolean addX5C) {
if (isEcKey(certificate.getPublicKey())) {
return IdpEccKeyDescriptor.constructFromX509Certificate(
certificate, keyId.orElse(certificate.getSerialNumber().toString()), addX5C);
return IdpEccKeyDescriptor.constructFromX509Certificate(certificate, keyId, addX5C);
} else {
return IdpRsaKeyDescriptor.constructFromX509Certificate(
certificate, keyId.orElse(certificate.getSerialNumber().toString()), addX5C);
return IdpRsaKeyDescriptor.constructFromX509Certificate(certificate, keyId);
}
}

public static IdpKeyDescriptor createFromPublicKey(
final PublicKey publicKey, final String keyId) {

if (isEcKey(publicKey)) {
return IdpEccKeyDescriptor.createFromPublicKey(publicKey, keyId);
} else {
throw new IdpCryptoException("Unknown Key-Format encountered!");
}
}

public static String getKeyType(final X509Certificate certificate) {
if (isEcKey(certificate.getPublicKey())) {
return getKeyType(certificate.getPublicKey());
}

public static String getKeyType(final PublicKey publicKey) {
if (isEcKey(publicKey)) {
return EllipticCurveJsonWebKey.KEY_TYPE;
} else {
return RsaJsonWebKey.KEY_TYPE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,12 @@ public IdpRsaKeyDescriptor(
}

public static IdpKeyDescriptor constructFromX509Certificate(
final X509Certificate certificate, final String keyId, final boolean addX5C) {
final X509Certificate certificate, final String keyId) {
try {
final IdpRsaKeyDescriptor.IdpRsaKeyDescriptorBuilder descriptorBuilder =
IdpRsaKeyDescriptor.builder().keyId(keyId).keyType(getKeyType(certificate));
if (addX5C) {
descriptorBuilder.x5c(getCertArray(certificate));
}

descriptorBuilder.x5c(getCertArray(certificate));

final BCRSAPublicKey bcrsaPublicKey = (BCRSAPublicKey) certificate.getPublicKey();
descriptorBuilder
Expand Down
51 changes: 25 additions & 26 deletions idp-commons/src/main/java/de/gematik/idp/data/JwtHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import de.gematik.idp.authentication.IdpJwtProcessor;
import de.gematik.idp.exceptions.IdpRuntimeException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import lombok.AccessLevel;
Expand Down Expand Up @@ -53,40 +53,39 @@ public static String invalidateJsonSignature(final String jwsRawString) {
return String.join(".", splitJws);
}

public static IdpJwksDocument getJwks(final FederationPrivKey... federationPrivKeys) {
return IdpJwksDocument.builder()
.keys(
Arrays.stream(federationPrivKeys)
.map(
federationPrivKey -> {
final IdpKeyDescriptor keyDesc =
IdpKeyDescriptor.constructFromX509Certificate(
federationPrivKey.getIdentity().getCertificate(),
federationPrivKey.getKeyId(),
federationPrivKey.getAddX5c().orElse(false));
keyDesc.setPublicKeyUse(federationPrivKey.getUse().orElse(null));
return keyDesc;
})
.toList())
.build();
}

// TODO: IDP-740
public static IdpJwksDocument getJwks(@NonNull final FederationPubKey... federationPubKeys) {
return IdpJwksDocument.builder()
.keys(
final List<IdpKeyDescriptor> keyDescriptors =
new java.util.ArrayList<>(
Stream.of(federationPubKeys)
.filter(federationPubKey -> federationPubKey.getCertificate().isPresent())
.map(
federationPubKey -> {
final IdpKeyDescriptor keyDesc =
IdpKeyDescriptor.constructFromX509Certificate(
federationPubKey.getIdentity().getCertificate(),
federationPubKey.getCertificate().orElseThrow(),
federationPubKey.getKeyId(),
federationPubKey.getAddX5c().orElse(false));
true);
keyDesc.setPublicKeyUse(federationPubKey.getUse().orElse(null));
return keyDesc;
})
.toList())
.build();
.toList());

final List<IdpKeyDescriptor> keyDescriptorsWithoutX5c =
Stream.of(federationPubKeys)
.filter(federationPubKey -> federationPubKey.getPublicKey().isPresent())
.map(
federationPubKey -> {
final IdpKeyDescriptor keyDesc =
IdpKeyDescriptor.createFromPublicKey(
federationPubKey.getPublicKey().orElseThrow(),
federationPubKey.getKeyId());
keyDesc.setPublicKeyUse(federationPubKey.getUse().orElse(null));
return keyDesc;
})
.toList();

keyDescriptors.addAll(keyDescriptorsWithoutX5c);

return IdpJwksDocument.builder().keys(keyDescriptors).build();
}
}

0 comments on commit 2dc5d51

Please sign in to comment.