diff options
author | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:30:23 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2005-07-16 00:30:23 +0000 |
commit | f911ba985aa7fe0096c386c5be385ac5825ea527 (patch) | |
tree | a0b991cf5866ae1d616639b906ac001811d74508 /libjava/classpath/java/security/SignedObject.java | |
parent | 6f4434b39b261de5317dc81ddfdd94d2e1d62b11 (diff) | |
download | gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.zip gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.gz gcc-f911ba985aa7fe0096c386c5be385ac5825ea527.tar.bz2 |
Initial revision
From-SVN: r102074
Diffstat (limited to 'libjava/classpath/java/security/SignedObject.java')
-rw-r--r-- | libjava/classpath/java/security/SignedObject.java | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/libjava/classpath/java/security/SignedObject.java b/libjava/classpath/java/security/SignedObject.java new file mode 100644 index 0000000..d565b2e --- /dev/null +++ b/libjava/classpath/java/security/SignedObject.java @@ -0,0 +1,240 @@ +/* SignedObject.java --- Signed Object Class + Copyright (C) 1999, 2003, Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.security; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * <p><code>SignedObject</code> is a class for the purpose of creating authentic + * runtime objects whose integrity cannot be compromised without being detected. + * </p> + * + * <p>More specifically, a <code>SignedObject</code> contains another + * {@link Serializable} object, the (to-be-)signed object and its signature.</p> + * + * <p>The signed object is a <i>"deep copy"</i> (in serialized form) of an + * original object. Once the copy is made, further manipulation of the original + * object has no side effect on the copy.</p> + * + * <p>The underlying signing algorithm is designated by the {@link Signature} + * object passed to the constructor and the <code>verify()</code> method. A + * typical usage for signing is the following:</p> + * + * <pre> + * Signature signingEngine = Signature.getInstance(algorithm, provider); + * SignedObject so = new SignedObject(myobject, signingKey, signingEngine); + * </pre> + * + * <p>A typical usage for verification is the following (having received + * <code>SignedObject</code> so):</p> + * + * <pre> + * Signature verificationEngine = Signature.getInstance(algorithm, provider); + * if (so.verify(publickey, verificationEngine)) + * try + * { + * Object myobj = so.getObject(); + * } + * catch (ClassNotFoundException ignored) {}; + * </pre> + * + * <p>Several points are worth noting. First, there is no need to initialize the + * signing or verification engine, as it will be re-initialized inside the + * constructor and the <code>verify()</code> method. Secondly, for verification + * to succeed, the specified public key must be the public key corresponding to + * the private key used to generate the <code>SignedObject</code>.</p> + * + * <p>More importantly, for flexibility reasons, the <code>constructor</code> + * and <code>verify()</code> method allow for customized signature engines, + * which can implement signature algorithms that are not installed formally as + * part of a crypto provider. However, it is crucial that the programmer writing + * the verifier code be aware what {@link Signature} engine is being used, as + * its own implementation of the <code>verify()</code> method is invoked to + * verify a signature. In other words, a malicious {@link Signature} may choose + * to always return <code>true</code> on verification in an attempt to bypass a + * security check.</p> + * + * <p>The signature algorithm can be, among others, the NIST standard <i>DSS</i>, + * using <i>DSA</i> and <i>SHA-1</i>. The algorithm is specified using the same + * convention as that for signatures. The <i>DSA</i> algorithm using the + * <i>SHA-1</i> message digest algorithm can be specified, for example, as + * <code>"SHA/DSA"</code> or <code>"SHA-1/DSA"</code> (they are equivalent). In + * the case of <i>RSA</i>, there are multiple choices for the message digest + * algorithm, so the signing algorithm could be specified as, for example, + * <code>"MD2/RSA"</code>, <code>"MD5/RSA"</code> or <code>"SHA-1/RSA"</code>. + * The algorithm name must be specified, as there is no default.</p> + * + * <p>The name of the Cryptography Package Provider is designated also by the + * {@link Signature} parameter to the <code>constructor</code> and the <code> + * verify()</code> method. If the provider is not specified, the default + * provider is used. Each installation can be configured to use a particular + * provider as default.</p> + * + * <p>Potential applications of <code>SignedObject</code> include:</p> + * + * <ul> + * <li>It can be used internally to any Java runtime as an unforgeable + * authorization token -- one that can be passed around without the fear that + * the token can be maliciously modified without being detected.</li> + * <li>It can be used to sign and serialize data/object for storage outside the + * Java runtime (e.g., storing critical access control data on disk).</li> + * <li>Nested <i>SignedObjects</i> can be used to construct a logical sequence + * of signatures, resembling a chain of authorization and delegation.</li> + * </ul> + * + * @author Mark Benvenuto (ivymccough@worldnet.att.net) + * @since 1.2 + * @see Signature + */ +public final class SignedObject implements Serializable +{ + private static final long serialVersionUID = 720502720485447167L; + + /** @serial */ + private byte[] content; + /** @serial */ + private byte[] signature; + /** @serial */ + private String thealgorithm; + + /** + * Constructs a <code>SignedObject</code> from any {@link Serializable} + * object. The given object is signed with the given signing key, using the + * designated signature engine. + * + * @param object the object to be signed. + * @param signingKey the private key for signing. + * @param signingEngine the signature signing engine. + * @throws IOException if an error occurs during serialization. + * @throws InvalidKeyException if the key is invalid. + * @throws SignatureException if signing fails. + */ + public SignedObject(Serializable object, PrivateKey signingKey, + Signature signingEngine) + throws IOException, InvalidKeyException, SignatureException + { + thealgorithm = signingEngine.getAlgorithm(); + + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + ObjectOutputStream p = new ObjectOutputStream(ostream); + p.writeObject(object); + p.flush(); + p.close(); + + content = ostream.toByteArray(); + + signingEngine.initSign(signingKey); + signingEngine.update(content); + signature = signingEngine.sign(); + } + + /** + * Retrieves the encapsulated object. The encapsulated object is de-serialized + * before it is returned. + * + * @return the encapsulated object. + * @throws IOException if an error occurs during de-serialization. + * @throws ClassNotFoundException if an error occurs during de-serialization. + */ + public Object getObject() throws IOException, ClassNotFoundException + { + ByteArrayInputStream bais = new ByteArrayInputStream(content); + ObjectInput oi = new ObjectInputStream(bais); + Object obj = oi.readObject(); + oi.close(); + bais.close(); + + return obj; + } + + /** + * Retrieves the signature on the signed object, in the form of a byte array. + * + * @return a copy of the signature. + */ + public byte[] getSignature() + { + return (byte[]) signature.clone(); + + } + + /** + * Retrieves the name of the signature algorithm. + * + * @return the signature algorithm name. + */ + public String getAlgorithm() + { + return thealgorithm; + } + + /** + * Verifies that the signature in this <code>SignedObject</code> is the valid + * signature for the object stored inside, with the given verification key, + * using the designated verification engine. + * + * @param verificationKey the public key for verification. + * @param verificationEngine the signature verification engine. + * @return <code>true</code> if the signature is valid, <code>false</code> + * otherwise. + * @throws SignatureException if signature verification failed. + * @throws InvalidKeyException if the verification key is invalid. + */ + public boolean verify(PublicKey verificationKey, Signature verificationEngine) + throws InvalidKeyException, SignatureException + { + verificationEngine.initVerify(verificationKey); + verificationEngine.update(content); + return verificationEngine.verify(signature); + } + + /** Called to restore the state of the SignedObject from a stream. */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + content = (byte[]) content.clone(); + signature = (byte[]) signature.clone(); + } +} |