• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FIWARE / trusted-issuers-registry / #9

26 Mar 2024 02:34PM UTC coverage: 74.517% (+0.6%) from 73.938%
#9

push

web-flow
Merge 0964f4c47 into ccfe35d76

2 of 2 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

386 of 518 relevant lines covered (74.52%)

0.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.89
/src/main/java/org/fiware/iam/tir/auth/JWTService.java
1
package org.fiware.iam.tir.auth;
2

3
import com.auth0.jwt.JWT;
4
import com.auth0.jwt.algorithms.Algorithm;
5
import com.auth0.jwt.exceptions.JWTVerificationException;
6
import com.auth0.jwt.interfaces.DecodedJWT;
7
import jakarta.inject.Singleton;
8
import lombok.RequiredArgsConstructor;
9
import lombok.extern.slf4j.Slf4j;
10
import org.fiware.iam.tir.configuration.Party;
11
import org.fiware.iam.tir.configuration.SatelliteProperties;
12
import org.fiware.iam.tir.configuration.TrustedCA;
13
import org.fiware.iam.tir.repository.PartiesRepo;
14

15
import java.security.*;
16
import java.security.cert.Certificate;
17
import java.security.cert.*;
18
import java.util.List;
19
import java.util.Optional;
20
import java.util.stream.Collectors;
21

22
/**
23
 * Handles validation of JWT tokens with iShare specifics. Verifies that the tokens are issued by a trusted party
24
 */
25
@Slf4j
1✔
26
@RequiredArgsConstructor
1✔
27
@Singleton
28
public class JWTService {
29

30
    private final PartiesRepo partiesRepo;
31
    private final SatelliteProperties satelliteProperties;
32
    private final CertificateMapper certificateMapper;
33

34

35
    private void validateCertificateChain(List<String> certificates) {
36
        try {
37
            List<Certificate> mappedCertificates = certificates
1✔
38
                    .stream()
1✔
39
                    .map(certificateMapper::mapCertificate)
1✔
40
                    .collect(Collectors.toList());
1✔
41
            List<? extends Certificate> certificateChain = certificateMapper.getCertificateFactory().generateCertPath(mappedCertificates).getCertificates();
1✔
42

43
            for (int i = 0; i < certificateChain.size() - 1; i++) {
1✔
44
                certificateChain.get(i).verify(certificateChain.get(i + 1).getPublicKey());
1✔
45
            }
46
        } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException |
1✔
47
                 SignatureException e) {
48
            throw new IllegalArgumentException("Certificate chain could not be validated", e);
1✔
49
        }
1✔
50
    }
1✔
51

52

53
    /**
54
     * Validate and decode a JWT token build according to the iShare spec. Requires a PEM formatted certificate chain in the header claim
55
     *
56
     * @param jwtString
57
     * @return
58
     */
59
    public DecodedJWT validateJWT(String jwtString) {
60
        DecodedJWT decodedJWT = JWT.decode(jwtString);
1✔
61
        List<String> certs = decodedJWT.getHeaderClaim("x5c").asList(String.class);
1✔
62
        if (certs.isEmpty()) {
1✔
UNCOV
63
            throw new IllegalArgumentException("Did not receive a full x5c chain.");
×
64
        }
65

66
        validateCertificateChain(certs);
1✔
67

68
        String clientCert = certs.get(0);
1✔
69
        String caCert = certs.get(certs.size()-1);
1✔
70
        try {
71
            JWT.require(Algorithm.RSA256(certificateMapper.getPublicKey(clientCert))).build().verify(jwtString);
1✔
72
        } catch (JWTVerificationException jwtVerificationException) {
×
73
            throw new IllegalArgumentException("Token not verified.", jwtVerificationException);
×
74
        }
1✔
75
        Optional<String> optionalTrustedCA = satelliteProperties.getTrustedList().stream()
1✔
76
                .map(TrustedCA::crt)
1✔
77
                .map(certificateMapper::stripCertificateOfPEMHeaders)
1✔
78
                .filter(caCert::equals)
1✔
79
                .findFirst();
1✔
80
        if (optionalTrustedCA.isEmpty()) {
1✔
81
            partiesRepo.getPartyById(decodedJWT.getClaim("iss").asString())
1✔
82
                    .map(Party::crt)
1✔
83
                    .map(certificateMapper::getCertificatesWithoutHeaders)
1✔
84
                    // get the client cert
85
                    .map(parsedCerts -> parsedCerts.get(0))
1✔
86
                    .filter(clientCert::equals)
1✔
87
                    .orElseThrow(() -> new IllegalArgumentException("No trusted CA and no trusted party found."));
1✔
88
        }
89

90
        return decodedJWT;
1✔
91
    }
92

93

94

95

96

97
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc