1   /* $RCSfile: JHBCI.java,v $
2    * $Revision: 1.14 $
3    * $Date: 2003/10/04 19:18:38 $
4    * $Author: uwe_guenther $
5    * $State: Exp $
6    *
7    * Created on July 15, 2001, 1:20 PM
8    *
9    * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10   *
11   * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12   * ServiceProvider is a library, written in JavaTM, that should be
13   * used in HBCI banking applications (clients and may be servers),
14   * to do cryptographic operations.
15   *
16   * The jhbci library is free software; you can redistribute it and/or
17   * modify it under the terms of the GNU Lesser General Public
18   * License as published by the Free Software Foundation; either
19   * version 2.1 of the License, or (at your option) any later version.
20   *
21   * The jhbci library is distributed in the hope that it will be useful,
22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   * Lesser General Public License for more details.
25   *
26   * You should have received a copy of the GNU Lesser General Public
27   * License along with this library; if not, write to the Free Software
28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29   *
30   */
31  
32  package de.cscc.crypto.provider;
33  
34  import java.io.ByteArrayInputStream;
35  import java.io.IOException;
36  import java.io.InputStream;
37  import java.net.JarURLConnection;
38  import java.net.MalformedURLException;
39  import java.net.URL;
40  import java.security.AccessController;
41  import java.security.CodeSource;
42  import java.security.PrivilegedAction;
43  import java.security.PrivilegedActionException;
44  import java.security.PrivilegedExceptionAction;
45  import java.security.Provider;
46  import java.security.cert.Certificate;
47  import java.security.cert.CertificateException;
48  import java.security.cert.CertificateFactory;
49  import java.security.cert.X509Certificate;
50  import java.util.Enumeration;
51  import java.util.Vector;
52  import java.util.jar.JarEntry;
53  import java.util.jar.JarFile;
54  import java.util.jar.Manifest;
55  
56  
57  /**
58   * JHBCI - the Provider Class.
59   *
60   * @author  <a href=mailto:uwe@cscc.de>Uwe G&uuml;nther</a>
61   * @version $Revision: 1.14 $
62   */
63  public final class JHBCI extends Provider {
64      
65      /** Info of JHBCI Provider. */
66      private static final String INFO =
67      "JHBCI Provider, by Uwe Guenther <uwe@cscc.de>";
68      
69      /** Provider version. */
70      private static double VERSION;
71      
72      /** Provider name. */
73      private static final String NAME = "JHBCI";
74      
75      /** Initialize the double Version variable with Ant version TAGS. */
76      {
77          try {
78              JHBCI.VERSION = Double.parseDouble("0.06");
79          } catch (NumberFormatException e) {
80              JHBCI.VERSION = 0.0;
81          }
82      }
83      
84      /** Creates new JHBCI provider class. */
85      public JHBCI() {
86          
87          //name, version, info about the provider
88          super(JHBCI.NAME, JHBCI.VERSION, JHBCI.INFO);
89          
90          AccessController.doPrivileged(new PrivilegedAction() {
91              public Object run() {
92                  
93                  //////
94                  //
95                  // DES1Key, DESede2Key, DESede3Key
96                  //
97                  // Cipher, SecretKeyFactory, KeyGenerator
98                  //
99                  //////
100                 
101                 //Cipher DES1Key
102                 put("Cipher.DES1Key",
103                 "de.cscc.crypto.provider.DES1KeyCipherEngine");
104                 //put("Alg.Alias.Cipher.DES", "DES1Key");
105                 
106                 //Cipher DESede2Key
107                 put("Cipher.DESede2Key",
108                 "de.cscc.crypto.provider.DESede2KeyCipherEngine");
109                 
110                 //Cipher DESede3Key
111                 put("Cipher.DESede3Key",
112                 "de.cscc.crypto.provider.DESede3KeyCipherEngine");
113                 
114                 //SecretKeyFactory DES1Key
115                 put("SecretKeyFactory.DES1Key",
116                 "de.cscc.crypto.provider.DES1KeySecretKeyFactoryEngine");
117                 
118                 //SecretKeyFactory DESede2Key
119                 put("SecretKeyFactory.DESede2Key",
120                 "de.cscc.crypto.provider.DESede2KeySecretKeyFactoryEngine");
121                 
122                 //SecretKeyFactory DESede3Key
123                 put("SecretKeyFactory.DESede3Key",
124                 "de.cscc.crypto.provider.DESede3KeySecretKeyFactoryEngine");
125                 
126                 //KeyGenerator DES1Key
127                 put("KeyGenerator.DES1Key", 
128                 "de.cscc.crypto.provider.DES1KeySecretKeyGeneratorEngine");
129                 
130                 //KeyGenerator DESede2Key
131                 put("KeyGenerator.DESede2Key",
132                 "de.cscc.crypto.provider.DESede2KeySecretKeyGeneratorEngine");
133                 
134                 //KeyGenerator DESede3Key
135                 put("KeyGenerator.DESede3Key",
136                 "de.cscc.crypto.provider.DESede3KeySecretKeyGeneratorEngine");
137       
138                 
139                 //////
140                 //
141                 // RSA
142                 //
143                 // Cipher, Signature, KeyFactory, KeyPairGenerator
144                 //
145                 //////                
146                 
147                 //Cipher RSA
148                 put("Cipher.RSA",
149                 "de.cscc.crypto.provider.RSACipherEngine");
150 
151                 //Signature ISO9796-1WithRSA
152                 put("Signature.ISO9796-1WithRSA",
153                 "de.cscc.crypto.provider.ISO9796Part1WithRSASignatureEngine"); 
154 
155                 //Signature RIPEMD160WithISO9796-1AndRSA
156                 put("Signature.RIPEMD160WithISO9796-1AndRSA",
157                 "de.cscc.crypto.provider.RIPEMD160WithISO9796Part1AndRSASignatureEngine");                
158                 
159                 //KeyFactory RSA
160                 put("KeyFactory.RSA",
161                 "de.cscc.crypto.provider.RSAKeyFactoryEngine");                
162                 
163                 //KeyPairGenerator RSA
164                 put("KeyPairGenerator.RSA",
165                 "de.cscc.crypto.provider.RSAKeyPairGeneratorEngine");
166                 
167       
168                 //////
169                 //
170                 // RIPEMD160
171                 //
172                 // MessageDigest
173                 //
174                 //////                
175                                
176                 //MessageDigest RIPEMD160
177                 put("MessageDigest.RIPEMD160",
178                 "de.cscc.crypto.provider.RIPEMD160MessageDigestEngine");
179 
180                 return null;
181             }
182         });
183     }
184 
185 
186     
187     /*
188      * At these point follows only static Self Integrity Checking Stuff.
189      * You have to put the following code in any JCE SPI-Class in this
190      * Provider: 
191      *
192      * <pre>
193      * if (JHBCI.selfIntegrityChecking() == false) {
194      *     throw new SecurityException("JHBCI-Provider is tampered.");
195      * }
196      * </pre>
197      *
198      * Note: That is only necessary for JCE SPI-Classes not for JCA SPI-Classes.
199      */
200     
201     /**
202      * For efficiency, keep track of whether or not the provider
203      * has already been verified to avoid doing it multiple times
204      * unnecessarily.
205      */
206     private static boolean verifiedSelfIntegrity = false;
207 
208     /** 
209      * Provider's signing cert which is used to sign the jar. 
210      */
211     private static X509Certificate providerCert = null;
212 
213     /** Raw bytes of provider's own code signing cert.
214      *  This is the Guenther-Elektronik JCE cert. 
215      */
216     private static final byte[] bytesOfProviderCert = {
217         (byte) 0x30, (byte) 0x82, (byte) 0x03, (byte) 0xa1,
218         (byte) 0x30, (byte) 0x82, (byte) 0x03, (byte) 0x5f,
219         (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
220         (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x17,
221         (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x07,
222         (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce,
223         (byte) 0x38, (byte) 0x04, (byte) 0x03, (byte) 0x05,
224         (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x90,
225         (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
226         (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
227         (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55,
228         (byte) 0x53, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
229         (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
230         (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02,
231         (byte) 0x43, (byte) 0x41, (byte) 0x31, (byte) 0x12,
232         (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x03,
233         (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13,
234         (byte) 0x09, (byte) 0x50, (byte) 0x61, (byte) 0x6c,
235         (byte) 0x6f, (byte) 0x20, (byte) 0x41, (byte) 0x6c,
236         (byte) 0x74, (byte) 0x6f, (byte) 0x31, (byte) 0x1d,
237         (byte) 0x30, (byte) 0x1b, (byte) 0x06, (byte) 0x03,
238         (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13,
239         (byte) 0x14, (byte) 0x53, (byte) 0x75, (byte) 0x6e,
240         (byte) 0x20, (byte) 0x4d, (byte) 0x69, (byte) 0x63,
241         (byte) 0x72, (byte) 0x6f, (byte) 0x73, (byte) 0x79,
242         (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x6d,
243         (byte) 0x73, (byte) 0x20, (byte) 0x49, (byte) 0x6e,
244         (byte) 0x63, (byte) 0x31, (byte) 0x23, (byte) 0x30,
245         (byte) 0x21, (byte) 0x06, (byte) 0x03, (byte) 0x55,
246         (byte) 0x04, (byte) 0x0b, (byte) 0x13, (byte) 0x1a,
247         (byte) 0x4a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
248         (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66,
249         (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72,
250         (byte) 0x65, (byte) 0x20, (byte) 0x43, (byte) 0x6f,
251         (byte) 0x64, (byte) 0x65, (byte) 0x20, (byte) 0x53,
252         (byte) 0x69, (byte) 0x67, (byte) 0x6e, (byte) 0x69,
253         (byte) 0x6e, (byte) 0x67, (byte) 0x31, (byte) 0x1c,
254         (byte) 0x30, (byte) 0x1a, (byte) 0x06, (byte) 0x03,
255         (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x13,
256         (byte) 0x13, (byte) 0x4a, (byte) 0x43, (byte) 0x45,
257         (byte) 0x20, (byte) 0x43, (byte) 0x6f, (byte) 0x64,
258         (byte) 0x65, (byte) 0x20, (byte) 0x53, (byte) 0x69,
259         (byte) 0x67, (byte) 0x6e, (byte) 0x69, (byte) 0x6e,
260         (byte) 0x67, (byte) 0x20, (byte) 0x43, (byte) 0x41,
261         (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d,
262         (byte) 0x30, (byte) 0x31, (byte) 0x30, (byte) 0x36,
263         (byte) 0x31, (byte) 0x32, (byte) 0x31, (byte) 0x35,
264         (byte) 0x34, (byte) 0x30, (byte) 0x34, (byte) 0x39,
265         (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x30,
266         (byte) 0x36, (byte) 0x30, (byte) 0x36, (byte) 0x31,
267         (byte) 0x31, (byte) 0x31, (byte) 0x35, (byte) 0x34,
268         (byte) 0x30, (byte) 0x34, (byte) 0x39, (byte) 0x5a,
269         (byte) 0x30, (byte) 0x62, (byte) 0x31, (byte) 0x1d,
270         (byte) 0x30, (byte) 0x1b, (byte) 0x06, (byte) 0x03,
271         (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13,
272         (byte) 0x14, (byte) 0x53, (byte) 0x75, (byte) 0x6e,
273         (byte) 0x20, (byte) 0x4d, (byte) 0x69, (byte) 0x63,
274         (byte) 0x72, (byte) 0x6f, (byte) 0x73, (byte) 0x79,
275         (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x6d,
276         (byte) 0x73, (byte) 0x20, (byte) 0x49, (byte) 0x6e,
277         (byte) 0x63, (byte) 0x31, (byte) 0x23, (byte) 0x30,
278         (byte) 0x21, (byte) 0x06, (byte) 0x03, (byte) 0x55,
279         (byte) 0x04, (byte) 0x0b, (byte) 0x13, (byte) 0x1a,
280         (byte) 0x4a, (byte) 0x61, (byte) 0x76, (byte) 0x61,
281         (byte) 0x20, (byte) 0x53, (byte) 0x6f, (byte) 0x66,
282         (byte) 0x74, (byte) 0x77, (byte) 0x61, (byte) 0x72,
283         (byte) 0x65, (byte) 0x20, (byte) 0x43, (byte) 0x6f,
284         (byte) 0x64, (byte) 0x65, (byte) 0x20, (byte) 0x53,
285         (byte) 0x69, (byte) 0x67, (byte) 0x6e, (byte) 0x69,
286         (byte) 0x6e, (byte) 0x67, (byte) 0x31, (byte) 0x1c,
287         (byte) 0x30, (byte) 0x1a, (byte) 0x06, (byte) 0x03,
288         (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x13,
289         (byte) 0x13, (byte) 0x47, (byte) 0x75, (byte) 0x65,
290         (byte) 0x6e, (byte) 0x74, (byte) 0x68, (byte) 0x65,
291         (byte) 0x72, (byte) 0x2d, (byte) 0x45, (byte) 0x6c,
292         (byte) 0x65, (byte) 0x6b, (byte) 0x74, (byte) 0x72,
293         (byte) 0x6f, (byte) 0x6e, (byte) 0x69, (byte) 0x6b,
294         (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xb7,
295         (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2c,
296         (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86,
297         (byte) 0x48, (byte) 0xce, (byte) 0x38, (byte) 0x04,
298         (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01,
299         (byte) 0x1f, (byte) 0x02, (byte) 0x81, (byte) 0x81,
300         (byte) 0x00, (byte) 0xfd, (byte) 0x7f, (byte) 0x53,
301         (byte) 0x81, (byte) 0x1d, (byte) 0x75, (byte) 0x12,
302         (byte) 0x29, (byte) 0x52, (byte) 0xdf, (byte) 0x4a,
303         (byte) 0x9c, (byte) 0x2e, (byte) 0xec, (byte) 0xe4,
304         (byte) 0xe7, (byte) 0xf6, (byte) 0x11, (byte) 0xb7,
305         (byte) 0x52, (byte) 0x3c, (byte) 0xef, (byte) 0x44,
306         (byte) 0x00, (byte) 0xc3, (byte) 0x1e, (byte) 0x3f,
307         (byte) 0x80, (byte) 0xb6, (byte) 0x51, (byte) 0x26,
308         (byte) 0x69, (byte) 0x45, (byte) 0x5d, (byte) 0x40,
309         (byte) 0x22, (byte) 0x51, (byte) 0xfb, (byte) 0x59,
310         (byte) 0x3d, (byte) 0x8d, (byte) 0x58, (byte) 0xfa,
311         (byte) 0xbf, (byte) 0xc5, (byte) 0xf5, (byte) 0xba,
312         (byte) 0x30, (byte) 0xf6, (byte) 0xcb, (byte) 0x9b,
313         (byte) 0x55, (byte) 0x6c, (byte) 0xd7, (byte) 0x81,
314         (byte) 0x3b, (byte) 0x80, (byte) 0x1d, (byte) 0x34,
315         (byte) 0x6f, (byte) 0xf2, (byte) 0x66, (byte) 0x60,
316         (byte) 0xb7, (byte) 0x6b, (byte) 0x99, (byte) 0x50,
317         (byte) 0xa5, (byte) 0xa4, (byte) 0x9f, (byte) 0x9f,
318         (byte) 0xe8, (byte) 0x04, (byte) 0x7b, (byte) 0x10,
319         (byte) 0x22, (byte) 0xc2, (byte) 0x4f, (byte) 0xbb,
320         (byte) 0xa9, (byte) 0xd7, (byte) 0xfe, (byte) 0xb7,
321         (byte) 0xc6, (byte) 0x1b, (byte) 0xf8, (byte) 0x3b,
322         (byte) 0x57, (byte) 0xe7, (byte) 0xc6, (byte) 0xa8,
323         (byte) 0xa6, (byte) 0x15, (byte) 0x0f, (byte) 0x04,
324         (byte) 0xfb, (byte) 0x83, (byte) 0xf6, (byte) 0xd3,
325         (byte) 0xc5, (byte) 0x1e, (byte) 0xc3, (byte) 0x02,
326         (byte) 0x35, (byte) 0x54, (byte) 0x13, (byte) 0x5a,
327         (byte) 0x16, (byte) 0x91, (byte) 0x32, (byte) 0xf6,
328         (byte) 0x75, (byte) 0xf3, (byte) 0xae, (byte) 0x2b,
329         (byte) 0x61, (byte) 0xd7, (byte) 0x2a, (byte) 0xef,
330         (byte) 0xf2, (byte) 0x22, (byte) 0x03, (byte) 0x19,
331         (byte) 0x9d, (byte) 0xd1, (byte) 0x48, (byte) 0x01,
332         (byte) 0xc7, (byte) 0x02, (byte) 0x15, (byte) 0x00,
333         (byte) 0x97, (byte) 0x60, (byte) 0x50, (byte) 0x8f,
334         (byte) 0x15, (byte) 0x23, (byte) 0x0b, (byte) 0xcc,
335         (byte) 0xb2, (byte) 0x92, (byte) 0xb9, (byte) 0x82,
336         (byte) 0xa2, (byte) 0xeb, (byte) 0x84, (byte) 0x0b,
337         (byte) 0xf0, (byte) 0x58, (byte) 0x1c, (byte) 0xf5,
338         (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00,
339         (byte) 0xf7, (byte) 0xe1, (byte) 0xa0, (byte) 0x85,
340         (byte) 0xd6, (byte) 0x9b, (byte) 0x3d, (byte) 0xde,
341         (byte) 0xcb, (byte) 0xbc, (byte) 0xab, (byte) 0x5c,
342         (byte) 0x36, (byte) 0xb8, (byte) 0x57, (byte) 0xb9,
343         (byte) 0x79, (byte) 0x94, (byte) 0xaf, (byte) 0xbb,
344         (byte) 0xfa, (byte) 0x3a, (byte) 0xea, (byte) 0x82,
345         (byte) 0xf9, (byte) 0x57, (byte) 0x4c, (byte) 0x0b,
346         (byte) 0x3d, (byte) 0x07, (byte) 0x82, (byte) 0x67,
347         (byte) 0x51, (byte) 0x59, (byte) 0x57, (byte) 0x8e,
348         (byte) 0xba, (byte) 0xd4, (byte) 0x59, (byte) 0x4f,
349         (byte) 0xe6, (byte) 0x71, (byte) 0x07, (byte) 0x10,
350         (byte) 0x81, (byte) 0x80, (byte) 0xb4, (byte) 0x49,
351         (byte) 0x16, (byte) 0x71, (byte) 0x23, (byte) 0xe8,
352         (byte) 0x4c, (byte) 0x28, (byte) 0x16, (byte) 0x13,
353         (byte) 0xb7, (byte) 0xcf, (byte) 0x09, (byte) 0x32,
354         (byte) 0x8c, (byte) 0xc8, (byte) 0xa6, (byte) 0xe1,
355         (byte) 0x3c, (byte) 0x16, (byte) 0x7a, (byte) 0x8b,
356         (byte) 0x54, (byte) 0x7c, (byte) 0x8d, (byte) 0x28,
357         (byte) 0xe0, (byte) 0xa3, (byte) 0xae, (byte) 0x1e,
358         (byte) 0x2b, (byte) 0xb3, (byte) 0xa6, (byte) 0x75,
359         (byte) 0x91, (byte) 0x6e, (byte) 0xa3, (byte) 0x7f,
360         (byte) 0x0b, (byte) 0xfa, (byte) 0x21, (byte) 0x35,
361         (byte) 0x62, (byte) 0xf1, (byte) 0xfb, (byte) 0x62,
362         (byte) 0x7a, (byte) 0x01, (byte) 0x24, (byte) 0x3b,
363         (byte) 0xcc, (byte) 0xa4, (byte) 0xf1, (byte) 0xbe,
364         (byte) 0xa8, (byte) 0x51, (byte) 0x90, (byte) 0x89,
365         (byte) 0xa8, (byte) 0x83, (byte) 0xdf, (byte) 0xe1,
366         (byte) 0x5a, (byte) 0xe5, (byte) 0x9f, (byte) 0x06,
367         (byte) 0x92, (byte) 0x8b, (byte) 0x66, (byte) 0x5e,
368         (byte) 0x80, (byte) 0x7b, (byte) 0x55, (byte) 0x25,
369         (byte) 0x64, (byte) 0x01, (byte) 0x4c, (byte) 0x3b,
370         (byte) 0xfe, (byte) 0xcf, (byte) 0x49, (byte) 0x2a,
371         (byte) 0x03, (byte) 0x81, (byte) 0x84, (byte) 0x00,
372         (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x75,
373         (byte) 0xc5, (byte) 0xc4, (byte) 0xdf, (byte) 0xc7,
374         (byte) 0x0f, (byte) 0x37, (byte) 0xb9, (byte) 0x43,
375         (byte) 0x87, (byte) 0xec, (byte) 0x7a, (byte) 0xe0,
376         (byte) 0x5e, (byte) 0x91, (byte) 0xc2, (byte) 0x39,
377         (byte) 0x7a, (byte) 0xf1, (byte) 0xc8, (byte) 0x22,
378         (byte) 0x11, (byte) 0x74, (byte) 0x91, (byte) 0x9c,
379         (byte) 0x8a, (byte) 0xd6, (byte) 0xcb, (byte) 0x93,
380         (byte) 0xc0, (byte) 0x82, (byte) 0xe6, (byte) 0xcb,
381         (byte) 0x3d, (byte) 0x1c, (byte) 0xf9, (byte) 0x76,
382         (byte) 0xe1, (byte) 0xfb, (byte) 0xb2, (byte) 0x03,
383         (byte) 0xc8, (byte) 0xba, (byte) 0x53, (byte) 0x8f,
384         (byte) 0xe3, (byte) 0xba, (byte) 0xfa, (byte) 0xa1,
385         (byte) 0x05, (byte) 0x49, (byte) 0x8f, (byte) 0xcc,
386         (byte) 0x4d, (byte) 0x01, (byte) 0x2c, (byte) 0x95,
387         (byte) 0xa9, (byte) 0x78, (byte) 0xda, (byte) 0x06,
388         (byte) 0xb9, (byte) 0x51, (byte) 0x82, (byte) 0x58,
389         (byte) 0x42, (byte) 0x40, (byte) 0x6c, (byte) 0xf4,
390         (byte) 0x8f, (byte) 0xd6, (byte) 0xe9, (byte) 0x14,
391         (byte) 0x7f, (byte) 0x14, (byte) 0x41, (byte) 0x6d,
392         (byte) 0x02, (byte) 0x83, (byte) 0x19, (byte) 0xa6,
393         (byte) 0x7e, (byte) 0x6e, (byte) 0x71, (byte) 0xeb,
394         (byte) 0xd6, (byte) 0x08, (byte) 0x0a, (byte) 0x70,
395         (byte) 0x3b, (byte) 0x32, (byte) 0x65, (byte) 0x7b,
396         (byte) 0xf3, (byte) 0x6a, (byte) 0x31, (byte) 0x07,
397         (byte) 0x41, (byte) 0xbb, (byte) 0xc8, (byte) 0xd6,
398         (byte) 0x96, (byte) 0x26, (byte) 0x28, (byte) 0xd9,
399         (byte) 0xc2, (byte) 0x84, (byte) 0x58, (byte) 0x82,
400         (byte) 0x72, (byte) 0xa0, (byte) 0x2c, (byte) 0x8a,
401         (byte) 0x33, (byte) 0xd9, (byte) 0x0b, (byte) 0xa9,
402         (byte) 0x79, (byte) 0xfe, (byte) 0x77, (byte) 0x57,
403         (byte) 0xf4, (byte) 0xd2, (byte) 0xc8, (byte) 0x6a,
404         (byte) 0x99, (byte) 0x36, (byte) 0x36, (byte) 0xa3,
405         (byte) 0x76, (byte) 0x30, (byte) 0x74, (byte) 0x30,
406         (byte) 0x11, (byte) 0x06, (byte) 0x09, (byte) 0x60,
407         (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x86,
408         (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x01,
409         (byte) 0x04, (byte) 0x04, (byte) 0x03, (byte) 0x02,
410         (byte) 0x00, (byte) 0x87, (byte) 0x30, (byte) 0x0e,
411         (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
412         (byte) 0x0f, (byte) 0x01, (byte) 0x01, (byte) 0xff,
413         (byte) 0x04, (byte) 0x04, (byte) 0x03, (byte) 0x02,
414         (byte) 0x01, (byte) 0xc6, (byte) 0x30, (byte) 0x1d,
415         (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
416         (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04,
417         (byte) 0x14, (byte) 0xbe, (byte) 0xbe, (byte) 0xc6,
418         (byte) 0x10, (byte) 0xba, (byte) 0xd5, (byte) 0x7f,
419         (byte) 0x04, (byte) 0x81, (byte) 0x1a, (byte) 0x69,
420         (byte) 0x35, (byte) 0x34, (byte) 0xe7, (byte) 0x61,
421         (byte) 0x53, (byte) 0xea, (byte) 0x93, (byte) 0xc9,
422         (byte) 0x7b, (byte) 0x30, (byte) 0x0f, (byte) 0x06,
423         (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13,
424         (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x04,
425         (byte) 0x05, (byte) 0x30, (byte) 0x03, (byte) 0x01,
426         (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x1f,
427         (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
428         (byte) 0x23, (byte) 0x04, (byte) 0x18, (byte) 0x30,
429         (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x65,
430         (byte) 0xe2, (byte) 0xf4, (byte) 0x86, (byte) 0xc9,
431         (byte) 0xd3, (byte) 0x4e, (byte) 0xf0, (byte) 0x91,
432         (byte) 0x4e, (byte) 0x58, (byte) 0xa2, (byte) 0x6a,
433         (byte) 0xf5, (byte) 0xd8, (byte) 0x78, (byte) 0x5a,
434         (byte) 0x9a, (byte) 0xc1, (byte) 0xa6, (byte) 0x30,
435         (byte) 0x0b, (byte) 0x06, (byte) 0x07, (byte) 0x2a,
436         (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
437         (byte) 0x04, (byte) 0x03, (byte) 0x05, (byte) 0x00,
438         (byte) 0x03, (byte) 0x2f, (byte) 0x00, (byte) 0x30,
439         (byte) 0x2c, (byte) 0x02, (byte) 0x14, (byte) 0x0e,
440         (byte) 0xbb, (byte) 0x4c, (byte) 0x61, (byte) 0x80,
441         (byte) 0xbf, (byte) 0x48, (byte) 0x48, (byte) 0x0e,
442         (byte) 0x62, (byte) 0xf4, (byte) 0x0a, (byte) 0xdf,
443         (byte) 0x17, (byte) 0xe3, (byte) 0x24, (byte) 0x86,
444         (byte) 0x5d, (byte) 0x0d, (byte) 0x09, (byte) 0x02,
445         (byte) 0x14, (byte) 0x54, (byte) 0x2f, (byte) 0xf7,
446         (byte) 0xcb, (byte) 0x7f, (byte) 0x53, (byte) 0x00,
447         (byte) 0x54, (byte) 0x47, (byte) 0x38, (byte) 0x28,
448         (byte) 0x27, (byte) 0x98, (byte) 0xcd, (byte) 0xfb,
449         (byte) 0x5d, (byte) 0x2e, (byte) 0xcc, (byte) 0xee,
450         (byte) 0x3f    
451     };
452 
453     /** 
454      * Perform self-integrity checking. Call this method in all 
455      * the constructors of your SPI implementation classes.
456      * NOTE: The following implementation assumes that all
457      * your provider implementation is packaged inside ONE jar. 
458      */
459     static final synchronized boolean selfIntegrityChecking() {
460         if (verifiedSelfIntegrity) {
461             return true;
462         }
463 
464         URL providerURL =
465             (URL) AccessController.doPrivileged(new PrivilegedAction() {
466             public Object run() {
467                 CodeSource cs =
468                     JHBCI.class.getProtectionDomain().getCodeSource();
469                 return cs.getLocation();
470             }
471         });
472 
473         if (providerURL == null) {
474             return false;
475         }
476 
477         // Open a connnection to the provider JAR file
478         JarVerifier jv = new JarVerifier(providerURL);
479 
480         // Make sure that the provider JAR file is signed with 
481         // provider's own signing certificate.
482         try {
483             if (providerCert == null) {
484                 providerCert = setupProviderCert();
485             }
486             jv.verify(providerCert);
487         } catch (Exception e) {
488             return false;
489         }
490 
491         verifiedSelfIntegrity = true;
492         
493         return verifiedSelfIntegrity;
494     }
495 
496     /*
497      * Set up 'providerCert' with the certificate bytes.
498      */
499     private static X509Certificate setupProviderCert()
500         throws IOException, CertificateException {
501         CertificateFactory cf = CertificateFactory.getInstance("X.509");
502         ByteArrayInputStream inStream =
503             new ByteArrayInputStream(bytesOfProviderCert);
504         X509Certificate cert =
505             (X509Certificate) cf.generateCertificate(inStream);
506         inStream.close();
507         return cert;
508     }
509 
510     public static class JarVerifier {
511 
512         private URL jarURL = null;
513         private JarFile jarFile = null;
514 
515         JarVerifier(URL jarURL) {
516             this.jarURL = jarURL;
517         }
518 
519         /**
520          * Retrive the jar file from the specified url.
521          */
522         private JarFile retrieveJarFileFromURL(URL url)
523             throws PrivilegedActionException, MalformedURLException {
524             JarFile jf = null;
525 
526             // Prep the url with the appropriate protocol.
527             jarURL =
528                 url.getProtocol().equalsIgnoreCase("jar")
529                     ? url
530                     : new URL("jar:" + url.toString() + "!/");
531             // Retrieve the jar file using JarURLConnection
532             jf =
533                 (
534                     JarFile) AccessController
535                         .doPrivileged(new PrivilegedExceptionAction() {
536                 public Object run() throws Exception {
537                     JarURLConnection conn =
538                         (JarURLConnection) jarURL.openConnection();
539                     // Always get a fresh copy, so we don't have to
540                     // worry about the stale file handle when the
541                     // cached jar is closed by some other application.
542                     conn.setUseCaches(false);
543                     return conn.getJarFile();
544                 }
545             });
546             return jf;
547         }
548 
549         /**
550          * First, retrieve the jar file from the URL passed in constructor.
551          * Then, compare it to the expected X509Certificate.
552          * If everything went well and the certificates are the same, no 
553          * exception is thrown.
554          */
555         public void verify(X509Certificate targetCert) throws IOException {
556             // Sanity checking
557             if (targetCert == null) {
558                 throw new SecurityException("Provider certificate is invalid");
559             }
560 
561             try {
562                 if (jarFile == null) {
563                     jarFile = retrieveJarFileFromURL(jarURL);
564                 }
565             } catch (Exception ex) {
566                 SecurityException se = new SecurityException();
567                 se.initCause(ex);
568                 throw se;
569             }
570 
571             Vector entriesVec = new Vector();
572 
573             // Ensure the jar file is signed.
574             Manifest man = jarFile.getManifest();
575             if (man == null) {
576                 throw new SecurityException("The provider is not signed");
577             }
578 
579             // Ensure all the entries' signatures verify correctly
580             byte[] buffer = new byte[8192];
581             Enumeration entries = jarFile.entries();
582 
583             while (entries.hasMoreElements()) {
584                 JarEntry je = (JarEntry) entries.nextElement();
585 
586                 // Skip directories.
587                 if (je.isDirectory())
588                     continue;
589                 entriesVec.addElement(je);
590                 InputStream is = jarFile.getInputStream(je);
591 
592                 // Read in each jar entry. A security exception will
593                 // be thrown if a signature/digest check fails.
594                 int n;
595                 while ((n = is.read(buffer, 0, buffer.length)) != -1) {
596                     // Don't care
597                 }
598                 is.close();
599             }
600 
601             // Get the list of signer certificates 
602             Enumeration e = entriesVec.elements();
603 
604             while (e.hasMoreElements()) {
605                 JarEntry je = (JarEntry) e.nextElement();
606 
607                 // Every file must be signed except files in META-INF.
608                 Certificate[] certs = je.getCertificates();
609                 if ((certs == null) || (certs.length == 0)) {
610                     if (!je.getName().startsWith("META-INF"))
611                         throw new SecurityException(
612                             "The provider " + "has unsigned " + "class files.");
613                 } else {
614                     // Check whether the file is signed by the expected
615                     // signer. The jar may be signed by multiple signers.
616                     // See if one of the signers is 'targetCert'.
617                     int startIndex = 0;
618                     X509Certificate[] certChain;
619                     boolean signedAsExpected = false;
620 
621                     while ((certChain = getAChain(certs, startIndex))
622                         != null) {
623                         if (certChain[0].equals(targetCert)) {
624                             // Stop since one trusted signer is found.
625                             signedAsExpected = true;
626                             break;
627                         }
628                         // Proceed to the next chain.
629                         startIndex += certChain.length;
630                     }
631 
632                     if (!signedAsExpected) {
633                         throw new SecurityException(
634                             "The provider "
635                                 + "is not signed by a "
636                                 + "trusted signer");
637                     }
638                 }
639             }
640         }
641 
642         /**
643          * Extracts ONE certificate chain from the specified certificate array
644          * which may contain multiple certificate chains, starting from index
645          * 'startIndex'.
646          */
647         private static X509Certificate[] getAChain(
648             Certificate[] certs,
649             int startIndex) {
650             if (startIndex > certs.length - 1)
651                 return null;
652 
653             int i;
654             // Keep going until the next certificate is not the 
655             // issuer of this certificate.
656             for (i = startIndex; i < certs.length - 1; i++) {
657                 if (!((X509Certificate) certs[i + 1])
658                     .getSubjectDN()
659                     .equals(((X509Certificate) certs[i]).getIssuerDN())) {
660                     break;
661                 }
662             }
663             // Construct and return the found certificate chain.
664             int certChainSize = (i - startIndex) + 1;
665             X509Certificate[] ret = new X509Certificate[certChainSize];
666             for (int j = 0; j < certChainSize; j++) {
667                 ret[j] = (X509Certificate) certs[startIndex + j];
668             }
669             return ret;
670         }
671 
672         // Close the jar file once this object is no longer needed.
673         protected void finalize() throws Throwable {
674             jarFile.close();
675         }
676     }
677 }
678