1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.security; 19 20import java.io.ByteArrayInputStream; 21import java.io.ByteArrayOutputStream; 22import java.io.IOException; 23import java.io.ObjectInputStream; 24import java.io.ObjectOutputStream; 25import java.io.Serializable; 26 27/** 28 * A {@code SignedObject} instance acts as a container for another object. The 29 * {@code SignedObject} contains the target in serialized form along with a 30 * digital signature of the serialized data. 31 */ 32public final class SignedObject implements Serializable { 33 34 private static final long serialVersionUID = 720502720485447167L; 35 36 private byte[] content; 37 38 private byte[] signature; 39 40 private String thealgorithm; 41 42 private void readObject(ObjectInputStream s) throws IOException, 43 ClassNotFoundException { 44 45 s.defaultReadObject(); 46 byte[] tmp = new byte[content.length]; 47 System.arraycopy(content, 0, tmp, 0, content.length); 48 content = tmp; 49 tmp = new byte[signature.length]; 50 System.arraycopy(signature, 0, tmp, 0, signature.length); 51 signature = tmp; 52 } 53 54 /** 55 * Constructs a new instance of {@code SignedObject} with the target object, 56 * the private key and the engine to compute the signature. The given 57 * {@code object} is signed with the specified key and engine. 58 * 59 * @param object 60 * the object to bes signed. 61 * @param signingKey 62 * the private key, used to sign the {@code object}. 63 * @param signingEngine 64 * the engine that performs the signature generation. 65 * @throws IOException 66 * if a serialization error occurs. 67 * @throws InvalidKeyException 68 * if the private key is not valid. 69 * @throws SignatureException 70 * if signature generation failed. 71 */ 72 public SignedObject(Serializable object, PrivateKey signingKey, 73 Signature signingEngine) throws IOException, InvalidKeyException, 74 SignatureException { 75 76 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 77 ObjectOutputStream oos = new ObjectOutputStream(baos); 78 try { 79 // Serialize 80 oos.writeObject(object); 81 oos.flush(); 82 } finally { 83 oos.close(); 84 } 85 content = baos.toByteArray(); 86 signingEngine.initSign(signingKey); 87 thealgorithm = signingEngine.getAlgorithm(); 88 signingEngine.update(content); 89 signature = signingEngine.sign(); 90 } 91 92 /** 93 * Returns the encapsulated object. Each time this method is invoked, the 94 * encapsulated object is deserialized before it is returned. 95 * 96 * @return the encapsulated object. 97 * @throws IOException 98 * if deserialization failed. 99 * @throws ClassNotFoundException 100 * if the class of the encapsulated object can not be found. 101 */ 102 public Object getObject() throws IOException, ClassNotFoundException { 103 // deserialize our object 104 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream( 105 content)); 106 try { 107 return ois.readObject(); 108 } finally { 109 ois.close(); 110 } 111 } 112 113 /** 114 * Returns the signature data of the encapsulated serialized object. 115 * 116 * @return the signature data of the encapsulated serialized object. 117 */ 118 public byte[] getSignature() { 119 byte[] sig = new byte[signature.length]; 120 System.arraycopy(signature, 0, sig, 0, signature.length); 121 return sig; 122 } 123 124 /** 125 * Returns the name of the algorithm of this {@code SignedObject}. 126 * 127 * @return the name of the algorithm of this {@code SignedObject}. 128 */ 129 public String getAlgorithm() { 130 return thealgorithm; 131 } 132 133 /** 134 * Indicates whether the contained signature for the encapsulated object is 135 * valid. 136 * 137 * @param verificationKey 138 * the public key to verify the signature. 139 * @param verificationEngine 140 * the signature engine. 141 * @return {@code true} if the contained signature for the encapsulated 142 * object is valid, {@code false} otherwise. 143 * @throws InvalidKeyException 144 * if the public key is invalid. 145 * @throws SignatureException 146 * if signature verification failed. 147 */ 148 public boolean verify(PublicKey verificationKey, 149 Signature verificationEngine) throws InvalidKeyException, 150 SignatureException { 151 152 verificationEngine.initVerify(verificationKey); 153 verificationEngine.update(content); 154 return verificationEngine.verify(signature); 155 } 156 157} 158