916 lines · 39.0 KB · Java
RawDownload
/* * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. */ /* Copyright  (c) 2002 Graz University of Technology. All rights reserved. * * Redistribution and use in  source and binary forms, with or without * modification, are permitted  provided that the following conditions are met: * * 1. Redistributions of  source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * * 2. Redistributions in  binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must *    include the following acknowledgment: * *    "This product includes software developed by IAIK of Graz University of *     Technology." * *    Alternately, this acknowledgment may appear in the software itself, if *    and wherever such third-party acknowledgments normally appear. * * 4. The names "Graz University of Technology" and "IAIK of Graz University of *    Technology" must not be used to endorse or promote products derived from *    this software without prior written permission. * * 5. Products derived from this software may not be called *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior *    written permission of Graz University of Technology. * *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *  POSSIBILITY  OF SUCH DAMAGE. */ package sun.security.pkcs11.wrapper; import java.math.BigInteger; import java.util.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; /** * This class contains onyl static methods. It is the place for all functions * that are used by several classes in this package. * * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at> * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at> */public class Functions {     // maps between ids and their names, forward and reverse    // ids are stored as Integers to save space    // since only the lower 32 bits are ever used anyway     // mechanisms (CKM_*)    private static final Map<Integer,String> mechNames =        new HashMap<Integer,String>();     private static final Map<String,Integer> mechIds =        new HashMap<String,Integer>();     // key types (CKK_*)    private static final Map<Integer,String> keyNames =        new HashMap<Integer,String>();     private static final Map<String,Integer> keyIds =        new HashMap<String,Integer>();     // attributes (CKA_*)    private static final Map<Integer,String> attributeNames =        new HashMap<Integer,String>();     private static final Map<String,Integer> attributeIds =        new HashMap<String,Integer>();     // object classes (CKO_*)    private static final Map<Integer,String> objectClassNames =        new HashMap<Integer,String>();     private static final Map<String,Integer> objectClassIds =        new HashMap<String,Integer>();      /**     * For converting numbers to their hex presentation.     */    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();     /**     * Converts a long value to a hexadecimal String of length 16. Includes     * leading zeros if necessary.     *     * @param value The long value to be converted.     * @return The hexadecimal string representation of the long value.     */    public static String toFullHexString(long value) {        long currentValue = value;        StringBuffer stringBuffer = new StringBuffer(16);        for(int j = 0; j < 16; j++) {            int currentDigit = (int) currentValue & 0xf;            stringBuffer.append(HEX_DIGITS[currentDigit]);            currentValue >>>= 4;        }         return stringBuffer.reverse().toString();    }     /**     * Converts a int value to a hexadecimal String of length 8. Includes     * leading zeros if necessary.     *     * @param value The int value to be converted.     * @return The hexadecimal string representation of the int value.     */    public static String toFullHexString(int value) {        int currentValue = value;        StringBuffer stringBuffer = new StringBuffer(8);        for(int i = 0; i < 8; i++) {            int currentDigit = currentValue & 0xf;            stringBuffer.append(HEX_DIGITS[currentDigit]);            currentValue >>>= 4;        }         return stringBuffer.reverse().toString();    }     /**     * converts a long value to a hexadecimal String     *     * @param value the long value to be converted     * @return the hexadecimal string representation of the long value     */    public static String toHexString(long value) {        return Long.toHexString(value);    }     /**     * Converts a byte array to a hexadecimal String. Each byte is presented by     * its two digit hex-code; 0x0A -> "0a", 0x00 -> "00". No leading "0x" is     * included in the result.     *     * @param value the byte array to be converted     * @return the hexadecimal string representation of the byte array     */    public static String toHexString(byte[] value) {        if (value == null) {            return null;        }         StringBuffer buffer = new StringBuffer(2 * value.length);        int          single;         for (int i = 0; i < value.length; i++) {            single = value[i] & 0xFF;             if (single < 0x10) {                buffer.append('0');            }             buffer.append(Integer.toString(single, 16));        }         return buffer.toString();    }     /**     * converts a long value to a binary String     *     * @param value the long value to be converted     * @return the binary string representation of the long value     */    public static String toBinaryString(long value) {        return Long.toString(value, 2);    }     /**     * converts a byte array to a binary String     *     * @param value the byte array to be converted     * @return the binary string representation of the byte array     */    public static String toBinaryString(byte[] value) {        BigInteger helpBigInteger = new BigInteger(1, value);         return helpBigInteger.toString(2);    }     private static class Flags {        private final long[] flagIds;        private final String[] flagNames;        Flags(long[] flagIds, String[] flagNames) {            if (flagIds.length != flagNames.length) {                throw new AssertionError("Array lengths do not match");            }            this.flagIds = flagIds;            this.flagNames = flagNames;        }        String toString(long val) {            StringBuilder sb = new StringBuilder();            boolean first = true;            for (int i = 0; i < flagIds.length; i++) {                if ((val & flagIds[i]) != 0) {                    if (first == false) {                        sb.append(" | ");                    }                    sb.append(flagNames[i]);                    first = false;                }            }            return sb.toString();        }    }     private static final Flags slotInfoFlags = new Flags(new long[] {        CKF_TOKEN_PRESENT,        CKF_REMOVABLE_DEVICE,        CKF_HW_SLOT,    }, new String[] {        "CKF_TOKEN_PRESENT",        "CKF_REMOVABLE_DEVICE",        "CKF_HW_SLOT",    });     /**     * converts the long value flags to a SlotInfoFlag string     *     * @param flags the flags to be converted     * @return the SlotInfoFlag string representation of the flags     */    public static String slotInfoFlagsToString(long flags) {        return slotInfoFlags.toString(flags);    }     private static final Flags tokenInfoFlags = new Flags(new long[] {        CKF_RNG,        CKF_WRITE_PROTECTED,        CKF_LOGIN_REQUIRED,        CKF_USER_PIN_INITIALIZED,        CKF_RESTORE_KEY_NOT_NEEDED,        CKF_CLOCK_ON_TOKEN,        CKF_PROTECTED_AUTHENTICATION_PATH,        CKF_DUAL_CRYPTO_OPERATIONS,        CKF_TOKEN_INITIALIZED,        CKF_SECONDARY_AUTHENTICATION,        CKF_USER_PIN_COUNT_LOW,        CKF_USER_PIN_FINAL_TRY,        CKF_USER_PIN_LOCKED,        CKF_USER_PIN_TO_BE_CHANGED,        CKF_SO_PIN_COUNT_LOW,        CKF_SO_PIN_FINAL_TRY,        CKF_SO_PIN_LOCKED,        CKF_SO_PIN_TO_BE_CHANGED,    }, new String[] {        "CKF_RNG",        "CKF_WRITE_PROTECTED",        "CKF_LOGIN_REQUIRED",        "CKF_USER_PIN_INITIALIZED",        "CKF_RESTORE_KEY_NOT_NEEDED",        "CKF_CLOCK_ON_TOKEN",        "CKF_PROTECTED_AUTHENTICATION_PATH",        "CKF_DUAL_CRYPTO_OPERATIONS",        "CKF_TOKEN_INITIALIZED",        "CKF_SECONDARY_AUTHENTICATION",        "CKF_USER_PIN_COUNT_LOW",        "CKF_USER_PIN_FINAL_TRY",        "CKF_USER_PIN_LOCKED",        "CKF_USER_PIN_TO_BE_CHANGED",        "CKF_SO_PIN_COUNT_LOW",        "CKF_SO_PIN_FINAL_TRY",        "CKF_SO_PIN_LOCKED",        "CKF_SO_PIN_TO_BE_CHANGED",    });     /**     * converts long value flags to a TokenInfoFlag string     *     * @param flags the flags to be converted     * @return the TokenInfoFlag string representation of the flags     */    public static String tokenInfoFlagsToString(long flags) {        return tokenInfoFlags.toString(flags);    }     private static final Flags sessionInfoFlags = new Flags(new long[] {        CKF_RW_SESSION,        CKF_SERIAL_SESSION,    }, new String[] {        "CKF_RW_SESSION",        "CKF_SERIAL_SESSION",    });     /**     * converts the long value flags to a SessionInfoFlag string     *     * @param flags the flags to be converted     * @return the SessionInfoFlag string representation of the flags     */    public static String sessionInfoFlagsToString(long flags) {        return sessionInfoFlags.toString(flags);    }     /**     * converts the long value state to a SessionState string     *     * @param state the state to be converted     * @return the SessionState string representation of the state     */    public static String sessionStateToString(long state) {        String name;         if (state == CKS_RO_PUBLIC_SESSION) {            name = "CKS_RO_PUBLIC_SESSION";        } else if (state == CKS_RO_USER_FUNCTIONS) {            name = "CKS_RO_USER_FUNCTIONS";        } else if (state == CKS_RW_PUBLIC_SESSION) {            name = "CKS_RW_PUBLIC_SESSION";        } else if (state == CKS_RW_USER_FUNCTIONS) {            name = "CKS_RW_USER_FUNCTIONS";        } else if (state == CKS_RW_SO_FUNCTIONS) {            name = "CKS_RW_SO_FUNCTIONS";        } else {            name = "ERROR: unknown session state 0x" + toFullHexString(state);        }         return name;    }     private static final Flags mechanismInfoFlags = new Flags(new long[] {        CKF_HW,        CKF_ENCRYPT,        CKF_DECRYPT,        CKF_DIGEST,        CKF_SIGN,        CKF_SIGN_RECOVER,        CKF_VERIFY,        CKF_VERIFY_RECOVER,        CKF_GENERATE,        CKF_GENERATE_KEY_PAIR,        CKF_WRAP,        CKF_UNWRAP,        CKF_DERIVE,        CKF_EC_F_P,        CKF_EC_F_2M,        CKF_EC_ECPARAMETERS,        CKF_EC_NAMEDCURVE,        CKF_EC_UNCOMPRESS,        CKF_EC_COMPRESS,        CKF_EXTENSION,    }, new String[] {        "CKF_HW",        "CKF_ENCRYPT",        "CKF_DECRYPT",        "CKF_DIGEST",        "CKF_SIGN",        "CKF_SIGN_RECOVER",        "CKF_VERIFY",        "CKF_VERIFY_RECOVER",        "CKF_GENERATE",        "CKF_GENERATE_KEY_PAIR",        "CKF_WRAP",        "CKF_UNWRAP",        "CKF_DERIVE",        "CKF_EC_F_P",        "CKF_EC_F_2M",        "CKF_EC_ECPARAMETERS",        "CKF_EC_NAMEDCURVE",        "CKF_EC_UNCOMPRESS",        "CKF_EC_COMPRESS",        "CKF_EXTENSION",    });     /**     * converts the long value flags to a MechanismInfoFlag string     *     * @param flags the flags to be converted     * @return the MechanismInfoFlag string representation of the flags     */    public static String mechanismInfoFlagsToString(long flags) {        return mechanismInfoFlags.toString(flags);    }     private static String getName(Map<Integer,String> nameMap, long id) {        String name = null;        if ((id >>> 32) == 0) {            name = nameMap.get(Integer.valueOf((int)id));        }        if (name == null) {            name = "Unknown 0x" + toFullHexString(id);        }        return name;    }     public static long getId(Map<String,Integer> idMap, String name) {        Integer mech = idMap.get(name);        if (mech == null) {            throw new IllegalArgumentException("Unknown name " + name);        }        return mech.intValue() & 0xffffffffL;    }     public static String getMechanismName(long id) {        return getName(mechNames, id);    }     public static long getMechanismId(String name) {        return getId(mechIds, name);    }     public static String getKeyName(long id) {        return getName(keyNames, id);    }     public static long getKeyId(String name) {        return getId(keyIds, name);    }     public static String getAttributeName(long id) {        return getName(attributeNames, id);    }     public static long getAttributeId(String name) {        return getId(attributeIds, name);    }     public static String getObjectClassName(long id) {        return getName(objectClassNames, id);    }     public static long getObjectClassId(String name) {        return getId(objectClassIds, name);    }     /**     * Check the given arrays for equalitiy. This method considers both arrays as     * equal, if both are <code>null</code> or both have the same length and     * contain exactly the same byte values.     *     * @param array1 The first array.     * @param array2 The second array.     * @return True, if both arrays are <code>null</code> or both have the same     *         length and contain exactly the same byte values. False, otherwise.     * @preconditions     * @postconditions     */    public static boolean equals(byte[] array1, byte[] array2) {        return Arrays.equals(array1, array2);    }     /**     * Check the given arrays for equalitiy. This method considers both arrays as     * equal, if both are <code>null</code> or both have the same length and     * contain exactly the same char values.     *     * @param array1 The first array.     * @param array2 The second array.     * @return True, if both arrays are <code>null</code> or both have the same     *         length and contain exactly the same char values. False, otherwise.     * @preconditions     * @postconditions     */    public static boolean equals(char[] array1, char[] array2) {        return Arrays.equals(array1, array2);    }     /**     * Check the given dates for equalitiy. This method considers both dates as     * equal, if both are <code>null</code> or both contain exactly the same char     * values.     *     * @param date1 The first date.     * @param date2 The second date.     * @return True, if both dates are <code>null</code> or both contain the same     *         char values. False, otherwise.     * @preconditions     * @postconditions     */    public static boolean equals(CK_DATE date1, CK_DATE date2) {        boolean equal = false;         if (date1 == date2) {            equal = true;        } else if ((date1 != null) && (date2 != null)) {            equal = equals(date1.year, date2.year)              && equals(date1.month, date2.month)              && equals(date1.day, date2.day);        } else {

Lines 1–500 of 916.