KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > maverick > ssl > TrustedCACertStore


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.maverick.ssl;
21
22 import java.io.ByteArrayInputStream JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.math.BigInteger JavaDoc;
27 import java.text.MessageFormat JavaDoc;
28 import java.util.Hashtable JavaDoc;
29
30 import com.maverick.crypto.asn1.ASN1OctetString;
31 import com.maverick.crypto.asn1.ASN1Sequence;
32 import com.maverick.crypto.asn1.DERInputStream;
33 import com.maverick.crypto.asn1.DERObjectIdentifier;
34 import com.maverick.crypto.asn1.x509.CertificateException;
35 import com.maverick.crypto.asn1.x509.X509Certificate;
36 import com.maverick.crypto.asn1.x509.X509CertificateStructure;
37 import com.maverick.crypto.digests.MD5Digest;
38 import com.maverick.crypto.digests.SHA1Digest;
39 import com.maverick.crypto.publickey.PublicKey;
40 import com.maverick.crypto.publickey.Rsa;
41 import com.maverick.crypto.publickey.RsaPublicKey;
42
43 /**
44  *
45  * @author Lee David Painter <a HREF="mailto:lee@3sp.com">&lt;lee@3sp.com&gt;</a>
46  */

47 public class TrustedCACertStore {
48
49     static Hashtable JavaDoc temporarilyTrusted = new Hashtable JavaDoc();
50
51     public TrustedCACertStore() {
52     }
53
54     public boolean isTrustedCertificate(X509Certificate x509, boolean allowInvalidCertificates, boolean allowUntrustedCertificates)
55                     throws SSLException {
56         try {
57             if (CertificateStore.getInstance().contains(x509.getIssuerDN().toString())) {
58
59
60                 X509Certificate trusted = (X509Certificate) CertificateStore.getInstance().get(x509.getIssuerDN().toString());
61
62                 // Verify the signature of the certificate with the trusted
63
// certificate
64
PublicKey publickey = trusted.getPublicKey();
65
66                 if (publickey instanceof RsaPublicKey) {
67                     // Verify the signature
68
if (x509.getSigAlgName().equals("MD5WithRSAEncryption")) { //$NON-NLS-1$
69

70                         try {
71                             byte[] blob = x509.getSignature();
72
73                             // Check for signed bit
74
if ((blob[0] & 0x80) == 0x80) {
75                                 blob = new byte[x509.getSignature().length + 1];
76                                 blob[0] = 0;
77                                 System.arraycopy(x509.getSignature(), 0, blob, 1, x509.getSignature().length);
78                             }
79
80                             BigInteger JavaDoc input = new BigInteger JavaDoc(blob);
81                             RsaPublicKey r = (RsaPublicKey) trusted.getPublicKey();
82                             BigInteger JavaDoc decoded = Rsa.doPublic(input, r.getModulus(), r.getPublicExponent());
83                             BigInteger JavaDoc result = Rsa.removePKCS1(decoded, 0x01);
84                             byte[] sig = result.toByteArray();
85
86                             MD5Digest digest = new MD5Digest();
87                             digest.update(x509.getTBSCertificate(), 0, x509.getTBSCertificate().length);
88                             byte[] hash = new byte[digest.getDigestSize()];
89                             digest.doFinal(hash, 0);
90
91                             DERInputStream der = new DERInputStream(new ByteArrayInputStream JavaDoc(sig));
92
93                             ASN1Sequence o = (ASN1Sequence) der.readObject();
94
95                             ASN1Sequence o1 = (ASN1Sequence) o.getObjectAt(0);
96
97                             DERObjectIdentifier o2 = (DERObjectIdentifier) o1.getObjectAt(0);
98                             ASN1OctetString o3 = (ASN1OctetString) o.getObjectAt(1);
99
100                             byte[] actual = o3.getOctets();
101
102                             for (int i = 0; i < actual.length; i++) {
103                                 if (actual[i] != hash[i]) {
104                                     return false;
105                                 }
106                             }
107
108                         } catch (IOException JavaDoc ex1) {
109                             throw new SSLException(SSLException.INTERNAL_ERROR, ex1.getMessage());
110                         }
111
112                     } else if (x509.getSigAlgName().equals("SHA1WithRSAEncryption")) { //$NON-NLS-1$
113

114                         try {
115                             byte[] blob = x509.getSignature();
116
117                             // Check for signed bit
118
if ((blob[0] & 0x80) == 0x80) {
119                                 blob = new byte[x509.getSignature().length + 1];
120                                 blob[0] = 0;
121                                 System.arraycopy(x509.getSignature(), 0, blob, 1, x509.getSignature().length);
122                             }
123
124                             BigInteger JavaDoc input = new BigInteger JavaDoc(blob);
125                             RsaPublicKey r = (RsaPublicKey) trusted.getPublicKey();
126
127                             BigInteger JavaDoc decoded = Rsa.doPublic(input, r.getModulus(), r.getPublicExponent());
128
129                             BigInteger JavaDoc result = Rsa.removePKCS1(decoded, 0x01);
130                             byte[] sig = result.toByteArray();
131
132                             SHA1Digest digest = new SHA1Digest();
133                             digest.update(x509.getTBSCertificate(), 0, x509.getTBSCertificate().length);
134                             byte[] hash = new byte[digest.getDigestSize()];
135                             digest.doFinal(hash, 0);
136
137                             DERInputStream der = new DERInputStream(new ByteArrayInputStream JavaDoc(sig));
138
139                             ASN1Sequence o = (ASN1Sequence) der.readObject();
140
141                             ASN1Sequence o1 = (ASN1Sequence) o.getObjectAt(0);
142
143                             DERObjectIdentifier o2 = (DERObjectIdentifier) o1.getObjectAt(0);
144                             ASN1OctetString o3 = (ASN1OctetString) o.getObjectAt(1);
145
146                             byte[] actual = o3.getOctets();
147
148                             for (int i = 0; i < actual.length; i++) {
149                                 if (actual[i] != hash[i]) {
150                                     return false;
151                                 }
152                             }
153
154                         } catch (IOException JavaDoc ex1) {
155                             throw new SSLException(SSLException.INTERNAL_ERROR, ex1.getMessage());
156                         }
157
158                     } else
159                         throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE,
160                             MessageFormat.format(Messages.getString("TrustedCACertStore.signatureAlgorithmNotSupported"), new Object JavaDoc[] { x509.getSigAlgName() })); //$NON-NLS-1$
161

162                     // Verify the validity
163
try {
164                         trusted.checkValidity();
165                         x509.checkValidity();
166                     } catch (CertificateException ex2) {
167                         if (allowInvalidCertificates) {
168                             return true;
169                         } else {
170                             if (CertificatePrompt.prompt != null) {
171                                 String JavaDoc str = new String JavaDoc(x509.getSignature());
172                                 if (temporarilyTrusted.containsKey(str)
173                                     || CertificatePrompt.prompt.invalid(x509) != CertificatePrompt.ABORT) {
174                                     temporarilyTrusted.put(str, x509);
175                                     return true;
176                                 }
177                             }
178                         }
179                         return false;
180                     }
181
182                     return true;
183
184                 } else {
185                     throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE,
186                         Messages.getString("TrustedCACertStore.unsupportedPublicKeyInX509Cert")); //$NON-NLS-1$
187
}
188
189             } else {
190
191                 // System.out.println("Certificate is not trusted. checking
192
// validity");
193
try {
194                     x509.checkValidity();
195                 } catch (CertificateException ex2) {
196                     // System.out.println("Certificate is invalid (2)");
197
if (allowInvalidCertificates) {
198                         // System.out.println("invalid cets = true");
199
return true;
200                     } else {
201                         if (CertificatePrompt.prompt != null) {
202                             String JavaDoc str = new String JavaDoc(x509.getSignature());
203                             if (temporarilyTrusted.containsKey(str)
204                                 || CertificatePrompt.prompt.invalid(x509) != CertificatePrompt.ABORT) {
205                                 temporarilyTrusted.put(str, x509);
206                                 return true;
207                             }
208                         }
209                     }
210                     return false;
211                 }
212
213                 // System.out.println("Checking for untrusted flag");
214

215                 if (allowUntrustedCertificates) {
216                     // System.out.println("Certificate is ok untrusted=true");
217
return true;
218                 } else {
219                     if (CertificatePrompt.prompt != null) {
220                         String JavaDoc str = new String JavaDoc(x509.getSignature());
221                         if (temporarilyTrusted.containsKey(str)
222                             || CertificatePrompt.prompt.untrusted(x509) != CertificatePrompt.ABORT) {
223                             temporarilyTrusted.put(str, x509);
224                             return true;
225                         }
226                     }
227                 }
228                 return false;
229             }
230         } catch (CertificateException ex) {
231             throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE, ex.getMessage());
232         } catch (IOException JavaDoc ex) {
233             ex.printStackTrace();
234             throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE,
235                 Messages.getString("TrustedCACertStore.errorGettingCertFromTrustStore")); //$NON-NLS-1$
236
}
237     }
238
239     private void log(String JavaDoc msg, byte[] buf) {
240
241         // System.out.print(msg + ": ");
242
for (int i = 0; i < buf.length; i++) {
243             // System.out.print(Integer.toHexString(buf[i] & 0xFF).toUpperCase()
244
// + " ");
245
}
246         // System.out.println();
247
}
248
249     public static void main(String JavaDoc[] args) {
250
251         TrustedCACertStore store = new TrustedCACertStore();
252
253         DERInputStream der = null;
254         InputStream JavaDoc in = null;
255         try {
256             in = new FileInputStream JavaDoc("c:\\exported.cer"); //$NON-NLS-1$
257
der = new DERInputStream(in);
258
259             ASN1Sequence certificate = (ASN1Sequence) der.readObject();
260             com.maverick.crypto.asn1.x509.X509Certificate x509 = new com.maverick.crypto.asn1.x509.X509Certificate(X509CertificateStructure.getInstance(certificate));
261
262             /*
263              * if (store.isTrustedCertificate(x509, false, false)) {
264              * //System.out.println("Success"); } else {
265              * //System.out.println("Failure"); }
266              */

267         } catch (Exception JavaDoc ex) {
268             ex.printStackTrace();
269         } finally {
270             // Util.closeStream(der);
271
// Util.closeStream(in);
272
}
273
274     }
275 }
276
Popular Tags