--- old/src/java.base/share/classes/sun/security/ssl/Utilities.java 2018-05-11 15:06:23.184201100 -0700 +++ new/src/java.base/share/classes/sun/security/ssl/Utilities.java 2018-05-11 15:06:22.705759000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,18 +25,21 @@ package sun.security.ssl; -import javax.net.ssl.*; +import java.math.BigInteger; import java.util.*; +import java.util.regex.Pattern; +import javax.net.ssl.*; import sun.net.util.IPAddressUtil; +import sun.security.action.GetPropertyAction; /** * A utility class to share the static methods. */ final class Utilities { - /** - * hex digits - */ static final char[] hexDigits = "0123456789ABCDEF".toCharArray(); + private static final String indent = " "; + private static final Pattern lineBreakPatern = + Pattern.compile("\\r\\n|\\n|\\r"); /** * Puts {@code hostname} into the {@code serverNames} list. @@ -66,9 +69,9 @@ SNIServerName serverName = sniList.get(i); if (serverName.getType() == StandardConstants.SNI_HOST_NAME) { sniList.set(i, sniHostName); - if (Debug.isOn("ssl")) { - System.out.println(Thread.currentThread().getName() + - ", the previous server name in SNI (" + serverName + + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.fine( + "the previous server name in SNI (" + serverName + ") was replaced with (" + sniHostName + ")"); } reset = true; @@ -107,9 +110,8 @@ sniHostName = new SNIHostName(hostname); } catch (IllegalArgumentException iae) { // don't bother to handle illegal host_name - if (Debug.isOn("ssl")) { - System.out.println(Thread.currentThread().getName() + - ", \"" + hostname + "\" " + + if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { + SSLLogger.fine(hostname + "\" " + "is not a legal HostName for server name indication"); } } @@ -117,4 +119,117 @@ return sniHostName; } + + /** + * Return the value of the boolean System property propName. + * + * Note use of privileged action. Do NOT make accessible to applications. + */ + static boolean getBooleanProperty(String propName, boolean defaultValue) { + // if set, require value of either true or false + String b = GetPropertyAction.privilegedGetProperty(propName); + if (b == null) { + return defaultValue; + } else if (b.equalsIgnoreCase("false")) { + return false; + } else if (b.equalsIgnoreCase("true")) { + return true; + } else { + throw new RuntimeException("Value of " + propName + + " must either be 'true' or 'false'"); + } + } + + static String indent(String source) { + return Utilities.indent(source, indent); + } + + static String indent(String source, String prefix) { + StringBuilder builder = new StringBuilder(); + if (source == null) { + builder.append("\n" + prefix + ""); + } else { + String[] lines = lineBreakPatern.split(source); + boolean isFirst = true; + for (String line : lines) { + if (isFirst) { + isFirst = false; + } else { + builder.append("\n"); + } + builder.append(prefix).append(line); + } + } + + return builder.toString(); + } + + static String toHexString(byte b) { + return String.valueOf(hexDigits[(b >> 4) & 0x0F]) + + String.valueOf(hexDigits[b & 0x0F]); + } + + static String byte16HexString(int id) { + return "0x" + + hexDigits[(id >> 12) & 0x0F] + hexDigits[(id >> 8) & 0x0F] + + hexDigits[(id >> 4) & 0x0F] + hexDigits[id & 0x0F]; + } + + static String toHexString(byte[] bytes) { + if (bytes == null || bytes.length == 0) { + return ""; + } + + StringBuilder builder = new StringBuilder(bytes.length * 3); + boolean isFirst = true; + for (byte b : bytes) { + if (isFirst) { + isFirst = false; + } else { + builder.append(' '); + } + + builder.append(hexDigits[(b >> 4) & 0x0F]); + builder.append(hexDigits[b & 0x0F]); + } + return builder.toString(); + } + + static String toHexString(long lv) { + StringBuilder builder = new StringBuilder(128); + + boolean isFirst = true; + do { + if (isFirst) { + isFirst = false; + } else { + builder.append(' '); + } + + builder.append(hexDigits[(int)(lv & 0x0F)]); + lv >>>= 4; + builder.append(hexDigits[(int)(lv & 0x0F)]); + lv >>>= 4; + } while (lv != 0); + builder.reverse(); + + return builder.toString(); + } + + /** + * Utility method to convert a BigInteger to a byte array in unsigned + * format as needed in the handshake messages. BigInteger uses + * 2's complement format, i.e. it prepends an extra zero if the MSB + * is set. We remove that. + */ + static byte[] toByteArray(BigInteger bi) { + byte[] b = bi.toByteArray(); + if ((b.length > 1) && (b[0] == 0)) { + int n = b.length - 1; + byte[] newarray = new byte[n]; + System.arraycopy(b, 1, newarray, 0, n); + b = newarray; + } + return b; + } }