1 package es.caib.signatura.impl;
2
3 import java.io.*;
4 import java.lang.reflect.Constructor;
5 import java.security.InvalidKeyException;
6 import java.security.NoSuchAlgorithmException;
7 import java.security.NoSuchProviderException;
8 import java.security.SignatureException;
9 import java.security.cert.CertificateException;
10 import java.security.cert.CertificateExpiredException;
11 import java.security.cert.CertificateNotYetValidException;
12 import java.security.cert.X509Certificate;
13 import java.util.Collection;
14 import java.util.Iterator;
15 import java.util.List;
16
17 import es.caib.signatura.api.CertificateVerifyException;
18 import es.caib.signatura.api.ParsedCertificate;
19 import es.caib.signatura.api.SignatureProviderException;
20 import es.caib.signatura.api.SignatureVerifyException;
21 import es.caib.signatura.api.Certificate;
22
23
24
25
26 public class CertificateImpl implements Certificate {
27 private X509Certificate[] certificateChain = null;
28
29
30
31
32
33
34
35 public CertificateImpl(X509Certificate[] certificateChain){
36 this.certificateChain = certificateChain;
37 }
38
39
40
41
42 public String getCertCaName(){
43 if(certificateChain == null || certificateChain.length == 0){
44 throw new Error("The certificate chain cannot be found.");
45 }
46 return certificateChain[certificateChain.length-1].getSubjectX500Principal().getName();
47 }
48
49
50
51
52 public String getCertSubjectCommonName(){
53 ParsedCertificate Parsed = this.getParsedCertificate();
54 return(Parsed.getName());
55 }
56
57
58
59
60 public String getCertSubjectAlternativeNames(){
61 StringBuffer altNameSB = new StringBuffer("");
62 String altNameString = null;
63 try {
64 Collection generalNames = certificateChain[0].getSubjectAlternativeNames();
65 Iterator itr = generalNames.iterator();
66 while (itr.hasNext()) {
67 List list = (List) itr.next();
68
69 int tagNo = ((Integer) list.get(0)).intValue();
70 switch (tagNo) {
71 case 0:
72 altNameSB.append("," + "otherName=");
73 break;
74
75 case 1:
76 altNameSB.append("," + "rfc822Name=");
77 break;
78
79 case 2:
80 altNameSB.append("," + "dNSName=");
81 break;
82
83 case 3:
84 altNameSB.append("," + "x400Address=");
85 break;
86
87 case 4:
88 altNameSB.append("," + "directoryName=");
89 break;
90
91 case 5:
92 altNameSB.append("," + "ediPartyName=");
93 break;
94
95 case 6:
96 altNameSB.append("," + "uniformResourceIdentifier=");
97 break;
98
99 case 7:
100 altNameSB.append("," + "iPAddress=");
101 break;
102
103 case 8:
104 altNameSB.append("," + "registeredID=");
105 break;
106
107 }
108 altNameSB.append(list.get(1).toString());
109
110
111 if (altNameSB.length() > 0) {
112 altNameString = altNameSB.substring(1, altNameSB.length());
113 }
114
115 }
116 }
117
118 catch (Exception ex) {
119 return null;
120 }
121
122 return altNameString;
123 }
124
125
126
127
128
129 public X509Certificate getCert(){
130 return certificateChain[0];
131 }
132
133
134
135
136 public ParsedCertificate getParsedCertificate(){
137 try {
138 ClassLoader cl = ClassLoaderFactory.getFactory().getMasterClassLoader();
139 Class clazz = cl .loadClass( "es.caib.signatura.provider.impl.common.ParsedCertificatImpl" );
140 Constructor constructor = clazz.getConstructor(new Class[] {certificateChain.getClass(), Boolean.TYPE});
141 ParsedCertificate parsed = (ParsedCertificate) constructor.newInstance(new Object [] {certificateChain, new Boolean(false)});
142 return new ParsedCertificateProxy (parsed);
143 } catch (Exception e) {
144 throw new RuntimeException(e);
145 }
146 }
147
148
149
150
151 public boolean verify()
152 throws IOException, CertificateVerifyException{
153 boolean isValid = true;
154 isValid = isValid && verifyCertificateChain();
155 if(!isValid){
156
157
158
159 invertCertificateChain();
160 isValid = isValid && verifyCertificateChain();
161 if(!isValid){
162
163
164
165
166 invertCertificateChain();
167 }
168 }
169 return isValid;
170 }
171
172
173
174
175 private void invertCertificateChain(){
176 for(int i = 0;i < certificateChain.length / 2;i++){
177 X509Certificate temporalCertificate = certificateChain[certificateChain.length - 1 - i];
178 certificateChain[certificateChain.length - 1 - i] = certificateChain[i];
179 certificateChain[i] = temporalCertificate;
180 }
181 }
182
183
184
185
186 private boolean verifyCertificateChain()
187 throws IOException, CertificateVerifyException{
188 boolean isValid = true;
189
190
191
192 for(int i = 0;i < certificateChain.length && isValid;i++){
193 try {
194 certificateChain[i].checkValidity();
195
196 } catch (CertificateExpiredException cee) {
197 System.out.println("CMSSignature Certificat rebutjat, el certificat ha caducat.");
198 isValid = false;
199 } catch (CertificateNotYetValidException cve) {
200 System.out.println("CMSSignature Certificat rebutjat, el certificat encara no és vàlid.");
201 isValid = false;
202 }
203 }
204
205
206
207 for(int i = 0;(i < certificateChain.length - 1) && isValid;i++){
208 try {
209 certificateChain[i].verify(certificateChain[i + 1].getPublicKey());
210 } catch (InvalidKeyException e) {
211 isValid = false;
212 } catch (CertificateException e) {
213 isValid = false;
214 } catch (NoSuchAlgorithmException e) {
215 throw new CertificateVerifyException(e);
216 } catch (NoSuchProviderException e) {
217 throw new CertificateVerifyException(e);
218 } catch (SignatureException e) {
219 isValid = false;
220 }
221 }
222
223
224
225 try{
226 isValid = isValid && verifyCertificateWebServices(certificateChain);
227 }catch(Exception e){
228 throw new CertificateVerifyException(e);
229 }
230 return isValid;
231 }
232
233
234
235
236 private boolean verifyCertificateWebServices(X509Certificate[] certificateChain)throws CertificateVerifyException{
237
238 return true;
239
240
241
242
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303 }