/*
 * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/**
 * @test
 * @bug 4900891
 * @summary Test the EncryptedPrivateKeyInfo.getKeySpec(...)
 * methods with scenarios where the decrypted bytes are not
 * encoded correctly per PKCS#8 standard.
 * @author Valerie Peng
 */
import java.util.*;
import java.nio.*;
import java.io.*;
import java.security.*;
import java.util.Arrays;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class GetKeySpecInvalidEncoding {
    private static final String cipherAlg = "PBEWithMD5AndDES";
    private static final char[] passwd = { 'p','a','s','s', 'w', 'd' };
    private static AlgorithmParameters GOOD_PARAMS;

    static {
        try {
            PBEParameterSpec goodParamSpec =
                new PBEParameterSpec(new byte[8], 6);
            GOOD_PARAMS = AlgorithmParameters.getInstance
                (cipherAlg, "SunJCE");
            GOOD_PARAMS.init(goodParamSpec);
        } catch (Exception ex) {
            // should never happen
            GOOD_PARAMS = null;
        }
    }

    private static String encryptedPKCS8 = "5C:BC:13:5D:40:2F:02:28:94:3C:A9:F7:98:A6:58:DC:F9:12:B7:CB:0F:40:DD:66:AB:58:6B:23:2F:8A:5A:81:9D:55:2A:EB:3F:AA:6A:CE:AE:23:8A:96:12:21:5A:09:BF:59:65:3F:B8:48:59:69:C6:D0:9C:48:B6:78:C3:C6:B4:24:F9:BE:10:00:D5:F3:52:88:53:CD:07:CA:88:93:15:3F:BA:19:4A:E9:5D:C7:44:46:49:F6:19:83:86:E0:25:51:9E:83:6D:AE:F2:14:9C:BF:02:7B:8C:64:B4:5F:F1:7B:28:2F:39:55:32:A4:F5:41:85:9E:77:F2:07:09:CD:97:90:5A:04:81:23:30";

    private static byte[] parse(String s) {
        try {
            int n = s.length();
            ByteArrayOutputStream out = new ByteArrayOutputStream(n / 3);
            StringReader r = new StringReader(s);
            while (true) {
                int b1 = nextNibble(r);
                if (b1 < 0) {
                    break;
                }
                int b2 = nextNibble(r);
                if (b2 < 0) {
                    throw new RuntimeException("Invalid string " + s);
                }
                int b = (b1 << 4) | b2;
                out.write(b);
            }
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    private static int nextNibble(StringReader r) throws IOException {
        while (true) {
            int ch = r.read();
            if (ch == -1) {
                return -1;
            } else if ((ch >= '0') && (ch <= '9')) {
                return ch - '0';
            } else if ((ch >= 'a') && (ch <= 'f')) {
                return ch - 'a' + 10;
            } else if ((ch >= 'A') && (ch <= 'F')) {
                return ch - 'A' + 10;
            }
        }
    }

    public static void main(String[] argv) throws Exception {
        if (GOOD_PARAMS == null) {
            throw new Exception("Static parameter generation failed");
        }
        byte[] encryptedData = parse(encryptedPKCS8);

        Provider p = Security.getProvider("SunJCE");

        // generate encrypted data and EncryptedPrivateKeyInfo object
        EncryptedPrivateKeyInfo epki =
            new EncryptedPrivateKeyInfo(GOOD_PARAMS, encryptedData);

        PKCS8EncodedKeySpec pkcs8Spec;
        // TEST#1 getKeySpec(Cipher)
        System.out.println("Testing getKeySpec(Cipher)...");
        // Prepare Cipher for decryption
        PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd);
        SecretKeyFactory skf = SecretKeyFactory.getInstance(cipherAlg, p);
        SecretKey cipherKey = skf.generateSecret(pbeKeySpec);
        Cipher cipher = Cipher.getInstance(cipherAlg, p);
        cipher.init(Cipher.DECRYPT_MODE, cipherKey, GOOD_PARAMS);
        try {
            pkcs8Spec = epki.getKeySpec(cipher);
            throw new Exception("getKeySpec(Cipher): should throw IKSE");
        } catch (InvalidKeySpecException ikse) {
            // expected
        }
        // TEST#2 getKeySpec(Key)
        System.out.println("Testing getKeySpec(Key)...");
        try {
            pkcs8Spec = epki.getKeySpec(cipherKey);
            throw new Exception("getKeySpec(Key): should throw IKE");
        } catch (InvalidKeyException ike) {
            // expected
        }

        // TEST#3 getKeySpec(Key, String)
        System.out.println("Testing getKeySpec(Key, String)...");
        try {
            pkcs8Spec = epki.getKeySpec(cipherKey, p.getName());
            throw new Exception("getKeySpec(Key, String): should throw IKE");
        } catch (InvalidKeyException ike) {
            // expected
        }

        // TEST#4 getKeySpec(Key, Provider)
        System.out.println("Testing getKeySpec(Key, Provider)...");
        try {
            pkcs8Spec = epki.getKeySpec(cipherKey, p);
            throw new Exception("getKeySpec(Key, Provider): should throw IKE");
        } catch (InvalidKeyException ike) {
            // expected
        }
        System.out.println("All Tests Passed");
    }
}
