1/*
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package sun.security.pkcs11;
27
28import java.math.BigInteger;
29import java.security.*;
30
31/**
32 * Collection of static utility methods.
33 *
34 * @author  Andreas Sterbenz
35 * @since   1.5
36 */
37public final class P11Util {
38
39    private static Object LOCK = new Object();
40
41    private static volatile Provider sun, sunRsaSign, sunJce;
42
43    private P11Util() {
44        // empty
45    }
46
47    static Provider getSunProvider() {
48        Provider p = sun;
49        if (p == null) {
50            synchronized (LOCK) {
51                p = getProvider
52                    (sun, "SUN", "sun.security.provider.Sun");
53                sun = p;
54            }
55        }
56        return p;
57    }
58
59    static Provider getSunRsaSignProvider() {
60        Provider p = sunRsaSign;
61        if (p == null) {
62            synchronized (LOCK) {
63                p = getProvider
64                    (sunRsaSign, "SunRsaSign", "sun.security.rsa.SunRsaSign");
65                sunRsaSign = p;
66            }
67        }
68        return p;
69    }
70
71    static Provider getSunJceProvider() {
72        Provider p = sunJce;
73        if (p == null) {
74            synchronized (LOCK) {
75                p = getProvider
76                    (sunJce, "SunJCE", "com.sun.crypto.provider.SunJCE");
77                sunJce = p;
78            }
79        }
80        return p;
81    }
82
83    private static Provider getProvider(Provider p, String providerName,
84            String className) {
85        if (p != null) {
86            return p;
87        }
88        p = Security.getProvider(providerName);
89        if (p == null) {
90            try {
91                @SuppressWarnings("deprecation")
92                Object o = Class.forName(className).newInstance();
93                p = (Provider)o;
94            } catch (Exception e) {
95                throw new ProviderException
96                        ("Could not find provider " + providerName, e);
97            }
98        }
99        return p;
100    }
101
102    static byte[] convert(byte[] input, int offset, int len) {
103        if ((offset == 0) && (len == input.length)) {
104            return input;
105        } else {
106            byte[] t = new byte[len];
107            System.arraycopy(input, offset, t, 0, len);
108            return t;
109        }
110    }
111
112    static byte[] subarray(byte[] b, int ofs, int len) {
113        byte[] out = new byte[len];
114        System.arraycopy(b, ofs, out, 0, len);
115        return out;
116    }
117
118    static byte[] concat(byte[] b1, byte[] b2) {
119        byte[] b = new byte[b1.length + b2.length];
120        System.arraycopy(b1, 0, b, 0, b1.length);
121        System.arraycopy(b2, 0, b, b1.length, b2.length);
122        return b;
123    }
124
125    static long[] concat(long[] b1, long[] b2) {
126        if (b1.length == 0) {
127            return b2;
128        }
129        long[] b = new long[b1.length + b2.length];
130        System.arraycopy(b1, 0, b, 0, b1.length);
131        System.arraycopy(b2, 0, b, b1.length, b2.length);
132        return b;
133    }
134
135    public static byte[] getMagnitude(BigInteger bi) {
136        byte[] b = bi.toByteArray();
137        if ((b.length > 1) && (b[0] == 0)) {
138            int n = b.length - 1;
139            byte[] newarray = new byte[n];
140            System.arraycopy(b, 1, newarray, 0, n);
141            b = newarray;
142        }
143        return b;
144    }
145
146    static byte[] getBytesUTF8(String s) {
147        try {
148            return s.getBytes("UTF8");
149        } catch (java.io.UnsupportedEncodingException e) {
150            throw new RuntimeException(e);
151        }
152    }
153
154    static byte[] sha1(byte[] data) {
155        try {
156            MessageDigest md = MessageDigest.getInstance("SHA-1");
157            md.update(data);
158            return md.digest();
159        } catch (GeneralSecurityException e) {
160            throw new ProviderException(e);
161        }
162    }
163
164    private final static char[] hexDigits = "0123456789abcdef".toCharArray();
165
166    static String toString(byte[] b) {
167        if (b == null) {
168            return "(null)";
169        }
170        StringBuilder sb = new StringBuilder(b.length * 3);
171        for (int i = 0; i < b.length; i++) {
172            int k = b[i] & 0xff;
173            if (i != 0) {
174                sb.append(':');
175            }
176            sb.append(hexDigits[k >>> 4]);
177            sb.append(hexDigits[k & 0xf]);
178        }
179        return sb.toString();
180    }
181
182}
183