1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.ssl.util;
17
18 import javax.security.auth.x500.X500Principal;
19 import java.io.ByteArrayInputStream;
20 import java.math.BigInteger;
21 import java.security.InvalidKeyException;
22 import java.security.NoSuchAlgorithmException;
23 import java.security.NoSuchProviderException;
24 import java.security.Principal;
25 import java.security.Provider;
26 import java.security.PublicKey;
27 import java.security.SignatureException;
28 import java.security.cert.CertificateEncodingException;
29 import java.security.cert.CertificateException;
30 import java.security.cert.CertificateExpiredException;
31 import java.security.cert.CertificateFactory;
32 import java.security.cert.CertificateNotYetValidException;
33 import java.security.cert.CertificateParsingException;
34 import java.security.cert.X509Certificate;
35 import java.util.Collection;
36 import java.util.Date;
37 import java.util.List;
38 import java.util.Set;
39
40 import static java.util.Objects.requireNonNull;
41
42 public final class LazyX509Certificate extends X509Certificate {
43
44 static final CertificateFactory X509_CERT_FACTORY;
45 static {
46 try {
47 X509_CERT_FACTORY = CertificateFactory.getInstance("X.509");
48 } catch (CertificateException e) {
49 throw new ExceptionInInitializerError(e);
50 }
51 }
52
53 private final byte[] bytes;
54 private X509Certificate wrapped;
55
56
57
58
59 public LazyX509Certificate(byte[] bytes) {
60 this.bytes = requireNonNull(bytes, "bytes");
61 }
62
63 @Override
64 public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {
65 unwrap().checkValidity();
66 }
67
68 @Override
69 public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException {
70 unwrap().checkValidity(date);
71 }
72
73 @Override
74 public X500Principal getIssuerX500Principal() {
75 return unwrap().getIssuerX500Principal();
76 }
77
78 @Override
79 public X500Principal getSubjectX500Principal() {
80 return unwrap().getSubjectX500Principal();
81 }
82
83 @Override
84 public List<String> getExtendedKeyUsage() throws CertificateParsingException {
85 return unwrap().getExtendedKeyUsage();
86 }
87
88 @Override
89 public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException {
90 return unwrap().getSubjectAlternativeNames();
91 }
92
93 @Override
94 public Collection<List<?>> getIssuerAlternativeNames() throws CertificateParsingException {
95 return unwrap().getSubjectAlternativeNames();
96 }
97
98
99 @Override
100 public void verify(PublicKey key, Provider sigProvider)
101 throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
102 unwrap().verify(key, sigProvider);
103 }
104
105 @Override
106 public int getVersion() {
107 return unwrap().getVersion();
108 }
109
110 @Override
111 public BigInteger getSerialNumber() {
112 return unwrap().getSerialNumber();
113 }
114
115 @Override
116 public Principal getIssuerDN() {
117 return unwrap().getIssuerDN();
118 }
119
120 @Override
121 public Principal getSubjectDN() {
122 return unwrap().getSubjectDN();
123 }
124
125 @Override
126 public Date getNotBefore() {
127 return unwrap().getNotBefore();
128 }
129
130 @Override
131 public Date getNotAfter() {
132 return unwrap().getNotAfter();
133 }
134
135 @Override
136 public byte[] getTBSCertificate() throws CertificateEncodingException {
137 return unwrap().getTBSCertificate();
138 }
139
140 @Override
141 public byte[] getSignature() {
142 return unwrap().getSignature();
143 }
144
145 @Override
146 public String getSigAlgName() {
147 return unwrap().getSigAlgName();
148 }
149
150 @Override
151 public String getSigAlgOID() {
152 return unwrap().getSigAlgOID();
153 }
154
155 @Override
156 public byte[] getSigAlgParams() {
157 return unwrap().getSigAlgParams();
158 }
159
160 @Override
161 public boolean[] getIssuerUniqueID() {
162 return unwrap().getIssuerUniqueID();
163 }
164
165 @Override
166 public boolean[] getSubjectUniqueID() {
167 return unwrap().getSubjectUniqueID();
168 }
169
170 @Override
171 public boolean[] getKeyUsage() {
172 return unwrap().getKeyUsage();
173 }
174
175 @Override
176 public int getBasicConstraints() {
177 return unwrap().getBasicConstraints();
178 }
179
180 @Override
181 public byte[] getEncoded() {
182 return bytes.clone();
183 }
184
185 @Override
186 public void verify(PublicKey key)
187 throws CertificateException, NoSuchAlgorithmException,
188 InvalidKeyException, NoSuchProviderException, SignatureException {
189 unwrap().verify(key);
190 }
191
192 @Override
193 public void verify(PublicKey key, String sigProvider)
194 throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,
195 NoSuchProviderException, SignatureException {
196 unwrap().verify(key, sigProvider);
197 }
198
199 @Override
200 public String toString() {
201 return unwrap().toString();
202 }
203
204 @Override
205 public PublicKey getPublicKey() {
206 return unwrap().getPublicKey();
207 }
208
209 @Override
210 public boolean hasUnsupportedCriticalExtension() {
211 return unwrap().hasUnsupportedCriticalExtension();
212 }
213
214 @Override
215 public Set<String> getCriticalExtensionOIDs() {
216 return unwrap().getCriticalExtensionOIDs();
217 }
218
219 @Override
220 public Set<String> getNonCriticalExtensionOIDs() {
221 return unwrap().getNonCriticalExtensionOIDs();
222 }
223
224 @Override
225 public byte[] getExtensionValue(String oid) {
226 return unwrap().getExtensionValue(oid);
227 }
228
229 private X509Certificate unwrap() {
230 X509Certificate wrapped = this.wrapped;
231 if (wrapped == null) {
232 try {
233 wrapped = this.wrapped = (X509Certificate) X509_CERT_FACTORY.generateCertificate(
234 new ByteArrayInputStream(bytes));
235 } catch (CertificateException e) {
236 throw new IllegalStateException(e);
237 }
238 }
239 return wrapped;
240 }
241 }