1 /* |
1 /* |
2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package sun.security.ssl; |
26 package sun.security.ssl; |
27 |
27 |
|
28 import java.math.BigInteger; |
|
29 import java.util.*; |
|
30 import java.util.regex.Pattern; |
28 import javax.net.ssl.*; |
31 import javax.net.ssl.*; |
29 import java.util.*; |
|
30 import sun.net.util.IPAddressUtil; |
32 import sun.net.util.IPAddressUtil; |
|
33 import sun.security.action.GetPropertyAction; |
31 |
34 |
32 /** |
35 /** |
33 * A utility class to share the static methods. |
36 * A utility class to share the static methods. |
34 */ |
37 */ |
35 final class Utilities { |
38 final class Utilities { |
36 /** |
|
37 * hex digits |
|
38 */ |
|
39 static final char[] hexDigits = "0123456789ABCDEF".toCharArray(); |
39 static final char[] hexDigits = "0123456789ABCDEF".toCharArray(); |
|
40 private static final String indent = " "; |
|
41 private static final Pattern lineBreakPatern = |
|
42 Pattern.compile("\\r\\n|\\n|\\r"); |
40 |
43 |
41 /** |
44 /** |
42 * Puts {@code hostname} into the {@code serverNames} list. |
45 * Puts {@code hostname} into the {@code serverNames} list. |
43 * <P> |
46 * <P> |
44 * If the {@code serverNames} does not look like a legal FQDN, it will |
47 * If the {@code serverNames} does not look like a legal FQDN, it will |
64 boolean reset = false; |
67 boolean reset = false; |
65 for (int i = 0; i < size; i++) { |
68 for (int i = 0; i < size; i++) { |
66 SNIServerName serverName = sniList.get(i); |
69 SNIServerName serverName = sniList.get(i); |
67 if (serverName.getType() == StandardConstants.SNI_HOST_NAME) { |
70 if (serverName.getType() == StandardConstants.SNI_HOST_NAME) { |
68 sniList.set(i, sniHostName); |
71 sniList.set(i, sniHostName); |
69 if (Debug.isOn("ssl")) { |
72 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { |
70 System.out.println(Thread.currentThread().getName() + |
73 SSLLogger.fine( |
71 ", the previous server name in SNI (" + serverName + |
74 "the previous server name in SNI (" + serverName + |
72 ") was replaced with (" + sniHostName + ")"); |
75 ") was replaced with (" + sniHostName + ")"); |
73 } |
76 } |
74 reset = true; |
77 reset = true; |
75 break; |
78 break; |
76 } |
79 } |
105 |
108 |
106 try { |
109 try { |
107 sniHostName = new SNIHostName(hostname); |
110 sniHostName = new SNIHostName(hostname); |
108 } catch (IllegalArgumentException iae) { |
111 } catch (IllegalArgumentException iae) { |
109 // don't bother to handle illegal host_name |
112 // don't bother to handle illegal host_name |
110 if (Debug.isOn("ssl")) { |
113 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { |
111 System.out.println(Thread.currentThread().getName() + |
114 SSLLogger.fine(hostname + "\" " + |
112 ", \"" + hostname + "\" " + |
|
113 "is not a legal HostName for server name indication"); |
115 "is not a legal HostName for server name indication"); |
114 } |
116 } |
115 } |
117 } |
116 } |
118 } |
117 |
119 |
118 return sniHostName; |
120 return sniHostName; |
119 } |
121 } |
|
122 |
|
123 /** |
|
124 * Return the value of the boolean System property propName. |
|
125 * |
|
126 * Note use of privileged action. Do NOT make accessible to applications. |
|
127 */ |
|
128 static boolean getBooleanProperty(String propName, boolean defaultValue) { |
|
129 // if set, require value of either true or false |
|
130 String b = GetPropertyAction.privilegedGetProperty(propName); |
|
131 if (b == null) { |
|
132 return defaultValue; |
|
133 } else if (b.equalsIgnoreCase("false")) { |
|
134 return false; |
|
135 } else if (b.equalsIgnoreCase("true")) { |
|
136 return true; |
|
137 } else { |
|
138 throw new RuntimeException("Value of " + propName |
|
139 + " must either be 'true' or 'false'"); |
|
140 } |
|
141 } |
|
142 |
|
143 static String indent(String source) { |
|
144 return Utilities.indent(source, indent); |
|
145 } |
|
146 |
|
147 static String indent(String source, String prefix) { |
|
148 StringBuilder builder = new StringBuilder(); |
|
149 if (source == null) { |
|
150 builder.append("\n" + prefix + "<blank message>"); |
|
151 } else { |
|
152 String[] lines = lineBreakPatern.split(source); |
|
153 boolean isFirst = true; |
|
154 for (String line : lines) { |
|
155 if (isFirst) { |
|
156 isFirst = false; |
|
157 } else { |
|
158 builder.append("\n"); |
|
159 } |
|
160 builder.append(prefix).append(line); |
|
161 } |
|
162 } |
|
163 |
|
164 return builder.toString(); |
|
165 } |
|
166 |
|
167 static String toHexString(byte b) { |
|
168 return String.valueOf(hexDigits[(b >> 4) & 0x0F]) + |
|
169 String.valueOf(hexDigits[b & 0x0F]); |
|
170 } |
|
171 |
|
172 static String byte16HexString(int id) { |
|
173 return "0x" + |
|
174 hexDigits[(id >> 12) & 0x0F] + hexDigits[(id >> 8) & 0x0F] + |
|
175 hexDigits[(id >> 4) & 0x0F] + hexDigits[id & 0x0F]; |
|
176 } |
|
177 |
|
178 static String toHexString(byte[] bytes) { |
|
179 if (bytes == null || bytes.length == 0) { |
|
180 return ""; |
|
181 } |
|
182 |
|
183 StringBuilder builder = new StringBuilder(bytes.length * 3); |
|
184 boolean isFirst = true; |
|
185 for (byte b : bytes) { |
|
186 if (isFirst) { |
|
187 isFirst = false; |
|
188 } else { |
|
189 builder.append(' '); |
|
190 } |
|
191 |
|
192 builder.append(hexDigits[(b >> 4) & 0x0F]); |
|
193 builder.append(hexDigits[b & 0x0F]); |
|
194 } |
|
195 return builder.toString(); |
|
196 } |
|
197 |
|
198 static String toHexString(long lv) { |
|
199 StringBuilder builder = new StringBuilder(128); |
|
200 |
|
201 boolean isFirst = true; |
|
202 do { |
|
203 if (isFirst) { |
|
204 isFirst = false; |
|
205 } else { |
|
206 builder.append(' '); |
|
207 } |
|
208 |
|
209 builder.append(hexDigits[(int)(lv & 0x0F)]); |
|
210 lv >>>= 4; |
|
211 builder.append(hexDigits[(int)(lv & 0x0F)]); |
|
212 lv >>>= 4; |
|
213 } while (lv != 0); |
|
214 builder.reverse(); |
|
215 |
|
216 return builder.toString(); |
|
217 } |
|
218 |
|
219 /** |
|
220 * Utility method to convert a BigInteger to a byte array in unsigned |
|
221 * format as needed in the handshake messages. BigInteger uses |
|
222 * 2's complement format, i.e. it prepends an extra zero if the MSB |
|
223 * is set. We remove that. |
|
224 */ |
|
225 static byte[] toByteArray(BigInteger bi) { |
|
226 byte[] b = bi.toByteArray(); |
|
227 if ((b.length > 1) && (b[0] == 0)) { |
|
228 int n = b.length - 1; |
|
229 byte[] newarray = new byte[n]; |
|
230 System.arraycopy(b, 1, newarray, 0, n); |
|
231 b = newarray; |
|
232 } |
|
233 return b; |
|
234 } |
120 } |
235 } |