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