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