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
26package sun.security.ssl;
27
28import java.security.AlgorithmConstraints;
29import java.security.CryptoPrimitive;
30
31import java.util.Set;
32import java.util.HashSet;
33import java.util.Map;
34import java.util.EnumSet;
35import java.util.TreeMap;
36import java.util.Collection;
37import java.util.Collections;
38import 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 */
61final 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