KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ch > ethz > prose > SignedAspect


1 //
2
// This file is part of the prose package.
3
//
4
// The contents of this file are subject to the Mozilla Public License
5
// Version 1.1 (the "License"); you may not use this file except in
6
// compliance with the License. You may obtain a copy of the License at
7
// http://www.mozilla.org/MPL/
8
//
9
// Software distributed under the License is distributed on an "AS IS" basis,
10
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
// for the specific language governing rights and limitations under the
12
// License.
13
//
14
// The Original Code is prose.
15
//
16
// The Initial Developer of the Original Code is Andrei Popovici. Portions
17
// created by Andrei Popovici are Copyright (C) 2002 Andrei Popovici.
18
// All Rights Reserved.
19
//
20
// Contributor(s):
21
// $Id: SignedAspect.java,v 1.1.1.1 2003/07/02 15:30:51 apopovic Exp $
22
// =====================================================================
23
//
24
// (history at end)
25
//
26

27 package ch.ethz.prose;
28
29 // used packages
30
import java.io.FileInputStream JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.rmi.MarshalledObject JavaDoc;
33 import java.security.InvalidKeyException JavaDoc;
34 import java.security.KeyPair JavaDoc;
35 import java.security.KeyStore JavaDoc;
36 import java.security.NoSuchAlgorithmException JavaDoc;
37 import java.security.PrivateKey JavaDoc;
38 import java.security.PublicKey JavaDoc;
39 import java.security.Signature JavaDoc;
40 import java.security.SignatureException JavaDoc;
41 import java.security.SignedObject JavaDoc;
42 import java.util.List JavaDoc;
43
44 import ch.ethz.prose.crosscut.Crosscut;
45 import ch.ethz.inf.util.Logger;
46
47 /**
48  * Class SignedAspect is a wrapper for an Aspect contained in a
49  * SignedObject. Thus it is possible to verify the signer of the
50  * extension before it is used. For security reason, this class
51  * is (and has to be) declared <code>final</code><p>
52  *
53  * At construction, the public and private keys passed as <code>
54  * KeyPair</code> are not checked for being a valid pair
55  * and the private key is not stored for later use. Only
56  * an explicit call to <code>verifyExtension</code> does
57  * check the public key stored. The signing algorithm
58  * to use is deduced by the algorithm type of the public
59  * key: if the public key is of type "DSA" then the algorithm
60  * "SHA1withDSA" is used, in case of an "RSA" key it is "MD5withRSA".
61  * Keys generated with the <code>keytool</code> for the standard
62  * Java 2 keystore are of type "DSA" if not specified otherwise.
63  * The creation of certificates has to be performed by a third party
64  * tool, such as the ones provided with OpenSSL.<p>
65  *
66  * The JCE signing engine that is used can not be specified for the
67  * moment, this class simply uses the first available one.<p>
68  *
69  * To repeat: It is up to the user of this class to assign trust to such
70  * an extension, this class can only be used to transfer an extension
71  * secured from unnoticed changes.<p>
72  *
73  * Remark: to simplify the security auditing of this class, the
74  * necessary and constant parameters are passed to the constructor
75  * and no additional setter-methods are available.
76  *
77  * @version $Revision: 1.1.1.1 $
78  * @author Marcel Muller
79  */

80 final public class SignedAspect extends Aspect {
81     private static KeyPair JavaDoc keyPair;
82
83     private SignedObject JavaDoc signedExtension;
84     private PublicKey JavaDoc publicKey;
85     // private Certificate[] certificateChain; // will work only with jdk 1.3 and later
86

87     transient Aspect wrappedExtension;
88     transient boolean verified = false;
89
90
91     /**
92      * Constructs a signed extension and protects it from being modified unnoticed.
93      * Only the public key from the key pair passed is store in the generated object.
94      *
95      * @param extension the extension to be wrapped into a SignedObject
96      * @param keys the key pair used to sign and verify the extension
97      */

98     public SignedAspect(Aspect extension, KeyPair JavaDoc keys) {
99     publicKey = keys.getPublic();
100
101     try {
102         Signature JavaDoc signingEngine = Signature.getInstance(getSigningAlgorithm());
103         signedExtension = new SignedObject JavaDoc(new MarshalledObject JavaDoc(extension), keys.getPrivate(), signingEngine);
104     } catch (Exception JavaDoc e) {
105         throw new IllegalArgumentException JavaDoc("failed to sign extension ("+e+")");
106     }
107     }
108
109     // delegate work
110
public void insertionAction(boolean beforeInsertion) throws AspectInsertionException {
111     getExtension().insertionAction(beforeInsertion);
112     }
113
114
115     public void withdrawalAction(boolean beforeWithdrawal) {
116     getExtension().withdrawalAction(beforeWithdrawal);
117     }
118
119     protected Crosscut[] crosscuts()
120     {
121     return getExtension().crosscuts();
122     }
123
124     public List JavaDoc getCrosscuts() {
125     return getExtension().getCrosscuts();
126     }
127
128     /**
129      * Convinience method to sign extensions. Throws IllegalStateException
130      * if signing is not possible.<p>
131      *
132      * FIX: CONTAINS A LOT OF HARD CODED STUFF!!!!
133      */

134     public static SignedAspect signExtension(Aspect ext) {
135     try {
136         if (keyPair == null) {
137         String JavaDoc ksl = System.getProperty("ch.ethz.prose.keystore.location");
138         String JavaDoc ksp = System.getProperty("ch.ethz.prose.keystore.password");
139         String JavaDoc alias = "runes-system"; // FIX
140

141         KeyStore JavaDoc ks = KeyStore.getInstance("JKS");
142         ks.load(new FileInputStream JavaDoc(ksl), ksp.toCharArray());
143         PrivateKey JavaDoc privateKey = (PrivateKey JavaDoc) ks.getKey(alias, alias.toCharArray()); // FIX, password
144
PublicKey JavaDoc publicKey = ks.getCertificate(alias).getPublicKey();
145         keyPair = new KeyPair JavaDoc(publicKey, privateKey);
146         }
147
148         return new SignedAspect(ext, keyPair);
149
150     } catch (Exception JavaDoc e) {
151         Logger.error("SignedAspect.signExtension: could not sign extension", e);
152         throw new IllegalStateException JavaDoc("could not sign extension");
153     }
154     }
155
156     /**
157      * Verifies that the public key stored in this object corresponds
158      * to the private key used to sign the extension.
159      *
160      * @param verificationEngine a verification engine to use
161      * @returns <code>true</code> if verification succeeded
162      */

163     public void verifyExtension() throws NoSuchAlgorithmException JavaDoc, SignatureException JavaDoc, InvalidKeyException JavaDoc {
164     Signature JavaDoc verificationEngine = Signature.getInstance(getSigningAlgorithm());
165     signedExtension.verify(publicKey, verificationEngine);
166     verified = true;
167     }
168
169     /**
170      * Returns wrapped extension without checking it for being signed
171      * by a key corresponding to the public key stored.
172      *
173      * @returns the wrapped extension
174      */

175     public Aspect getExtension() {
176     try {
177         if (wrappedExtension == null) {
178         wrappedExtension = (Aspect) ((MarshalledObject JavaDoc) signedExtension.getObject()).get();
179         }
180
181         return wrappedExtension;
182
183     } catch (IOException JavaDoc e) {
184         Logger.error("SignedAspect.getExtension: io exception", e);
185         throw new RuntimeException JavaDoc("contained exception " + e);
186
187     } catch (ClassNotFoundException JavaDoc e) {
188         Logger.error("SignedAspect.getExtension: class not found", e);
189         throw new RuntimeException JavaDoc("contained exception " + e);
190     }
191     }
192
193     /**
194      * Returns public key that possibly corresponds to signing key
195      *
196      * @returns the public key passed in the constructor
197      */

198     public PublicKey JavaDoc getPublicKey() {
199     return publicKey;
200     }
201
202     /**
203      * Returns signing algorithm name
204      *
205      * @returns the algorithm name
206      */

207     public String JavaDoc getSigningAlgorithm() {
208     String JavaDoc signingAlgorithm;
209
210     if (publicKey.getAlgorithm().equals("DSA")) {
211         signingAlgorithm = "SHA1withDSA";
212
213     } else if (publicKey.getAlgorithm().equals("RSA")) {
214         signingAlgorithm = "MD5withRSA";
215
216     } else {
217         throw new IllegalArgumentException JavaDoc("unknown key algorithm, currently supported are DSA and RSA");
218     }
219
220     return signingAlgorithm;
221     }
222
223     /**
224      * Implementation: we don't use getExtension() here, as we don't want to
225      * de-marshall extension just because of the toString call
226      */

227     public String JavaDoc toString() {
228     if (wrappedExtension != null) {
229         return "SignedAspect, "+ (verified?"verified":"not verified") +", containing " + wrappedExtension.toString();
230
231     } else {
232         return "SignedAspect, not accessed";
233     }
234     }
235
236 // public void setCertificateChain(Certificate[] certificateChain) {
237
// this.certificateChain = certificateChain;
238
// }
239

240 // public Certificate[] getCertificateChain() {
241
// return certificateChain;
242
// }
243

244
245     /**
246      * Delegate to wrapped extension
247      */

248     public boolean equals(Object JavaDoc o) {
249     if (o instanceof SignedAspect) {
250         return getExtension().equals(((SignedAspect) o).getExtension());
251
252     } else if (o instanceof Aspect) {
253         return getExtension().equals(o);
254
255     } else {
256         return false;
257     }
258     }
259
260     /**
261      * delegate to wrapped extension
262      */

263     public int hashCode() {
264     return getExtension().hashCode();
265     }
266 }
267
268
269 //======================================================================
270
//
271
// $Log: SignedAspect.java,v $
272
// Revision 1.1.1.1 2003/07/02 15:30:51 apopovic
273
// Imported from ETH Zurich
274
//
275
// Revision 1.1 2003/05/05 13:58:30 popovici
276
// renaming from runes to prose
277
//
278
// Revision 1.2 2003/04/17 15:43:44 popovici
279
// crosscuts renamed to 'getCrosscuts'
280
// createCrosscuts renamed to 'crosscuts'
281
//
282
// Revision 1.1 2003/04/17 15:15:04 popovici
283
// Extension->Aspect renaming
284
//
285
// Revision 1.6 2003/04/17 12:49:41 popovici
286
// Refactoring of the crosscut package
287
// ExceptionCut renamed to ThrowCut
288
// McutSignature is now SignaturePattern
289
//
290
// Revision 1.5 2003/04/17 08:47:14 popovici
291
// Important functionality additions
292
// - Cflow specializers
293
// - Restructuring of the MethodCut, SetCut, ThrowCut, and GetCut (they are much smaller)
294
// - Transactional capabilities
295
// - Total refactoring of Specializer evaluation, which permits fine-grained distinction
296
// between static and dynamic specializers.
297
// - Functionality pulled up in abstract classes
298
// - Uniformization of advice methods patterns and names
299
//
300
// Revision 1.4 2003/03/04 18:36:37 popovici
301
// Organization of imprts
302
//
303
// Revision 1.3 2002/05/29 13:39:06 popovici
304
// minor double semicolumn eliminated
305
//
306
// Revision 1.2 2002/03/28 13:48:38 popovici
307
// Mozilla-ified
308
//
309
// Revision 1.1.1.1 2001/11/29 18:13:16 popovici
310
// Sources from runes
311
//
312
// Revision 1.1.2.6 2001/04/27 07:09:28 mrmuller
313
// Added UGLY convenience method to sign extensions. Like
314
// this, the ugly code is kept centrally and not spread
315
// all around the project.
316
//
317
// Revision 1.1.2.5 2001/04/21 13:57:08 mrmuller
318
// correct handling of equals and hashcode. this method calls
319
// are now correctly delegated to the extension contained inside
320
//
321
// Revision 1.1.2.4 2001/04/10 11:17:30 mrmuller
322
// removed passing of verification engine as parameter and added JavaDoc
323
//
324
// Revision 1.1.2.3 2001/03/27 18:25:50 mrmuller
325
// introduced getSigningAlgorithm
326
//
327
// Revision 1.1.2.2 2001/03/16 17:29:19 mrmuller
328
// cosmetics, javadoc and exception handling changes
329
//
330
// Revision 1.1.2.1 2001/03/16 13:12:32 mrmuller
331
// initial release of new (really) secure extension insertion mechanism
332
//
333
Popular Tags