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

FIWARE / contract-management / #75

18 Dec 2025 08:09AM UTC coverage: 1.686%. Remained the same
#75

push

wistefan
the default trust-anchors(provided by the system trust store) should be used in case nothing is explicitly configured.

0 of 4 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

587 of 34810 relevant lines covered (1.69%)

0.02 hits per line

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

0.0
/src/main/java/org/fiware/iam/Application.java
1
package org.fiware.iam;
2

3
import com.fasterxml.jackson.databind.ObjectMapper;
4
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
5
import com.fasterxml.jackson.databind.module.SimpleModule;
6
import com.nimbusds.jose.JWEAlgorithm;
7
import io.github.wistefan.dcql.DCQLEvaluator;
8
import io.github.wistefan.dcql.DcSdJwtCredentialEvaluator;
9
import io.github.wistefan.dcql.JwtCredentialEvaluator;
10
import io.github.wistefan.dcql.VcSdJwtCredentialEvaluator;
11
import io.github.wistefan.dcql.model.CredentialFormat;
12
import io.github.wistefan.dcql.model.TrustedAuthorityType;
13
import io.github.wistefan.oid4vp.HolderSigningService;
14
import io.github.wistefan.oid4vp.OID4VPClient;
15
import io.github.wistefan.oid4vp.SigningService;
16
import io.github.wistefan.oid4vp.client.X509SanDnsClientResolver;
17
import io.github.wistefan.oid4vp.config.HolderConfiguration;
18
import io.github.wistefan.oid4vp.credentials.CredentialsRepository;
19
import io.github.wistefan.oid4vp.credentials.FileSystemCredentialsRepository;
20
import io.github.wistefan.oid4vp.mapping.CredentialFormatDeserializer;
21
import io.github.wistefan.oid4vp.mapping.TrustedAuthorityTypeDeserializer;
22
import io.micronaut.context.annotation.Bean;
23
import io.micronaut.context.annotation.Factory;
24
import io.micronaut.context.annotation.Requires;
25
import io.micronaut.runtime.Micronaut;
26
import jakarta.inject.Singleton;
27
import org.bouncycastle.jce.provider.BouncyCastleProvider;
28
import org.fiware.iam.configuration.Oid4VpConfiguration;
29
import org.fiware.iam.exception.Oid4VpInitException;
30

31
import java.io.IOException;
32
import java.io.InputStream;
33
import java.net.InetSocketAddress;
34
import java.net.ProxySelector;
35
import java.net.http.HttpClient;
36
import java.nio.charset.StandardCharsets;
37
import java.security.KeyFactory;
38
import java.security.NoSuchAlgorithmException;
39
import java.security.PrivateKey;
40
import java.security.Security;
41
import java.security.cert.*;
42
import java.security.spec.InvalidKeySpecException;
43
import java.security.spec.PKCS8EncodedKeySpec;
44
import java.util.*;
45
import java.util.stream.Collectors;
46

47
@Factory
48
public class Application {
×
49

50
    private static final String CACERTS_PATH = System.getProperty("javax.net.ssl.trustStore",
×
51
            System.getProperty("java.home") + "/lib/security/cacerts");
×
52
    private static final char[] DEFAULT_TRUSTSTORE_PASSWORD = System.getProperty(
×
53
            "javax.net.ssl.trustStorePassword", "changeit").toCharArray();
×
54

55
    public static void main(String[] args) {
56
        Micronaut.run(Application.class, args);
×
57
    }
×
58

59
    @Requires(bean = Oid4VpConfiguration.class)
60
    @Singleton
61
    public HttpClient httpClient(Oid4VpConfiguration.ProxyConfig proxyConfig) {
62
        HttpClient.Builder httpClientBuilder = HttpClient.newBuilder();
×
63
        // required for the authorization flow to work
64
        httpClientBuilder.followRedirects(HttpClient.Redirect.NORMAL);
×
65
        if (proxyConfig.useProxy()) {
×
66
            ProxySelector proxySelector = ProxySelector.of(new InetSocketAddress(proxyConfig.proxyHost(), proxyConfig.proxyPort()));
×
67
            httpClientBuilder.proxy(proxySelector);
×
68
        }
69

70
        return httpClientBuilder.build();
×
71
    }
72

73
    @Requires(bean = Oid4VpConfiguration.class)
74
    @Bean
75
    public CredentialsRepository credentialsRepository(Oid4VpConfiguration oid4VpConfiguration, ObjectMapper objectMapper) {
76
        return new FileSystemCredentialsRepository(oid4VpConfiguration.getCredentialsFolder(), objectMapper);
×
77
    }
78

79
    @Requires(bean = Oid4VpConfiguration.class)
80
    @Bean
81
    public OID4VPClient oid4VPClient(HttpClient httpClient, ObjectMapper objectMapper, Oid4VpConfiguration oid4VpConfiguration, CredentialsRepository credentialsRepository) {
82
        // required for octect-key support
83
        Security.addProvider(new BouncyCastleProvider());
×
84

85
        // properly deserialize dcql
86
        ObjectMapper authObjectMapper = objectMapper.copy();
×
87
        authObjectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
×
88
        SimpleModule deserializerModule = new SimpleModule();
×
89
        deserializerModule.addDeserializer(CredentialFormat.class, new CredentialFormatDeserializer());
×
90
        deserializerModule.addDeserializer(TrustedAuthorityType.class, new TrustedAuthorityTypeDeserializer());
×
91
        authObjectMapper.registerModule(deserializerModule);
×
92

93
        // initialize the holder
94
        PrivateKey privateKey = loadPrivateKey(oid4VpConfiguration.getHolder().keyType(), oid4VpConfiguration.getHolder().keyPath());
×
95
        HolderConfiguration holderConfiguration = new HolderConfiguration(
×
96
                oid4VpConfiguration.getHolder().holderId(),
×
97
                oid4VpConfiguration.getHolder().holderId().toString(),
×
98
                JWEAlgorithm.parse(oid4VpConfiguration.getHolder().signatureAlgorithm()),
×
99
                privateKey);
100
        SigningService signingService = new HolderSigningService(holderConfiguration, objectMapper);
×
101

102
        Set<TrustAnchor> trustAnchors = oid4VpConfiguration.getTrustAnchors()
×
103
                .stream()
×
104
                .map(Application::loadCertificates)
×
105
                .flatMap(List::stream)
×
106
                .map(c -> new TrustAnchor(c, null))
×
107
                .collect(Collectors.toSet());
×
108

NEW
109
        X509SanDnsClientResolver clientResolver = new X509SanDnsClientResolver();
×
NEW
110
        if (!trustAnchors.isEmpty()) {
×
111
            //if trust anchors are explicitly configured, use them.
NEW
112
            clientResolver = new X509SanDnsClientResolver(trustAnchors, false);
×
113
        }
114

UNCOV
115
        DCQLEvaluator dcqlEvaluator = new DCQLEvaluator(List.of(
×
116
                new JwtCredentialEvaluator(),
117
                new DcSdJwtCredentialEvaluator(),
118
                new VcSdJwtCredentialEvaluator()));
119

120

121
        return new OID4VPClient(
×
122
                httpClient,
123
                holderConfiguration,
124
                authObjectMapper,
NEW
125
                List.of(clientResolver),
×
126
                dcqlEvaluator,
127
                credentialsRepository,
128
                signingService);
129

130
    }
131

132
    private static PrivateKey loadPrivateKey(String keyType, String filename) {
133
        try (InputStream is = Application.class.getClassLoader().getResourceAsStream(filename)) {
×
134
            if (is == null) {
×
135
                throw new IllegalArgumentException("Resource not found: " + filename);
×
136
            }
137

138
            // Read PEM file content
139
            String pem = new String(is.readAllBytes(), StandardCharsets.UTF_8)
×
140
                    .replaceAll("-----BEGIN (.*)-----", "")
×
141
                    .replaceAll("-----END (.*)-----", "")
×
142
                    .replaceAll("\\s", "");
×
143

144
            // Base64 decode
145
            byte[] decoded = Base64.getDecoder().decode(pem);
×
146

147
            // Build key spec
148
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
×
149
            KeyFactory keyFactory = KeyFactory.getInstance(keyType); // or "EC"
×
150
            return keyFactory.generatePrivate(keySpec);
×
151
        } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
×
152
            throw new Oid4VpInitException(String.format("Was not able to load the private key with type %s from %s", keyType, filename), e);
×
153
        }
154
    }
155

156
    private static List<X509Certificate> loadCertificates(String resource) {
157

158
        try (InputStream is = Application.class.getClassLoader().getResourceAsStream(resource)) {
×
159
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
×
160
            Collection<? extends Certificate> certs = cf.generateCertificates(is);
×
161

162
            List<X509Certificate> list = new ArrayList<>();
×
163
            for (Certificate cert : certs) {
×
164
                list.add((X509Certificate) cert);
×
165
            }
×
166
            return list;
×
167
        } catch (IOException | CertificateException e) {
×
168
            throw new Oid4VpInitException(String.format("Was not able to load the certificates from %s", resource), e);
×
169
        }
170
    }
171

172

173
}
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

© 2026 Coveralls, Inc