History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/ssl/SignatureAndHashAlgorithm.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/ssl/SignatureAndHashAlgorithm.java+387−0
@@ -0,0 +1,387 @@
1+/*
2+ * Copyright (c) 2010, 2011, 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+
26+package sun.security.ssl;
27+
28+import java.security.AlgorithmConstraints;
29+import java.security.CryptoPrimitive;
30+
31+import java.util.Set;
32+import java.util.HashSet;
33+import java.util.Map;
34+import java.util.EnumSet;
35+import java.util.TreeMap;
36+import java.util.Collection;
37+import java.util.Collections;
38+import java.util.ArrayList;
39+
40+/**
41+ * Signature and hash algorithm.
42+ *
43+ * [RFC5246] The client uses the "signature_algorithms" extension to
44+ * indicate to the server which signature/hash algorithm pairs may be
45+ * used in digital signatures. The "extension_data" field of this
46+ * extension contains a "supported_signature_algorithms" value.
47+ *
48+ * enum {
49+ * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
50+ * sha512(6), (255)
51+ * } HashAlgorithm;
52+ *
53+ * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
54+ * SignatureAlgorithm;
55+ *
56+ * struct {
57+ * HashAlgorithm hash;
58+ * SignatureAlgorithm signature;
59+ * } SignatureAndHashAlgorithm;
60+ */
61+final class SignatureAndHashAlgorithm {
62+
63+ // minimum priority for default enabled algorithms
64+ final static int SUPPORTED_ALG_PRIORITY_MAX_NUM = 0x00F0;
65+
66+ // performance optimization
67+ private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
68+ EnumSet.of(CryptoPrimitive.SIGNATURE);
69+
70+ // supported pairs of signature and hash algorithm
71+ private final static Map<Integer, SignatureAndHashAlgorithm> supportedMap;
72+ private final static Map<Integer, SignatureAndHashAlgorithm> priorityMap;
73+
74+ // the hash algorithm
75+ private HashAlgorithm hash;
76+
77+ // the signature algorithm
78+ private SignatureAlgorithm signature;
79+
80+ // id in 16 bit MSB format, i.e. 0x0603 for SHA512withECDSA
81+ private int id;
82+
83+ // the standard algorithm name, for example "SHA512withECDSA"
84+ private String algorithm;
85+
86+ // Priority for the preference order. The lower the better.
87+ //
88+ // If the algorithm is unsupported, its priority should be bigger
89+ // than SUPPORTED_ALG_PRIORITY_MAX_NUM.
90+ private int priority;
91+
92+ // constructor for supported algorithm
93+ private SignatureAndHashAlgorithm(HashAlgorithm hash,
94+ SignatureAlgorithm signature, String algorithm, int priority) {
95+ this.hash = hash;
96+ this.signature = signature;
97+ this.algorithm = algorithm;
98+ this.id = ((hash.value & 0xFF) << 8) | (signature.value & 0xFF);
99+ this.priority = priority;
100+ }
101+
102+ // constructor for unsupported algorithm
103+ private SignatureAndHashAlgorithm(String algorithm, int id, int sequence) {
104+ this.hash = HashAlgorithm.valueOf((id >> 8) & 0xFF);
105+ this.signature = SignatureAlgorithm.valueOf(id & 0xFF);
106+ this.algorithm = algorithm;
107+ this.id = id;
108+
109+ // add one more to the sequece number, in case that the number is zero
110+ this.priority = SUPPORTED_ALG_PRIORITY_MAX_NUM + sequence + 1;
111+ }
112+
113+ // Note that we do not use the sequence argument for supported algorithms,
114+ // so please don't sort by comparing the objects read from handshake
115+ // messages.
116+ static SignatureAndHashAlgorithm valueOf(int hash,
117+ int signature, int sequence) {
118+ hash &= 0xFF;
119+ signature &= 0xFF;
120+
121+ int id = (hash << 8) | signature;
122+ SignatureAndHashAlgorithm signAlg = supportedMap.get(id);
123+ if (signAlg == null) {
124+ // unsupported algorithm
125+ signAlg = new SignatureAndHashAlgorithm(
126+ "Unknown (hash:0x" + Integer.toString(hash, 16) +
127+ ", signature:0x" + Integer.toString(signature, 16) + ")",
128+ id, sequence);
129+ }
130+
131+ return signAlg;
132+ }
133+
134+ int getHashValue() {
135+ return (id >> 8) & 0xFF;
136+ }
137+
138+ int getSignatureValue() {
139+ return id & 0xFF;
140+ }
141+
142+ String getAlgorithmName() {
143+ return algorithm;
144+ }
145+
146+ // return the size of a SignatureAndHashAlgorithm structure in TLS record
147+ static int sizeInRecord() {
148+ return 2;
149+ }
150+
151+ // Get local supported algorithm collection complying to
152+ // algorithm constraints
153+ static Collection<SignatureAndHashAlgorithm>
154+ getSupportedAlgorithms(AlgorithmConstraints constraints) {
155+
156+ Collection<SignatureAndHashAlgorithm> supported = new ArrayList<>();
157+ synchronized (priorityMap) {
158+ for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) {
159+ if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM &&
160+ constraints.permits(SIGNATURE_PRIMITIVE_SET,
161+ sigAlg.algorithm, null)) {
162+ supported.add(sigAlg);
163+ }
164+ }
165+ }
166+
167+ return supported;
168+ }
169+
170+ // Get supported algorithm collection from an untrusted collection
171+ static Collection<SignatureAndHashAlgorithm> getSupportedAlgorithms(
172+ Collection<SignatureAndHashAlgorithm> algorithms ) {
173+ Collection<SignatureAndHashAlgorithm> supported = new ArrayList<>();
174+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
175+ if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
176+ supported.add(sigAlg);
177+ }
178+ }
179+
180+ return supported;
181+ }
182+
183+ static String[] getAlgorithmNames(
184+ Collection<SignatureAndHashAlgorithm> algorithms) {
185+ ArrayList<String> algorithmNames = new ArrayList<>();
186+ if (algorithms != null) {
187+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
188+ algorithmNames.add(sigAlg.algorithm);
189+ }
190+ }
191+
192+ String[] array = new String[algorithmNames.size()];
193+ return algorithmNames.toArray(array);
194+ }
195+
196+ static Set<String> getHashAlgorithmNames(
197+ Collection<SignatureAndHashAlgorithm> algorithms) {
198+ Set<String> algorithmNames = new HashSet<>();
199+ if (algorithms != null) {
200+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
201+ if (sigAlg.hash.value > 0) {
202+ algorithmNames.add(sigAlg.hash.standardName);
203+ }
204+ }
205+ }
206+
207+ return algorithmNames;
208+ }
209+
210+ static String getHashAlgorithmName(SignatureAndHashAlgorithm algorithm) {
211+ return algorithm.hash.standardName;
212+ }
213+
214+ private static void supports(HashAlgorithm hash,
215+ SignatureAlgorithm signature, String algorithm, int priority) {
216+
217+ SignatureAndHashAlgorithm pair =
218+ new SignatureAndHashAlgorithm(hash, signature, algorithm, priority);
219+ if (supportedMap.put(pair.id, pair) != null) {
220+ throw new RuntimeException(
221+ "Duplicate SignatureAndHashAlgorithm definition, id: " +
222+ pair.id);
223+ }
224+ if (priorityMap.put(pair.priority, pair) != null) {
225+ throw new RuntimeException(
226+ "Duplicate SignatureAndHashAlgorithm definition, priority: " +
227+ pair.priority);
228+ }
229+ }
230+
231+ static SignatureAndHashAlgorithm getPreferableAlgorithm(
232+ Collection<SignatureAndHashAlgorithm> algorithms, String expected) {
233+
234+ if (expected == null && !algorithms.isEmpty()) {
235+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
236+ if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
237+ return sigAlg;
238+ }
239+ }
240+
241+ return null; // no supported algorithm
242+ }
243+
244+
245+ for (SignatureAndHashAlgorithm algorithm : algorithms) {
246+ int signValue = algorithm.id & 0xFF;
247+ if ((expected.equalsIgnoreCase("dsa") &&
248+ signValue == SignatureAlgorithm.DSA.value) ||
249+ (expected.equalsIgnoreCase("rsa") &&
250+ signValue == SignatureAlgorithm.RSA.value) ||
251+ (expected.equalsIgnoreCase("ecdsa") &&
252+ signValue == SignatureAlgorithm.ECDSA.value) ||
253+ (expected.equalsIgnoreCase("ec") &&
254+ signValue == SignatureAlgorithm.ECDSA.value)) {
255+ return algorithm;
256+ }
257+ }
258+
259+ return null;
260+ }
261+
262+ static enum HashAlgorithm {
263+ UNDEFINED("undefined", "", -1),
264+ NONE( "none", "NONE", 0),
265+ MD5( "md5", "MD5", 1),
266+ SHA1( "sha1", "SHA-1", 2),
267+ SHA224( "sha224", "SHA-224", 3),
268+ SHA256( "sha256", "SHA-256", 4),
269+ SHA384( "sha384", "SHA-384", 5),
270+ SHA512( "sha512", "SHA-512", 6);
271+
272+ final String name; // not the standard signature algorithm name
273+ // except the UNDEFINED, other names are defined
274+ // by TLS 1.2 protocol
275+ final String standardName; // the standard MessageDigest algorithm name
276+ final int value;
277+
278+ private HashAlgorithm(String name, String standardName, int value) {
279+ this.name = name;
280+ this.standardName = standardName;
281+ this.value = value;
282+ }
283+
284+ static HashAlgorithm valueOf(int value) {
285+ HashAlgorithm algorithm = UNDEFINED;
286+ switch (value) {
287+ case 0:
288+ algorithm = NONE;
289+ break;
290+ case 1:
291+ algorithm = MD5;
292+ break;
293+ case 2:
294+ algorithm = SHA1;
295+ break;
296+ case 3:
297+ algorithm = SHA224;
298+ break;
299+ case 4:
300+ algorithm = SHA256;
301+ break;
302+ case 5:
303+ algorithm = SHA384;
304+ break;
305+ case 6:
306+ algorithm = SHA512;
307+ break;
308+ }
309+
310+ return algorithm;
311+ }
312+ }
313+
314+ static enum SignatureAlgorithm {
315+ UNDEFINED("undefined", -1),
316+ ANONYMOUS("anonymous", 0),
317+ RSA( "rsa", 1),
318+ DSA( "dsa", 2),
319+ ECDSA( "ecdsa", 3);
320+
321+ final String name; // not the standard signature algorithm name
322+ // except the UNDEFINED, other names are defined
323+ // by TLS 1.2 protocol
324+ final int value;
325+
326+ private SignatureAlgorithm(String name, int value) {
327+ this.name = name;
328+ this.value = value;
329+ }
330+
331+ static SignatureAlgorithm valueOf(int value) {
332+ SignatureAlgorithm algorithm = UNDEFINED;
333+ switch (value) {
334+ case 0:
335+ algorithm = ANONYMOUS;
336+ break;
337+ case 1:
338+ algorithm = RSA;
339+ break;
340+ case 2:
341+ algorithm = DSA;
342+ break;
343+ case 3:
344+ algorithm = ECDSA;
345+ break;
346+ }
347+
348+ return algorithm;
349+ }
350+ }
351+
352+ static {
353+ supportedMap = Collections.synchronizedSortedMap(
354+ new TreeMap<Integer, SignatureAndHashAlgorithm>());
355+ priorityMap = Collections.synchronizedSortedMap(
356+ new TreeMap<Integer, SignatureAndHashAlgorithm>());
357+
358+ synchronized (supportedMap) {
359+ int p = SUPPORTED_ALG_PRIORITY_MAX_NUM;
360+ supports(HashAlgorithm.MD5, SignatureAlgorithm.RSA,
361+ "MD5withRSA", --p);
362+ supports(HashAlgorithm.SHA1, SignatureAlgorithm.DSA,
363+ "SHA1withDSA", --p);
364+ supports(HashAlgorithm.SHA1, SignatureAlgorithm.RSA,
365+ "SHA1withRSA", --p);
366+ supports(HashAlgorithm.SHA1, SignatureAlgorithm.ECDSA,
367+ "SHA1withECDSA", --p);
368+ supports(HashAlgorithm.SHA224, SignatureAlgorithm.RSA,
369+ "SHA224withRSA", --p);
370+ supports(HashAlgorithm.SHA224, SignatureAlgorithm.ECDSA,
371+ "SHA224withECDSA", --p);
372+ supports(HashAlgorithm.SHA256, SignatureAlgorithm.RSA,
373+ "SHA256withRSA", --p);
374+ supports(HashAlgorithm.SHA256, SignatureAlgorithm.ECDSA,
375+ "SHA256withECDSA", --p);
376+ supports(HashAlgorithm.SHA384, SignatureAlgorithm.RSA,
377+ "SHA384withRSA", --p);
378+ supports(HashAlgorithm.SHA384, SignatureAlgorithm.ECDSA,
379+ "SHA384withECDSA", --p);
380+ supports(HashAlgorithm.SHA512, SignatureAlgorithm.RSA,
381+ "SHA512withRSA", --p);
382+ supports(HashAlgorithm.SHA512, SignatureAlgorithm.ECDSA,
383+ "SHA512withECDSA", --p);
384+ }
385+ }
386+}
387+