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

FIWARE / contract-management / #85

15 Apr 2026 08:18AM UTC coverage: 1.681%. Remained the same
#85

Pull #21

wistefan
load from file
Pull Request #21: load from file

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

587 of 34920 relevant lines covered (1.68%)

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.nio.file.Files;
38
import java.nio.file.Path;
39
import java.nio.file.Paths;
40
import java.security.KeyFactory;
41
import java.security.NoSuchAlgorithmException;
42
import java.security.PrivateKey;
43
import java.security.Security;
44
import java.security.cert.*;
45
import java.security.spec.InvalidKeySpecException;
46
import java.security.spec.PKCS8EncodedKeySpec;
47
import java.util.*;
48
import java.util.stream.Collectors;
49

50
@Factory
51
public class Application {
×
52

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

58
    public static void main(String[] args) {
59
        Micronaut.run(Application.class, args);
×
60
    }
×
61

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

73
        return httpClientBuilder.build();
×
74
    }
75

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

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

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

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

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

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

118
        DCQLEvaluator dcqlEvaluator = new DCQLEvaluator(List.of(
×
119
                new JwtCredentialEvaluator(),
120
                new DcSdJwtCredentialEvaluator(),
121
                new VcSdJwtCredentialEvaluator()));
122

123

124
        return new OID4VPClient(
×
125
                httpClient,
126
                holderConfiguration,
127
                authObjectMapper,
128
                List.of(clientResolver),
×
129
                dcqlEvaluator,
130
                credentialsRepository,
131
                signingService);
132

133
    }
134

135
    private static InputStream openInputStream(String filepath) throws IOException {
136
        Path path = Paths.get(filepath);
×
137
        if (Files.isDirectory(path)) {
×
138
            return null;
×
139
        }
140
        if (Files.exists(path)) {
×
141
            return Files.newInputStream(path);
×
142
        }
143
        return null;
×
144
    }
145

146
    private static PrivateKey loadPrivateKey(String keyType, String filename) {
147
        try (InputStream is = openInputStream(filename)) {
×
148
            if (is == null) {
×
149
                throw new IllegalArgumentException("Private key not found: " + filename);
×
150
            }
151

152
            // Read PEM file content
153
            String pem =
×
154
                    new String(is.readAllBytes(), StandardCharsets.UTF_8)
×
155
                            .replaceAll("-----BEGIN (.*)-----", "")
×
156
                            .replaceAll("-----END (.*)-----", "")
×
157
                            .replaceAll("\\s", "");
×
158

159
            // Base64 decode
160
            byte[] decoded = Base64.getDecoder().decode(pem);
×
161

162
            // Build key spec
163
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
×
164
            KeyFactory keyFactory = KeyFactory.getInstance(keyType); // or "EC"
×
165
            return keyFactory.generatePrivate(keySpec);
×
166
        } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
×
167
            throw new IllegalArgumentException(
×
168
                    String.format(
×
169
                            "Was not able to load the private key with type %s from %s", keyType, filename),
170
                    e);
171
        }
172
    }
173

174
    private static List<X509Certificate> loadCertificates(String resource) {
175

NEW
176
        try (InputStream is = openInputStream(resource)) {
×
177
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
×
178
            Collection<? extends Certificate> certs = cf.generateCertificates(is);
×
179

180
            List<X509Certificate> list = new ArrayList<>();
×
181
            for (Certificate cert : certs) {
×
182
                list.add((X509Certificate) cert);
×
183
            }
×
184
            return list;
×
185
        } catch (IOException | CertificateException e) {
×
186
            throw new IllegalArgumentException(String.format("Was not able to load the certificates from %s", resource), e);
×
187
        }
188
    }
189
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc