Path: blob/master/test/jdk/com/sun/crypto/provider/CICO/CICOSkipTest.java
41155 views
/*1* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import static java.lang.System.out;2425import java.io.ByteArrayInputStream;26import java.io.IOException;27import java.security.InvalidAlgorithmParameterException;28import java.security.InvalidKeyException;29import java.security.NoSuchAlgorithmException;30import java.security.Provider;31import java.security.Security;32import java.security.spec.AlgorithmParameterSpec;33import java.security.spec.InvalidKeySpecException;34import javax.crypto.Cipher;35import javax.crypto.CipherInputStream;36import javax.crypto.KeyGenerator;37import javax.crypto.NoSuchPaddingException;38import javax.crypto.SecretKey;39import javax.crypto.SecretKeyFactory;40import javax.crypto.spec.IvParameterSpec;41import javax.crypto.spec.PBEKeySpec;42import javax.crypto.spec.PBEParameterSpec;4344/*45* @test46* @bug 804860447* @summary This test verifies the assertion "The skip feature of Filter48* streams should be supported." for feature49* CipherInputStream and CipherOutputStream50*/51public class CICOSkipTest {52/**53* Block length.54*/55private static final int BLOCK = 50;5657/**58* Saving bytes length.59*/60private static final int SAVE = 45;6162/**63* Plain text length.64*/65private static final int PLAIN_TEXT_LENGTH = 800;6667/**68* Skip reading byte size. This should be same to BLOCK - SAVE69*/70private static final int DISCARD = BLOCK - SAVE;7172private static final String[] ALGOS = {"DES", "DESede", "Blowfish"};73private static final String[] MODES = {"ECB", "CBC", "CFB", "CFB32",74"OFB", "OFB64", "PCBC"};75private static final String[] PADDINGS = {"NoPadding", "Pkcs5Padding"};76private static final String[] PBE_ALGOS = {"PBEWithMD5AndDES",77"PBEWithMD5AndDES/CBC/PKCS5Padding"};7879public static void main(String[] args) throws Exception {80// how many kinds of padding mode such as PKCS5padding and NoPadding81for (String algo : ALGOS) {82for (String mode : MODES) {83int padKinds = 1;84if (mode.equalsIgnoreCase("ECB")85|| mode.equalsIgnoreCase("PCBC")86|| mode.equalsIgnoreCase("CBC")) {87padKinds = PADDINGS.length;88}89// PKCS5padding is meaningful only for ECB, CBC, PCBC90for (int k = 0; k < padKinds; k++) {91String info = algo + "/" + mode + "/" + PADDINGS[k];92try {93CipherGenerator cg = new CipherGenerator(algo, mode,94PADDINGS[k]);95for (ReadMethod model : ReadMethod.values()) {96runTest(cg.getPair(), info, model);97}98} catch (LengthLimitException exp) {99// skip this if this key length is larger than what's100// configured in the jce jurisdiction policy files101out.println(exp.getMessage() + " is expected.");102}103}104}105}106for (String pbeAlgo : PBE_ALGOS) {107for (ReadMethod model : ReadMethod.values()) {108System.out.println("Testing Algorithm : " + pbeAlgo109+ " ReadMethod : " + model);110runTest(new CipherGenerator(pbeAlgo).getPair(), pbeAlgo, model);111}112}113}114115private static void runTest(Cipher[] pair, String info, ReadMethod whichRead)116throws IOException {117byte[] plainText = TestUtilities.generateBytes(PLAIN_TEXT_LENGTH);118out.println("Testing: " + info + "/" + whichRead);119try (ByteArrayInputStream baInput = new ByteArrayInputStream(plainText);120CipherInputStream ciInput1 = new CipherInputStream(baInput,121pair[0]);122CipherInputStream ciInput2 = new CipherInputStream(ciInput1,123pair[1]);) {124// Skip 5 bytes after read 45 bytes and repeat until finish125// (Read from the input and write to the output using 2 types126// of buffering : byte[] and int)127// So output has size:128// (OVERALL/BLOCK)* SAVE = (800 / 50) * 45 = 720 bytes129int numOfBlocks = plainText.length / BLOCK;130131// Output buffer.132byte[] outputText = new byte[numOfBlocks * SAVE];133int index = 0;134for (int i = 0; i < numOfBlocks; i++) {135index = whichRead.readByte(ciInput2, outputText, SAVE, index);136// If available is more than expected discard byte size. Skip137// discard bytes, otherwise try to read discard bytes by read.138if (ciInput2.available() >= DISCARD) {139ciInput2.skip(DISCARD);140} else {141for (int k = 0; k < DISCARD; k++) {142ciInput2.read();143}144}145}146// Verify output is same as input147if (!TestUtilities148.equalsBlockPartial(plainText, outputText, BLOCK, SAVE)) {149throw new RuntimeException("Test failed with compare fail");150}151}152}153}154155class CipherGenerator {156/**157* Initialization vector length.158*/159private static final int IV_LENGTH = 8;160161private static final String PASSWD = "Sesame!(@#$%^&*)";162163private final Cipher[] pair = new Cipher[2];164165// For DES/DESede ciphers166CipherGenerator(String algo, String mo, String pad)167throws NoSuchAlgorithmException,168InvalidAlgorithmParameterException, InvalidKeyException,169NoSuchPaddingException, SecurityException, LengthLimitException {170// Do initialization171KeyGenerator kg = KeyGenerator.getInstance(algo);172SecretKey key = kg.generateKey();173if (key.getEncoded().length * 8 > Cipher.getMaxAllowedKeyLength(algo)) {174// skip this if this key length is larger than what's175// configured in the jce jurisdiction policy files176throw new LengthLimitException(177"Skip this test if key length is larger than what's"178+ "configured in the jce jurisdiction policy files");179}180AlgorithmParameterSpec aps = null;181if (!mo.equalsIgnoreCase("ECB")) {182byte[] iv = TestUtilities.generateBytes(IV_LENGTH);183aps = new IvParameterSpec(iv);184}185initCiphers(algo + "/" + mo + "/" + pad, key, aps);186}187188// For PBE ciphers189CipherGenerator(String algo) throws NoSuchAlgorithmException,190InvalidAlgorithmParameterException, InvalidKeyException,191NoSuchPaddingException, InvalidKeySpecException {192// Do initialization193byte[] salt = TestUtilities.generateBytes(IV_LENGTH);194int iterCnt = 6;195SecretKeyFactory skf = SecretKeyFactory.getInstance(algo.split("/")[0]);196SecretKey key = skf197.generateSecret(new PBEKeySpec(PASSWD.toCharArray()));198AlgorithmParameterSpec aps = new PBEParameterSpec(salt, iterCnt);199initCiphers(algo, key, aps);200}201202private void initCiphers(String algo, SecretKey key,203AlgorithmParameterSpec aps) throws NoSuchAlgorithmException,204NoSuchPaddingException, InvalidKeyException,205InvalidAlgorithmParameterException {206Provider provider = Security.getProvider("SunJCE");207if (provider == null) {208throw new RuntimeException("SunJCE provider does not exist.");209}210Cipher ci1 = Cipher.getInstance(algo, provider);211ci1.init(Cipher.ENCRYPT_MODE, key, aps);212pair[0] = ci1;213Cipher ci2 = Cipher.getInstance(algo, provider);214ci2.init(Cipher.DECRYPT_MODE, key, aps);215pair[1] = ci2;216}217218Cipher[] getPair() {219return pair;220}221}222223enum ReadMethod {224// read one byte at a time for save times225READ_ONE_BYTE {226@Override227int readByte(CipherInputStream ciIn2, byte[] outputText, int save,228int index) throws IOException {229for (int j = 0; j < save; j++, index++) {230int buffer0 = ciIn2.read();231if (buffer0 != -1) {232outputText[index] = (byte) buffer0;233} else {234break;235}236}237return index;238}239},240// read a chunk of save bytes if possible241READ_BLOCK {242@Override243int readByte(CipherInputStream ciIn2, byte[] outputText, int save,244int index) throws IOException {245int len1 = ciIn2.read(outputText, index, save);246out.println("Init: index=" + index + ",len=" + len1);247// read more until save bytes248index += len1;249int len2 = 0;250while (len1 != save && len2 != -1) {251len2 = ciIn2.read(outputText, index, save - len1);252out.println("Cont: index=" + index + ",len=" + len2);253len1 += len2;254index += len2;255}256return index;257}258};259260abstract int readByte(CipherInputStream ciIn2, byte[] outputText, int save,261int index) throws IOException;262};263264class LengthLimitException extends Exception {265266public LengthLimitException(String string) {267super(string);268}269}270271272