151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.security.ssl; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.ByteArrayOutputStream; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.*; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Arrays; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.LinkedList; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.List; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Locale; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Set; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Abstraction for the SSL/TLS hash of all handshake messages that is 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * maintained to verify the integrity of the negotiation. Internally, 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * it consists of an MD5 and an SHA1 digest. They are used in the client 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and server finished messages and in certificate verify messages (if sent). 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class transparently deals with cloneable and non-cloneable digests. 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class now supports TLS 1.2 also. The key difference for TLS 1.2 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is that you cannot determine the hash algorithms for CertificateVerify 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * at a early stage. On the other hand, it's simpler than TLS 1.1 (and earlier) 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that there is no messy MD5+SHA1 digests. 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You need to obey these conventions when using this class: 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1. protocolDetermined(version) should be called when the negotiated 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * protocol version is determined. 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2. Before protocolDetermined() is called, only update(), reset(), 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * restrictCertificateVerifyAlgs(), setFinishedAlg(), and 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * setCertificateVerifyAlg() can be called. 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3. After protocolDetermined() is called, reset() cannot be called. 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4. After protocolDetermined() is called, if the version is pre-TLS 1.2, 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getFinishedHash() and getCertificateVerifyHash() cannot be called. Otherwise, 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * getMD5Clone() and getSHAClone() cannot be called. 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5. getMD5Clone() and getSHAClone() can only be called after 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * protocolDetermined() is called and version is pre-TLS 1.2. 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6. getFinishedHash() and getCertificateVerifyHash() can only be called after 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * all protocolDetermined(), setCertificateVerifyAlg() and setFinishedAlg() 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * have been called and the version is TLS 1.2. If a CertificateVerify message 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is to be used, call setCertificateVerifyAlg() with the hash algorithm as the 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * argument. Otherwise, you still must call setCertificateVerifyAlg(null) before 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * calculating any hash value. 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Suggestions: Call protocolDetermined(), restrictCertificateVerifyAlgs(), 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * setFinishedAlg(), and setCertificateVerifyAlg() as early as possible. 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Example: 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * HandshakeHash hh = new HandshakeHash(...) 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.protocolDetermined(ProtocolVersion.TLS12); 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.update(clientHelloBytes); 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.setFinishedAlg("SHA-256"); 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.update(serverHelloBytes); 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ... 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.setCertificateVerifyAlg("SHA-384"); 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.update(CertificateVerifyBytes); 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte[] cvDigest = hh.getCertificateVerifyHash(); 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ... 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.update(finished1); 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte[] finDigest1 = hh.getFinishedHash(); 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.update(finished2); 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte[] finDigest2 = hh.getFinishedHash(); 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If no CertificateVerify message is to be used, call 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre> 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hh.setCertificateVerifyAlg(null); 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre> 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This call can be made once you are certain that this message 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will never be used. 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskifinal class HandshakeHash { 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Common 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -1: unknown 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 1: <=TLS 1.1 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 2: TLS 1.2 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int version = -1; 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ByteArrayOutputStream data = new ByteArrayOutputStream(); 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final boolean isServer; 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // For TLS 1.1 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private MessageDigest md5, sha; 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int clonesNeeded; // needs to be saved for later use 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // For TLS 1.2 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // cvAlgDetermined == true means setCertificateVerifyAlg() is called 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean cvAlgDetermined = false; 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private String cvAlg; 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private MessageDigest finMD; 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Create a new HandshakeHash. needCertificateVerify indicates whether 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a hash for the certificate verify message is required. The argument 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * algs is a set of all possible hash algorithms that might be used in 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * TLS 1.2. If the caller is sure that TLS 1.2 won't be used or no 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * CertificateVerify message will be used, leave it null or empty. 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HandshakeHash(boolean isServer, boolean needCertificateVerify, 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Set<String> algs) { 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.isServer = isServer; 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski clonesNeeded = needCertificateVerify ? 3 : 2; 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void update(byte[] b, int offset, int len) { 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (version) { 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 1: 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md5.update(b, offset, len); 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sha.update(b, offset, len); 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski default: 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (finMD != null) { 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski finMD.update(b, offset, len); 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data.write(b, offset, len); 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reset the remaining digests. Note this does *not* reset the number of 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * digest clones that can be obtained. Digests that have already been 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cloned and are gone remain gone. 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void reset() { 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (version != -1) { 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException( 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "reset() can be only be called before protocolDetermined"); 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski data.reset(); 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void protocolDetermined(ProtocolVersion pv) { 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Do not set again, will ignore 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (version != -1) return; 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski version = pv.compareTo(ProtocolVersion.TLS12) >= 0 ? 2 : 1; 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski switch (version) { 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 1: 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // initiate md5, sha and call update on saved array 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski md5 = CloneableDigest.getDigest("MD5", clonesNeeded); 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sha = CloneableDigest.getDigest("SHA", clonesNeeded); 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NoSuchAlgorithmException e) { 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ("Algorithm MD5 or SHA not available", e); 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] bytes = data.toByteArray(); 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski update(bytes, 0, bytes.length); 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski case 2: 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ///////////////////////////////////////////////////////////// 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Below are old methods for pre-TLS 1.1 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ///////////////////////////////////////////////////////////// 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return a new MD5 digest updated with all data hashed so far. 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MessageDigest getMD5Clone() { 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (version != 1) { 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException( 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "getMD5Clone() can be only be called for TLS 1.1"); 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cloneDigest(md5); 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return a new SHA digest updated with all data hashed so far. 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MessageDigest getSHAClone() { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (version != 1) { 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException( 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "getSHAClone() can be only be called for TLS 1.1"); 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cloneDigest(sha); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static MessageDigest cloneDigest(MessageDigest digest) { 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (MessageDigest)digest.clone(); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (CloneNotSupportedException e) { 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // cannot occur for digests generated via CloneableDigest 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException("Could not clone digest", e); 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ///////////////////////////////////////////////////////////// 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Below are new methods for TLS 1.2 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ///////////////////////////////////////////////////////////// 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static String normalizeAlgName(String alg) { 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski alg = alg.toUpperCase(Locale.US); 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (alg.startsWith("SHA")) { 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (alg.length() == 3) { 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "SHA-1"; 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (alg.charAt(3) != '-') { 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return "SHA-" + alg.substring(3); 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return alg; 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Specifies the hash algorithm used in Finished. This should be called 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * based in info in ServerHello. 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Can be called multiple times. 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void setFinishedAlg(String s) { 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s == null) { 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException( 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "setFinishedAlg's argument cannot be null"); 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Can be called multiple times, but only set once 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (finMD != null) return; 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski finMD = CloneableDigest.getDigest(normalizeAlgName(s), 2); 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (NoSuchAlgorithmException e) { 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new Error(e); 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski finMD.update(data.toByteArray()); 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Restricts the possible algorithms for the CertificateVerify. Called by 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the server based on info in CertRequest. The argument must be a subset 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the argument with the same name in the constructor. The method can be 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called multiple times. If the caller is sure that no CertificateVerify 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * message will be used, leave this argument null or empty. 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void restrictCertificateVerifyAlgs(Set<String> algs) { 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (version == 1) { 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException( 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "setCertificateVerifyAlg() cannot be called for TLS 1.1"); 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Not used yet 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Specifies the hash algorithm used in CertificateVerify. 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Can be called multiple times. 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void setCertificateVerifyAlg(String s) { 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Can be called multiple times, but only set once 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cvAlgDetermined) return; 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cvAlg = s == null ? null : normalizeAlgName(s); 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cvAlgDetermined = true; 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] getAllHandshakeMessages() { 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return data.toByteArray(); 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Calculates the hash in the CertificateVerify. Must be called right 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * after setCertificateVerifyAlg() 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /*byte[] getCertificateVerifyHash() { 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new Error("Do not call getCertificateVerifyHash()"); 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }*/ 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Calculates the hash in Finished. Must be called after setFinishedAlg(). 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method can be called twice, for Finished messages of the server 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * side and client side respectively. 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] getFinishedHash() { 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cloneDigest(finMD).digest(); 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new Error("BAD"); 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A wrapper for MessageDigests that simulates cloning of non-cloneable 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * digests. It uses the standard MessageDigest API and therefore can be used 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * transparently in place of a regular digest. 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note that we extend the MessageDigest class directly rather than 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * MessageDigestSpi. This works because MessageDigest was originally designed 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this way in the JDK 1.1 days which allows us to avoid creating an internal 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * provider. 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It can be "cloned" a limited number of times, which is specified at 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * construction time. This is achieved by internally maintaining n digests 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in parallel. Consequently, it is only 1/n-th times as fast as the original 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * digest. 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Example: 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * MessageDigest md = CloneableDigest.getDigest("SHA", 2); 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * md.update(data1); 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * MessageDigest md2 = (MessageDigest)md.clone(); 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * md2.update(data2); 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte[] d1 = md2.digest(); // digest of data1 || data2 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * md.update(data3); 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte[] d2 = md.digest(); // digest of data1 || data3 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class is not thread safe. 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskifinal class CloneableDigest extends MessageDigest implements Cloneable { 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The individual MessageDigests. Initially, all elements are non-null. 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When clone() is called, the non-null element with the maximum index is 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returned and the array element set to null. 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * All non-null element are always in the same state. 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final MessageDigest[] digests; 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private CloneableDigest(MessageDigest digest, int n, String algorithm) 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws NoSuchAlgorithmException { 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(algorithm); 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests = new MessageDigest[n]; 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests[0] = digest; 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 1; i < n; i++) { 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests[i] = JsseJce.getMessageDigest(algorithm); 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Return a MessageDigest for the given algorithm that can be cloned the 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified number of times. If the default implementation supports 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * cloning, it is returned. Otherwise, an instance of this class is 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returned. 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static MessageDigest getDigest(String algorithm, int n) 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws NoSuchAlgorithmException { 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MessageDigest digest = JsseJce.getMessageDigest(algorithm); 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digest.clone(); 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // already cloneable, use it 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return digest; 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (CloneNotSupportedException e) { 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new CloneableDigest(digest, n, algorithm); 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Check if this object is still usable. If it has already been cloned the 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * maximum number of times, there are no digests left and this object can no 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * longer be used. 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void checkState() { 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // XXX handshaking currently doesn't stop updating hashes... 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if (digests[0] == null) { 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // throw new IllegalStateException("no digests left"); 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // } 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected int engineGetDigestLength() { 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkState(); 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return digests[0].getDigestLength(); 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void engineUpdate(byte b) { 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkState(); 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; (i < digests.length) && (digests[i] != null); i++) { 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests[i].update(b); 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void engineUpdate(byte[] b, int offset, int len) { 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkState(); 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; (i < digests.length) && (digests[i] != null); i++) { 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests[i].update(b, offset, len); 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected byte[] engineDigest() { 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkState(); 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] digest = digests[0].digest(); 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digestReset(); 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return digest; 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected int engineDigest(byte[] buf, int offset, int len) 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws DigestException { 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkState(); 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = digests[0].digest(buf, offset, len); 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digestReset(); 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Reset all digests after a digest() call. digests[0] has already been 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * implicitly reset by the digest() call and does not need to be reset 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * again. 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void digestReset() { 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 1; (i < digests.length) && (digests[i] != null); i++) { 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests[i].reset(); 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void engineReset() { 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkState(); 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = 0; (i < digests.length) && (digests[i] != null); i++) { 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests[i].reset(); 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Object clone() { 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkState(); 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (int i = digests.length - 1; i >= 0; i--) { 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (digests[i] != null) { 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MessageDigest digest = digests[i]; 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski digests[i] = null; 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return digest; 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // cannot occur 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new InternalError(); 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 460