Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: KID encoding #96

Merged
merged 2 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.security.cert.CertificateEncodingException;
Expand All @@ -64,7 +63,6 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;


@Slf4j
@Service
@RequiredArgsConstructor
Expand All @@ -76,8 +74,8 @@ public class DidTrustListService {
private static final String SEPARATOR_FRAGMENT = "#";

private static final List<String> DID_CONTEXTS = List.of(
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/jws-2020/v1");
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/jws-2020/v1");

private final TrustedIssuerService trustedIssuerService;

Expand Down Expand Up @@ -147,19 +145,19 @@ private String getCountryAsLowerCaseAlpha3(String country) {
}

return configProperties.getCountryCodeMap().getVirtualCountries()
.compute(country, (alpha2, alpha3) -> {
if (alpha3 != null) {
return alpha3.toLowerCase();
}

try {
return new Locale("en", alpha2).getISO3Country().toLowerCase();
} catch (MissingResourceException e) {
log.error("Country Code to alpha 3 conversion issue for country {} : {}",
country, e.getMessage());
return null;
}
});
.compute(country, (alpha2, alpha3) -> {
if (alpha3 != null) {
return alpha3.toLowerCase();
}

try {
return new Locale("en", alpha2).getISO3Country().toLowerCase();
} catch (MissingResourceException e) {
log.error("Country Code to alpha 3 conversion issue for country {} : {}",
country, e.getMessage());
return null;
}
});
}

private String generateTrustList(List<String> countries) throws Exception {
Expand All @@ -180,36 +178,35 @@ private String generateTrustList(List<String> countries) throws Exception {

// Add DSC
List<TrustedCertificateTrustList> certs = trustListService.getTrustedCertificateTrustList(
SignerInformationEntity.CertificateType.stringValues(),
countries,
null,
configProperties.getDid().getIncludeFederated()
);
SignerInformationEntity.CertificateType.stringValues(),
countries,
null,
configProperties.getDid().getIncludeFederated());

for (TrustedCertificateTrustList cert : certs) {

PublicKey publicKey = cert.getParsedCertificate().getPublicKey();

if (publicKey instanceof RSAPublicKey rsaPublicKey) {
addTrustListEntry(trustList, cert,
new DidTrustListEntryDto.RsaPublicKeyJwk(rsaPublicKey, List.of(cert.getCertificate())));
new DidTrustListEntryDto.RsaPublicKeyJwk(rsaPublicKey, List.of(cert.getCertificate())));

} else if (publicKey instanceof ECPublicKey ecPublicKey) {
addTrustListEntry(trustList, cert,
new DidTrustListEntryDto.EcPublicKeyJwk(ecPublicKey, List.of(cert.getCertificate())));
new DidTrustListEntryDto.EcPublicKeyJwk(ecPublicKey, List.of(cert.getCertificate())));

} else {
log.error("Public Key is not RSA or EC Public Key for cert {} of country {}",
cert.getThumbprint(),
cert.getCountry());
cert.getThumbprint(),
cert.getCountry());
}
}

// Add TrustedIssuer
trustedIssuerService.search(
null, countries, configProperties.getDid().getIncludeFederated()).stream()
.filter(trustedIssuer -> trustedIssuer.getUrlType() == TrustedIssuerEntity.UrlType.DID)
.forEach(trustedIssuer -> trustList.getVerificationMethod().add(trustedIssuer.getUrl()));
.filter(trustedIssuer -> trustedIssuer.getUrlType() == TrustedIssuerEntity.UrlType.DID)
.forEach(trustedIssuer -> trustList.getVerificationMethod().add(trustedIssuer.getUrl()));

// Create LD-Proof Document
JsonWebSignature2020LdSigner signer = new JsonWebSignature2020LdSigner(byteSigner);
Expand All @@ -229,7 +226,7 @@ private String generateTrustList(List<String> countries) throws Exception {
}

try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(
"did_contexts/" + didContextFile)) {
"did_contexts/" + didContextFile)) {
if (inputStream != null) {
contextMap.put(URI.create(didContext), JsonDocument.of(inputStream));
}
Expand All @@ -247,14 +244,14 @@ private String generateTrustList(List<String> countries) throws Exception {
}

private void addTrustListEntry(DidTrustListDto trustList,
TrustedCertificateTrustList cert,
DidTrustListEntryDto.PublicKeyJwk publicKeyJwk)
TrustedCertificateTrustList cert,
DidTrustListEntryDto.PublicKeyJwk publicKeyJwk)
throws CertificateEncodingException, UnsupportedEncodingException {
Optional<TrustedCertificateTrustList> csca = searchForIssuer(cert);

if (csca.isPresent()) {
publicKeyJwk.getEncodedX509Certificates()
.add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded()));
.add(Base64.getEncoder().encodeToString(csca.get().getParsedCertificate().getEncoded()));
}

DidTrustListEntryDto trustListEntry = new DidTrustListEntryDto();
Expand All @@ -263,7 +260,7 @@ private void addTrustListEntry(DidTrustListDto trustList,
+ SEPARATOR_COLON
+ getCountryAsLowerCaseAlpha3(cert.getCountry())
+ SEPARATOR_FRAGMENT
+ getEncodedKid(cert.getKid()));;
+ cert.getKid());
trustListEntry.setController(configProperties.getDid().getTrustListControllerPrefix()
+ SEPARATOR_COLON + getCountryAsLowerCaseAlpha3(cert.getCountry()));
trustListEntry.setPublicKeyJwk(publicKeyJwk);
Expand All @@ -279,12 +276,8 @@ private Optional<TrustedCertificateTrustList> searchForIssuer(TrustedCertificate
List.of(cert.getCountry()),
List.of(cert.getDomain()),
configProperties.getDid().getIncludeFederated()).stream()
.filter(tp -> tp.getParsedCertificate().getSubjectX500Principal()
.equals(cert.getParsedCertificate().getIssuerX500Principal()))
.findFirst();
}

private String getEncodedKid(String kid) {
return Base64URL.encode(kid).toString();
.filter(tp -> tp.getParsedCertificate().getSubjectX500Principal()
.equals(cert.getParsedCertificate().getIssuerX500Principal()))
.findFirst();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,11 @@ void testTrustList(boolean isEcAlgorithm) throws Exception {
Assertions.assertEquals("b", parsed.getController());
Assertions.assertEquals(6, parsed.getVerificationMethod().size());

assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":deu" + "#" + getEncodedKid(certDscDeKid)),
assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":deu" + "#" + certDscDeKid),
certDscDeKid, certDscDe, certCscaDe, "deu");
assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":xeu" + "#" + getEncodedKid("kid2")),
assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":xeu" + "#" + "kid2"),
"kid2", certDscEu, certCscaEu, "xeu");
assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":xex" + "#" + getEncodedKid("kid3")),
assertVerificationMethod(getVerificationMethodByKid(parsed.getVerificationMethod(), "c" + ":xex" + "#" + "kid3"),
"kid3", federatedCertDscEx, null, "xex");

Assertions.assertTrue(parsed.getVerificationMethod().contains("did:trusted:DE:issuer"));
Expand Down Expand Up @@ -262,7 +262,7 @@ private void assertVerificationMethod(Object in, String kid, X509Certificate dsc
LinkedHashMap jsonNode = (LinkedHashMap) in;
Assertions.assertEquals("JsonWebKey2020", jsonNode.get("type"));
Assertions.assertEquals("d" + ":" + country, jsonNode.get("controller"));
Assertions.assertEquals("c" + ":" + country + "#" + getEncodedKid(kid), jsonNode.get("id"));
Assertions.assertEquals("c" + ":" + country + "#" + kid, jsonNode.get("id"));

LinkedHashMap publicKeyJwk = (LinkedHashMap) jsonNode.get("publicKeyJwk");

Expand Down Expand Up @@ -314,8 +314,4 @@ private static class LDProof {

}
}

private String getEncodedKid(String kid) {
return Base64URL.encode(kid).toString();
}
}
Loading