|
23 | 23 | package eu.webeid.security.validator.versionvalidators; |
24 | 24 |
|
25 | 25 | import eu.webeid.security.authtoken.SupportedSignatureAlgorithm; |
| 26 | +import eu.webeid.security.authtoken.UnverifiedSigningCertificate; |
26 | 27 | import eu.webeid.security.authtoken.WebEidAuthToken; |
27 | 28 | import eu.webeid.security.certificate.CertificateLoader; |
28 | 29 | import eu.webeid.security.exceptions.AuthTokenException; |
|
45 | 46 | import java.security.cert.CertificateNotYetValidException; |
46 | 47 | import java.security.cert.TrustAnchor; |
47 | 48 | import java.security.cert.X509Certificate; |
| 49 | +import java.util.ArrayList; |
48 | 50 | import java.util.Arrays; |
49 | 51 | import java.util.List; |
50 | 52 | import java.util.Set; |
@@ -90,37 +92,57 @@ protected String getSupportedFormatPrefix() { |
90 | 92 | @Override |
91 | 93 | public X509Certificate validate(WebEidAuthToken token, String currentChallengeNonce) throws AuthTokenException { |
92 | 94 | final X509Certificate subjectCertificate = validateV1(token, currentChallengeNonce); |
93 | | - final X509Certificate signingCertificate = validateSigningCertificateExists(token); |
94 | | - validateSupportedSignatureAlgorithms(token.getSupportedSignatureAlgorithms()); |
95 | | - validateSameSubject(subjectCertificate, signingCertificate); |
96 | | - validateSameIssuer(subjectCertificate, signingCertificate); |
97 | | - validateSigningCertificateValidity(signingCertificate); |
98 | | - validateKeyUsage(signingCertificate); |
| 95 | + final List<X509Certificate> signingCertificates = validateSigningCertificates(token); |
| 96 | + for (X509Certificate signingCertificate : signingCertificates) { |
| 97 | + validateSameSubject(subjectCertificate, signingCertificate); |
| 98 | + validateSameIssuer(subjectCertificate, signingCertificate); |
| 99 | + validateSigningCertificateValidity(signingCertificate); |
| 100 | + validateKeyUsage(signingCertificate); |
| 101 | + } |
99 | 102 |
|
100 | 103 | return subjectCertificate; |
101 | 104 | } |
102 | 105 |
|
103 | | - private static void validateSupportedSignatureAlgorithms(List<SupportedSignatureAlgorithm> algorithms) throws AuthTokenParseException { |
| 106 | + private static void validateSupportedSignatureAlgorithms(UnverifiedSigningCertificate cert) throws AuthTokenParseException { |
| 107 | + List<SupportedSignatureAlgorithm> algorithms = cert.getSupportedSignatureAlgorithms(); |
| 108 | + |
104 | 109 | if (algorithms == null || algorithms.isEmpty()) { |
105 | 110 | throw new AuthTokenParseException("'supportedSignatureAlgorithms' field is missing"); |
106 | 111 | } |
107 | 112 |
|
108 | | - boolean hasInvalid = algorithms.stream().anyMatch(supportedSignatureAlgorithm -> |
109 | | - !SUPPORTED_SIGNING_CRYPTO_ALGORITHMS.contains(supportedSignatureAlgorithm.getCryptoAlgorithm()) || |
110 | | - !SUPPORTED_SIGNING_HASH_FUNCTIONS.contains(supportedSignatureAlgorithm.getHashFunction()) || |
111 | | - !SUPPORTED_SIGNING_PADDING_SCHEMES.contains(supportedSignatureAlgorithm.getPaddingScheme()) |
| 113 | + boolean hasInvalid = algorithms.stream().anyMatch(algorithm -> |
| 114 | + algorithm == null || |
| 115 | + algorithm.getCryptoAlgorithm() == null || |
| 116 | + algorithm.getHashFunction() == null || |
| 117 | + algorithm.getPaddingScheme() == null || |
| 118 | + !SUPPORTED_SIGNING_CRYPTO_ALGORITHMS.contains(algorithm.getCryptoAlgorithm()) || |
| 119 | + !SUPPORTED_SIGNING_HASH_FUNCTIONS.contains(algorithm.getHashFunction()) || |
| 120 | + !SUPPORTED_SIGNING_PADDING_SCHEMES.contains(algorithm.getPaddingScheme()) |
112 | 121 | ); |
113 | 122 |
|
114 | 123 | if (hasInvalid) { |
115 | 124 | throw new AuthTokenParseException("Unsupported signature algorithm"); |
116 | 125 | } |
117 | 126 | } |
118 | 127 |
|
119 | | - private static X509Certificate validateSigningCertificateExists(WebEidAuthToken token) throws AuthTokenParseException, CertificateDecodingException { |
120 | | - if (isNullOrEmpty(token.getUnverifiedSigningCertificate())) { |
121 | | - throw new AuthTokenParseException("'unverifiedSigningCertificate' field is missing, null or empty for format 'web-eid:1.1'"); |
| 128 | + private static List<X509Certificate> validateSigningCertificates(WebEidAuthToken token) throws AuthTokenParseException, CertificateDecodingException { |
| 129 | + List<UnverifiedSigningCertificate> signingCertificates = token.getUnverifiedSigningCertificates(); |
| 130 | + |
| 131 | + if (signingCertificates == null || signingCertificates.isEmpty()) { |
| 132 | + throw new AuthTokenParseException("'unverifiedSigningCertificates' field is missing, null or empty for format 'web-eid:1.1'"); |
| 133 | + } |
| 134 | + |
| 135 | + List<X509Certificate> result = new ArrayList<>(); |
| 136 | + |
| 137 | + for (UnverifiedSigningCertificate certificate : signingCertificates) { |
| 138 | + if (certificate == null || isNullOrEmpty(certificate.getCertificate())) { |
| 139 | + throw new AuthTokenParseException("'unverifiedSigningCertificates' contains a null or empty entry for format 'web-eid:1.1'"); |
| 140 | + } |
| 141 | + validateSupportedSignatureAlgorithms(certificate); |
| 142 | + result.add(CertificateLoader.decodeCertificateFromBase64(certificate.getCertificate())); |
122 | 143 | } |
123 | | - return CertificateLoader.decodeCertificateFromBase64(token.getUnverifiedSigningCertificate()); |
| 144 | + |
| 145 | + return result; |
124 | 146 | } |
125 | 147 |
|
126 | 148 | private static void validateSameSubject(X509Certificate subjectCertificate, X509Certificate signingCertificate) |
|
0 commit comments