This commit is contained in:
Henry Jen 2019-07-17 00:21:02 +00:00
commit f860f94696
25 changed files with 534 additions and 156 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1363,8 +1363,11 @@ abstract class ChaCha20Cipher extends CipherSpi {
// Calculate and compare the tag. Only do the decryption // Calculate and compare the tag. Only do the decryption
// if and only if the tag matches. // if and only if the tag matches.
authFinalizeData(ctPlusTag, 0, ctLen, tag, 0); authFinalizeData(ctPlusTag, 0, ctLen, tag, 0);
if (Arrays.compare(ctPlusTag, ctLen, ctPlusTagLen, long tagCompare = ((long)asLongView.get(ctPlusTag, ctLen) ^
tag, 0, tag.length) != 0) { (long)asLongView.get(tag, 0)) |
((long)asLongView.get(ctPlusTag, ctLen + Long.BYTES) ^
(long)asLongView.get(tag, Long.BYTES));
if (tagCompare != 0) {
throw new AEADBadTagException("Tag mismatch"); throw new AEADBadTagException("Tag mismatch");
} }
chaCha20Transform(ctPlusTag, 0, ctLen, out, outOff); chaCha20Transform(ctPlusTag, 0, ctLen, out, outOff);

View File

@ -25,8 +25,8 @@
package java.lang; package java.lang;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
/** /**
* The {@code Throwable} class is the superclass of all errors and * The {@code Throwable} class is the superclass of all errors and
@ -904,24 +904,36 @@ public class Throwable implements Serializable {
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields s.defaultReadObject(); // read in all fields
if (suppressedExceptions != null) {
List<Throwable> suppressed = null; // Set suppressed exceptions and stack trace elements fields
if (suppressedExceptions.isEmpty()) { // to marker values until the contents from the serial stream
// Use the sentinel for a zero-length list // are validated.
suppressed = SUPPRESSED_SENTINEL; List<Throwable> candidateSuppressedExceptions = suppressedExceptions;
} else { // Copy Throwables to new list suppressedExceptions = SUPPRESSED_SENTINEL;
suppressed = new ArrayList<>(1);
for (Throwable t : suppressedExceptions) { StackTraceElement[] candidateStackTrace = stackTrace;
stackTrace = UNASSIGNED_STACK.clone();
if (candidateSuppressedExceptions != null) {
int suppressedSize = validateSuppressedExceptionsList(candidateSuppressedExceptions);
if (suppressedSize > 0) { // Copy valid Throwables to new list
var suppList = new ArrayList<Throwable>(Math.min(100, suppressedSize));
for (Throwable t : candidateSuppressedExceptions) {
// Enforce constraints on suppressed exceptions in // Enforce constraints on suppressed exceptions in
// case of corrupt or malicious stream. // case of corrupt or malicious stream.
Objects.requireNonNull(t, NULL_CAUSE_MESSAGE); Objects.requireNonNull(t, NULL_CAUSE_MESSAGE);
if (t == this) if (t == this)
throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE); throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE);
suppressed.add(t); suppList.add(t);
} }
// If there are any invalid suppressed exceptions,
// implicitly use the sentinel value assigned earlier.
suppressedExceptions = suppList;
} }
suppressedExceptions = suppressed; } else {
} // else a null suppressedExceptions field remains null suppressedExceptions = null;
}
/* /*
* For zero-length stack traces, use a clone of * For zero-length stack traces, use a clone of
@ -932,24 +944,41 @@ public class Throwable implements Serializable {
* the stackTrace needs to be constructed from the information * the stackTrace needs to be constructed from the information
* in backtrace. * in backtrace.
*/ */
if (stackTrace != null) { if (candidateStackTrace != null) {
if (stackTrace.length == 0) { // Work from a clone of the candidateStackTrace to ensure
stackTrace = UNASSIGNED_STACK.clone(); // consistency of checks.
} else if (stackTrace.length == 1 && candidateStackTrace = candidateStackTrace.clone();
if (candidateStackTrace.length >= 1) {
if (candidateStackTrace.length == 1 &&
// Check for the marker of an immutable stack trace // Check for the marker of an immutable stack trace
SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) { SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(candidateStackTrace[0])) {
stackTrace = null; stackTrace = null;
} else { // Verify stack trace elements are non-null. } else { // Verify stack trace elements are non-null.
for(StackTraceElement ste : stackTrace) { for (StackTraceElement ste : candidateStackTrace) {
Objects.requireNonNull(ste, "null StackTraceElement in serial stream."); Objects.requireNonNull(ste, "null StackTraceElement in serial stream.");
}
stackTrace = candidateStackTrace;
} }
} }
}
// A null stackTrace field in the serial form can result from
// an exception serialized without that field in older JDK
// releases; treat such exceptions as having empty stack
// traces by leaving stackTrace assigned to a clone of
// UNASSIGNED_STACK.
}
private int validateSuppressedExceptionsList(List<Throwable> deserSuppressedExceptions)
throws IOException {
if (!Object.class.getModule().
equals(deserSuppressedExceptions.getClass().getModule())) {
throw new StreamCorruptedException("List implementation not in base module.");
} else { } else {
// A null stackTrace field in the serial form can result int size = deserSuppressedExceptions.size();
// from an exception serialized without that field in if (size < 0) {
// older JDK releases; treat such exceptions as having throw new StreamCorruptedException("Negative list size reported.");
// empty stack traces. }
stackTrace = UNASSIGNED_STACK.clone(); return size;
} }
} }

View File

@ -45,6 +45,7 @@ import java.util.ServiceLoader;
import jdk.internal.access.JavaNetURLAccess; import jdk.internal.access.JavaNetURLAccess;
import jdk.internal.access.SharedSecrets; import jdk.internal.access.SharedSecrets;
import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
@ -466,13 +467,19 @@ public final class URL implements java.io.Serializable {
this.file = path; this.file = path;
} }
// Note: we don't do validation of the URL here. Too risky to change // Note: we don't do full validation of the URL here. Too risky to change
// right now, but worth considering for future reference. -br // right now, but worth considering for future reference. -br
if (handler == null && if (handler == null &&
(handler = getURLStreamHandler(protocol)) == null) { (handler = getURLStreamHandler(protocol)) == null) {
throw new MalformedURLException("unknown protocol: " + protocol); throw new MalformedURLException("unknown protocol: " + protocol);
} }
this.handler = handler; this.handler = handler;
if (host != null && isBuiltinStreamHandler(handler)) {
String s = IPAddressUtil.checkExternalForm(this);
if (s != null) {
throw new MalformedURLException(s);
}
}
} }
/** /**
@ -1038,7 +1045,12 @@ public final class URL implements java.io.Serializable {
* @since 1.5 * @since 1.5
*/ */
public URI toURI() throws URISyntaxException { public URI toURI() throws URISyntaxException {
return new URI (toString()); URI uri = new URI(toString());
if (authority != null && isBuiltinStreamHandler(handler)) {
String s = IPAddressUtil.checkAuthority(this);
if (s != null) throw new URISyntaxException(authority, s);
}
return uri;
} }
/** /**
@ -1635,6 +1647,10 @@ public final class URL implements java.io.Serializable {
return replacementURL; return replacementURL;
} }
boolean isBuiltinStreamHandler(URLStreamHandler handler) {
return isBuiltinStreamHandler(handler.getClass().getName());
}
private boolean isBuiltinStreamHandler(String handlerClassName) { private boolean isBuiltinStreamHandler(String handlerClassName) {
return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX)); return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
} }

View File

@ -516,12 +516,15 @@ public abstract class URLStreamHandler {
* different from this one * different from this one
* @since 1.3 * @since 1.3
*/ */
protected void setURL(URL u, String protocol, String host, int port, protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String path, String authority, String userInfo, String path,
String query, String ref) { String query, String ref) {
if (this != u.handler) { if (this != u.handler) {
throw new SecurityException("handler for url different from " + throw new SecurityException("handler for url different from " +
"this handler"); "this handler");
} else if (host != null && u.isBuiltinStreamHandler(this)) {
String s = IPAddressUtil.checkHostString(host);
if (s != null) throw new IllegalArgumentException(s);
} }
// ensure that no one can reset the protocol on a given URL. // ensure that no one can reset the protocol on a given URL.
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref); u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -445,7 +445,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter"); throw new NullPointerException("null permissions parameter");
} }
Class<?> caller = Reflection.getCallerClass(); Class<?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null, DomainCombiner dc = (context == null) ? null : context.getCombiner();
return AccessController.doPrivileged(action, createWrapper(dc,
caller, parent, context, perms)); caller, parent, context, perms));
} }
@ -860,7 +861,8 @@ public final class AccessController {
throw new NullPointerException("null permissions parameter"); throw new NullPointerException("null permissions parameter");
} }
Class<?> caller = Reflection.getCallerClass(); Class<?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms)); DomainCombiner dc = (context == null) ? null : context.getCombiner();
return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms));
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package java.util; package java.util;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Array; import java.lang.reflect.Array;
@ -39,6 +40,7 @@ import java.util.function.UnaryOperator;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import jdk.internal.access.SharedSecrets;
/** /**
* This class consists exclusively of static methods that operate on or return * This class consists exclusively of static methods that operate on or return
@ -5163,6 +5165,11 @@ public class Collections {
public Spliterator<E> spliterator() { public Spliterator<E> spliterator() {
return stream().spliterator(); return stream().spliterator();
} }
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, n);
}
} }
/** /**

View File

@ -32,9 +32,11 @@ import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.SocketException; import java.net.SocketException;
import java.net.URL;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -372,4 +374,181 @@ public class IPAddressUtil {
return null; return null;
} }
} }
// See java.net.URI for more details on how to generate these
// masks.
//
// square brackets
private static final long L_IPV6_DELIMS = 0x0L; // "[]"
private static final long H_IPV6_DELIMS = 0x28000000L; // "[]"
// RFC 3986 gen-delims
private static final long L_GEN_DELIMS = 0x8400800800000000L; // ":/?#[]@"
private static final long H_GEN_DELIMS = 0x28000001L; // ":/?#[]@"
// These gen-delims can appear in authority
private static final long L_AUTH_DELIMS = 0x400000000000000L; // "@[]:"
private static final long H_AUTH_DELIMS = 0x28000001L; // "@[]:"
// colon is allowed in userinfo
private static final long L_COLON = 0x400000000000000L; // ":"
private static final long H_COLON = 0x0L; // ":"
// slash should be encoded in authority
private static final long L_SLASH = 0x800000000000L; // "/"
private static final long H_SLASH = 0x0L; // "/"
// backslash should always be encoded
private static final long L_BACKSLASH = 0x0L; // "\"
private static final long H_BACKSLASH = 0x10000000L; // "\"
// ASCII chars 0-31 + 127 - various controls + CRLF + TAB
private static final long L_NON_PRINTABLE = 0xffffffffL;
private static final long H_NON_PRINTABLE = 0x8000000000000000L;
// All of the above
private static final long L_EXCLUDE = 0x84008008ffffffffL;
private static final long H_EXCLUDE = 0x8000000038000001L;
private static final char[] OTHERS = {
8263,8264,8265,8448,8449,8453,8454,10868,
65109,65110,65119,65131,65283,65295,65306,65311,65312
};
// Tell whether the given character is found by the given mask pair
public static boolean match(char c, long lowMask, long highMask) {
if (c < 64)
return ((1L << c) & lowMask) != 0;
if (c < 128)
return ((1L << (c - 64)) & highMask) != 0;
return false; // other non ASCII characters are not filtered
}
// returns -1 if the string doesn't contain any characters
// from the mask, the index of the first such character found
// otherwise.
public static int scan(String s, long lowMask, long highMask) {
int i = -1, len;
if (s == null || (len = s.length()) == 0) return -1;
boolean match = false;
while (++i < len && !(match = match(s.charAt(i), lowMask, highMask)));
if (match) return i;
return -1;
}
public static int scan(String s, long lowMask, long highMask, char[] others) {
int i = -1, len;
if (s == null || (len = s.length()) == 0) return -1;
boolean match = false;
char c, c0 = others[0];
while (++i < len && !(match = match((c=s.charAt(i)), lowMask, highMask))) {
if (c >= c0 && (Arrays.binarySearch(others, c) > -1)) {
match = true; break;
}
}
if (match) return i;
return -1;
}
private static String describeChar(char c) {
if (c < 32 || c == 127) {
if (c == '\n') return "LF";
if (c == '\r') return "CR";
return "control char (code=" + (int)c + ")";
}
if (c == '\\') return "'\\'";
return "'" + c + "'";
}
private static String checkUserInfo(String str) {
// colon is permitted in user info
int index = scan(str, L_EXCLUDE & ~L_COLON,
H_EXCLUDE & ~H_COLON);
if (index >= 0) {
return "Illegal character found in user-info: "
+ describeChar(str.charAt(index));
}
return null;
}
private static String checkHost(String str) {
int index;
if (str.startsWith("[") && str.endsWith("]")) {
str = str.substring(1, str.length() - 1);
if (isIPv6LiteralAddress(str)) {
index = str.indexOf('%');
if (index >= 0) {
index = scan(str = str.substring(index),
L_NON_PRINTABLE | L_IPV6_DELIMS,
H_NON_PRINTABLE | H_IPV6_DELIMS);
if (index >= 0) {
return "Illegal character found in IPv6 scoped address: "
+ describeChar(str.charAt(index));
}
}
return null;
}
return "Unrecognized IPv6 address format";
} else {
index = scan(str, L_EXCLUDE, H_EXCLUDE);
if (index >= 0) {
return "Illegal character found in host: "
+ describeChar(str.charAt(index));
}
}
return null;
}
private static String checkAuth(String str) {
int index = scan(str,
L_EXCLUDE & ~L_AUTH_DELIMS,
H_EXCLUDE & ~H_AUTH_DELIMS);
if (index >= 0) {
return "Illegal character found in authority: "
+ describeChar(str.charAt(index));
}
return null;
}
// check authority of hierarchical URL. Appropriate for
// HTTP-like protocol handlers
public static String checkAuthority(URL url) {
String s, u, h;
if (url == null) return null;
if ((s = checkUserInfo(u = url.getUserInfo())) != null) {
return s;
}
if ((s = checkHost(h = url.getHost())) != null) {
return s;
}
if (h == null && u == null) {
return checkAuth(url.getAuthority());
}
return null;
}
// minimal syntax checks - deeper check may be performed
// by the appropriate protocol handler
public static String checkExternalForm(URL url) {
String s;
if (url == null) return null;
int index = scan(s = url.getUserInfo(),
L_NON_PRINTABLE | L_SLASH,
H_NON_PRINTABLE | H_SLASH);
if (index >= 0) {
return "Illegal character found in authority: "
+ describeChar(s.charAt(index));
}
if ((s = checkHostString(url.getHost())) != null) {
return s;
}
return null;
}
public static String checkHostString(String host) {
if (host == null) return null;
int index = scan(host,
L_NON_PRINTABLE | L_SLASH,
H_NON_PRINTABLE | H_SLASH,
OTHERS);
if (index >= 0) {
return "Illegal character found in host: "
+ describeChar(host.charAt(index));
}
return null;
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,7 @@ import java.io.BufferedInputStream;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.FilterOutputStream; import java.io.FilterOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.SocketPermission; import java.net.SocketPermission;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@ -48,6 +49,7 @@ import java.util.Iterator;
import java.security.Permission; import java.security.Permission;
import java.util.Properties; import java.util.Properties;
import sun.net.NetworkClient; import sun.net.NetworkClient;
import sun.net.util.IPAddressUtil;
import sun.net.www.MessageHeader; import sun.net.www.MessageHeader;
import sun.net.www.MeteredStream; import sun.net.www.MeteredStream;
import sun.net.www.URLConnection; import sun.net.www.URLConnection;
@ -157,6 +159,21 @@ public class FtpURLConnection extends URLConnection {
} }
} }
static URL checkURL(URL u) throws IllegalArgumentException {
if (u != null) {
if (u.toExternalForm().indexOf('\n') > -1) {
Exception mfue = new MalformedURLException("Illegal character in URL");
throw new IllegalArgumentException(mfue.getMessage(), mfue);
}
}
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
Exception mfue = new MalformedURLException(s);
throw new IllegalArgumentException(mfue.getMessage(), mfue);
}
return u;
}
/** /**
* Creates an FtpURLConnection from a URL. * Creates an FtpURLConnection from a URL.
* *
@ -170,7 +187,7 @@ public class FtpURLConnection extends URLConnection {
* Same as FtpURLconnection(URL) with a per connection proxy specified * Same as FtpURLconnection(URL) with a per connection proxy specified
*/ */
FtpURLConnection(URL url, Proxy p) { FtpURLConnection(URL url, Proxy p) {
super(url); super(checkURL(url));
instProxy = p; instProxy = p;
host = url.getHost(); host = url.getHost();
port = url.getPort(); port = url.getPort();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -68,6 +68,7 @@ import java.util.StringJoiner;
import jdk.internal.access.JavaNetHttpCookieAccess; import jdk.internal.access.JavaNetHttpCookieAccess;
import jdk.internal.access.SharedSecrets; import jdk.internal.access.SharedSecrets;
import sun.net.*; import sun.net.*;
import sun.net.util.IPAddressUtil;
import sun.net.www.*; import sun.net.www.*;
import sun.net.www.http.HttpClient; import sun.net.www.http.HttpClient;
import sun.net.www.http.PosterOutputStream; import sun.net.www.http.PosterOutputStream;
@ -868,8 +869,13 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
throw new MalformedURLException("Illegal character in URL"); throw new MalformedURLException("Illegal character in URL");
} }
} }
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
throw new MalformedURLException(s);
}
return u; return u;
} }
protected HttpURLConnection(URL u, Proxy p, Handler handler) protected HttpURLConnection(URL u, Proxy p, Handler handler)
throws IOException { throws IOException {
super(checkURL(u)); super(checkURL(u));

View File

@ -37,6 +37,7 @@ import java.security.Principal;
import java.util.Map; import java.util.Map;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import sun.net.util.IPAddressUtil;
import sun.net.www.http.HttpClient; import sun.net.www.http.HttpClient;
/** /**
@ -69,6 +70,10 @@ public class HttpsURLConnectionImpl
throw new MalformedURLException("Illegal character in URL"); throw new MalformedURLException("Illegal character in URL");
} }
} }
String s = IPAddressUtil.checkAuthority(u);
if (s != null) {
throw new MalformedURLException(s);
}
return u; return u;
} }
@ -289,7 +294,7 @@ public class HttpsURLConnectionImpl
* @param key the keyword by which the request is known * @param key the keyword by which the request is known
* (e.g., "<code>accept</code>"). * (e.g., "<code>accept</code>").
* @param value the value associated with it. * @param value the value associated with it.
* @see #getRequestProperties(java.lang.String) * @see #getRequestProperty(java.lang.String)
* @since 1.4 * @since 1.4
*/ */
public void addRequestProperty(String key, String value) { public void addRequestProperty(String key, String value) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -724,12 +724,14 @@ final class CertStatusExtension {
// Update the context. // Update the context.
chc.handshakeExtensions.put( chc.handshakeExtensions.put(
SH_STATUS_REQUEST, CertStatusRequestSpec.DEFAULT); SH_STATUS_REQUEST, CertStatusRequestSpec.DEFAULT);
chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
SSLHandshake.CERTIFICATE_STATUS);
// Since we've received a legitimate status_request in the // Since we've received a legitimate status_request in the
// ServerHello, stapling is active if it's been enabled. // ServerHello, stapling is active if it's been enabled.
chc.staplingActive = chc.sslContext.isStaplingEnabled(true); chc.staplingActive = chc.sslContext.isStaplingEnabled(true);
if (chc.staplingActive) {
chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
SSLHandshake.CERTIFICATE_STATUS);
}
// No impact on session resumption. // No impact on session resumption.
} }
@ -1079,12 +1081,16 @@ final class CertStatusExtension {
// Update the context. // Update the context.
chc.handshakeExtensions.put( chc.handshakeExtensions.put(
SH_STATUS_REQUEST_V2, CertStatusRequestV2Spec.DEFAULT); SH_STATUS_REQUEST_V2, CertStatusRequestV2Spec.DEFAULT);
chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
SSLHandshake.CERTIFICATE_STATUS);
// Since we've received a legitimate status_request in the // Since we've received a legitimate status_request in the
// ServerHello, stapling is active if it's been enabled. // ServerHello, stapling is active if it's been enabled. If it
// is active, make sure we add the CertificateStatus message
// consumer.
chc.staplingActive = chc.sslContext.isStaplingEnabled(true); chc.staplingActive = chc.sslContext.isStaplingEnabled(true);
if (chc.staplingActive) {
chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id,
SSLHandshake.CERTIFICATE_STATUS);
}
// No impact on session resumption. // No impact on session resumption.
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -330,6 +330,15 @@ final class CertificateRequest {
// clean up this consumer // clean up this consumer
chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id); chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id);
SSLConsumer certStatCons = chc.handshakeConsumers.remove(
SSLHandshake.CERTIFICATE_STATUS.id);
if (certStatCons != null) {
// Stapling was active but no certificate status message
// was sent. We need to run the absence handler which will
// check the certificate chain.
CertificateStatus.handshakeAbsence.absent(context, null);
}
T10CertificateRequestMessage crm = T10CertificateRequestMessage crm =
new T10CertificateRequestMessage(chc, message); new T10CertificateRequestMessage(chc, message);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@ -647,6 +656,15 @@ final class CertificateRequest {
// clean up this consumer // clean up this consumer
chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id); chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id);
SSLConsumer certStatCons = chc.handshakeConsumers.remove(
SSLHandshake.CERTIFICATE_STATUS.id);
if (certStatCons != null) {
// Stapling was active but no certificate status message
// was sent. We need to run the absence handler which will
// check the certificate chain.
CertificateStatus.handshakeAbsence.absent(context, null);
}
T12CertificateRequestMessage crm = T12CertificateRequestMessage crm =
new T12CertificateRequestMessage(chc, message); new T12CertificateRequestMessage(chc, message);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -287,12 +287,16 @@ final class CertificateStatus {
} }
// Pin the received responses to the SSLSessionImpl. It will // Pin the received responses to the SSLSessionImpl. It will
// be retrieved by the X509TrustManagerImpl during the certficicate // be retrieved by the X509TrustManagerImpl during the certificate
// checking phase. // checking phase.
chc.handshakeSession.setStatusResponses(cst.encodedResponses); chc.handshakeSession.setStatusResponses(cst.encodedResponses);
// Now perform the check // Now perform the check
T12CertificateConsumer.checkServerCerts(chc, chc.deferredCerts); T12CertificateConsumer.checkServerCerts(chc, chc.deferredCerts);
// Update the handshake consumers to remove this message, indicating
// that it has been processed.
chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_STATUS.id);
} }
} }

View File

@ -1480,8 +1480,9 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
checkAdditionalTrust(chain, authType, engine, false); checkAdditionalTrust(chain, authType, engine, false);
} }
private void checkAdditionalTrust(X509Certificate[] chain, String authType, private void checkAdditionalTrust(X509Certificate[] chain,
Socket socket, boolean isClient) throws CertificateException { String authType, Socket socket,
boolean checkClientTrusted) throws CertificateException {
if (socket != null && socket.isConnected() && if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) { socket instanceof SSLSocket) {
@ -1495,9 +1496,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
String identityAlg = sslSocket.getSSLParameters(). String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) { if (identityAlg != null && !identityAlg.isEmpty()) {
String hostname = session.getPeerHost(); X509TrustManagerImpl.checkIdentity(session, chain,
X509TrustManagerImpl.checkIdentity( identityAlg, checkClientTrusted);
hostname, chain[0], identityAlg);
} }
// try the best to check the algorithm constraints // try the best to check the algorithm constraints
@ -1519,12 +1519,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(sslSocket, true); constraints = new SSLAlgorithmConstraints(sslSocket, true);
} }
checkAlgorithmConstraints(chain, constraints, isClient); checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
} }
} }
private void checkAdditionalTrust(X509Certificate[] chain, String authType, private void checkAdditionalTrust(X509Certificate[] chain,
SSLEngine engine, boolean isClient) throws CertificateException { String authType, SSLEngine engine,
boolean checkClientTrusted) throws CertificateException {
if (engine != null) { if (engine != null) {
SSLSession session = engine.getHandshakeSession(); SSLSession session = engine.getHandshakeSession();
if (session == null) { if (session == null) {
@ -1535,9 +1536,8 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
String identityAlg = engine.getSSLParameters(). String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) { if (identityAlg != null && !identityAlg.isEmpty()) {
String hostname = session.getPeerHost(); X509TrustManagerImpl.checkIdentity(session, chain,
X509TrustManagerImpl.checkIdentity( identityAlg, checkClientTrusted);
hostname, chain[0], identityAlg);
} }
// try the best to check the algorithm constraints // try the best to check the algorithm constraints
@ -1559,13 +1559,13 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(engine, true); constraints = new SSLAlgorithmConstraints(engine, true);
} }
checkAlgorithmConstraints(chain, constraints, isClient); checkAlgorithmConstraints(chain, constraints, checkClientTrusted);
} }
} }
private void checkAlgorithmConstraints(X509Certificate[] chain, private void checkAlgorithmConstraints(X509Certificate[] chain,
AlgorithmConstraints constraints, AlgorithmConstraints constraints,
boolean isClient) throws CertificateException { boolean checkClientTrusted) throws CertificateException {
try { try {
// Does the certificate chain end with a trusted certificate? // Does the certificate chain end with a trusted certificate?
int checkedLength = chain.length - 1; int checkedLength = chain.length - 1;
@ -1584,7 +1584,7 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
if (checkedLength >= 0) { if (checkedLength >= 0) {
AlgorithmChecker checker = AlgorithmChecker checker =
new AlgorithmChecker(constraints, null, new AlgorithmChecker(constraints, null,
(isClient ? Validator.VAR_TLS_CLIENT : (checkClientTrusted ? Validator.VAR_TLS_CLIENT :
Validator.VAR_TLS_SERVER)); Validator.VAR_TLS_SERVER));
checker.init(false); checker.init(false);
for (int i = checkedLength; i >= 0; i--) { for (int i = checkedLength; i >= 0; i--) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -133,6 +133,15 @@ final class ServerHelloDone {
// The consuming happens in client side only. // The consuming happens in client side only.
ClientHandshakeContext chc = (ClientHandshakeContext)context; ClientHandshakeContext chc = (ClientHandshakeContext)context;
SSLConsumer certStatCons = chc.handshakeConsumers.remove(
SSLHandshake.CERTIFICATE_STATUS.id);
if (certStatCons != null) {
// Stapling was active but no certificate status message
// was sent. We need to run the absence handler which will
// check the certificate chain.
CertificateStatus.handshakeAbsence.absent(context, null);
}
// clean up this consumer // clean up this consumer
chc.handshakeConsumers.clear(); chc.handshakeConsumers.clear();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -92,6 +92,15 @@ final class ServerKeyExchange {
// clean up this consumer // clean up this consumer
chc.handshakeConsumers.remove(SSLHandshake.SERVER_KEY_EXCHANGE.id); chc.handshakeConsumers.remove(SSLHandshake.SERVER_KEY_EXCHANGE.id);
SSLConsumer certStatCons = chc.handshakeConsumers.remove(
SSLHandshake.CERTIFICATE_STATUS.id);
if (certStatCons != null) {
// Stapling was active but no certificate status message
// was sent. We need to run the absence handler which will
// check the certificate chain.
CertificateStatus.handshakeAbsence.absent(context, null);
}
SSLKeyExchange ke = SSLKeyExchange.valueOf( SSLKeyExchange ke = SSLKeyExchange.valueOf(
chc.negotiatedCipherSuite.keyExchange, chc.negotiatedCipherSuite.keyExchange,
chc.negotiatedProtocol); chc.negotiatedProtocol);

View File

@ -145,7 +145,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
private Validator checkTrustedInit(X509Certificate[] chain, private Validator checkTrustedInit(X509Certificate[] chain,
String authType, boolean isClient) { String authType, boolean checkClientTrusted) {
if (chain == null || chain.length == 0) { if (chain == null || chain.length == 0) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"null or zero-length certificate chain"); "null or zero-length certificate chain");
@ -157,7 +157,7 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
Validator v = null; Validator v = null;
if (isClient) { if (checkClientTrusted) {
v = clientValidator; v = clientValidator;
if (v == null) { if (v == null) {
validatorLock.lock(); validatorLock.lock();
@ -192,9 +192,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
return v; return v;
} }
private void checkTrusted(X509Certificate[] chain, String authType, private void checkTrusted(X509Certificate[] chain,
Socket socket, boolean isClient) throws CertificateException { String authType, Socket socket,
Validator v = checkTrustedInit(chain, authType, isClient); boolean checkClientTrusted) throws CertificateException {
Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
X509Certificate[] trustedChain = null; X509Certificate[] trustedChain = null;
if ((socket != null) && socket.isConnected() && if ((socket != null) && socket.isConnected() &&
@ -223,28 +224,23 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
// Grab any stapled OCSP responses for use in validation // Grab any stapled OCSP responses for use in validation
List<byte[]> responseList = Collections.emptyList(); List<byte[]> responseList = Collections.emptyList();
if (!isClient && isExtSession) { if (!checkClientTrusted && isExtSession) {
responseList = responseList =
((ExtendedSSLSession)session).getStatusResponses(); ((ExtendedSSLSession)session).getStatusResponses();
} }
trustedChain = v.validate(chain, null, responseList, trustedChain = v.validate(chain, null, responseList,
constraints, isClient ? null : authType); constraints, checkClientTrusted ? null : authType);
// check if EE certificate chains to a public root CA (as
// pre-installed in cacerts)
boolean chainsToPublicCA = AnchorCertificates.contains(
trustedChain[trustedChain.length-1]);
// check endpoint identity // check endpoint identity
String identityAlg = sslSocket.getSSLParameters(). String identityAlg = sslSocket.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) { if (identityAlg != null && !identityAlg.isEmpty()) {
checkIdentity(session, trustedChain[0], identityAlg, isClient, checkIdentity(session,
getRequestedServerNames(socket), chainsToPublicCA); trustedChain, identityAlg, checkClientTrusted);
} }
} else { } else {
trustedChain = v.validate(chain, null, Collections.emptyList(), trustedChain = v.validate(chain, null, Collections.emptyList(),
null, isClient ? null : authType); null, checkClientTrusted ? null : authType);
} }
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
@ -253,9 +249,10 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
} }
private void checkTrusted(X509Certificate[] chain, String authType, private void checkTrusted(X509Certificate[] chain,
SSLEngine engine, boolean isClient) throws CertificateException { String authType, SSLEngine engine,
Validator v = checkTrustedInit(chain, authType, isClient); boolean checkClientTrusted) throws CertificateException {
Validator v = checkTrustedInit(chain, authType, checkClientTrusted);
X509Certificate[] trustedChain = null; X509Certificate[] trustedChain = null;
if (engine != null) { if (engine != null) {
@ -281,28 +278,23 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
// Grab any stapled OCSP responses for use in validation // Grab any stapled OCSP responses for use in validation
List<byte[]> responseList = Collections.emptyList(); List<byte[]> responseList = Collections.emptyList();
if (!isClient && isExtSession) { if (!checkClientTrusted && isExtSession) {
responseList = responseList =
((ExtendedSSLSession)session).getStatusResponses(); ((ExtendedSSLSession)session).getStatusResponses();
} }
trustedChain = v.validate(chain, null, responseList, trustedChain = v.validate(chain, null, responseList,
constraints, isClient ? null : authType); constraints, checkClientTrusted ? null : authType);
// check if EE certificate chains to a public root CA (as
// pre-installed in cacerts)
boolean chainsToPublicCA = AnchorCertificates.contains(
trustedChain[trustedChain.length-1]);
// check endpoint identity // check endpoint identity
String identityAlg = engine.getSSLParameters(). String identityAlg = engine.getSSLParameters().
getEndpointIdentificationAlgorithm(); getEndpointIdentificationAlgorithm();
if (identityAlg != null && !identityAlg.isEmpty()) { if (identityAlg != null && !identityAlg.isEmpty()) {
checkIdentity(session, trustedChain[0], identityAlg, isClient, checkIdentity(session, trustedChain,
getRequestedServerNames(engine), chainsToPublicCA); identityAlg, checkClientTrusted);
} }
} else { } else {
trustedChain = v.validate(chain, null, Collections.emptyList(), trustedChain = v.validate(chain, null, Collections.emptyList(),
null, isClient ? null : authType); null, checkClientTrusted ? null : authType);
} }
if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) {
@ -360,14 +352,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
static List<SNIServerName> getRequestedServerNames(Socket socket) { static List<SNIServerName> getRequestedServerNames(Socket socket) {
if (socket != null && socket.isConnected() && if (socket != null && socket.isConnected() &&
socket instanceof SSLSocket) { socket instanceof SSLSocket) {
return getRequestedServerNames(
SSLSocket sslSocket = (SSLSocket)socket; ((SSLSocket)socket).getHandshakeSession());
SSLSession session = sslSocket.getHandshakeSession();
if (session != null && (session instanceof ExtendedSSLSession)) {
ExtendedSSLSession extSession = (ExtendedSSLSession)session;
return extSession.getRequestedServerNames();
}
} }
return Collections.<SNIServerName>emptyList(); return Collections.<SNIServerName>emptyList();
@ -376,12 +362,16 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
// Also used by X509KeyManagerImpl // Also used by X509KeyManagerImpl
static List<SNIServerName> getRequestedServerNames(SSLEngine engine) { static List<SNIServerName> getRequestedServerNames(SSLEngine engine) {
if (engine != null) { if (engine != null) {
SSLSession session = engine.getHandshakeSession(); return getRequestedServerNames(engine.getHandshakeSession());
}
if (session != null && (session instanceof ExtendedSSLSession)) { return Collections.<SNIServerName>emptyList();
ExtendedSSLSession extSession = (ExtendedSSLSession)session; }
return extSession.getRequestedServerNames();
} private static List<SNIServerName> getRequestedServerNames(
SSLSession session) {
if (session != null && (session instanceof ExtendedSSLSession)) {
return ((ExtendedSSLSession)session).getRequestedServerNames();
} }
return Collections.<SNIServerName>emptyList(); return Collections.<SNIServerName>emptyList();
@ -402,23 +392,28 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
* the identity checking aginst the server_name extension if present, and * the identity checking aginst the server_name extension if present, and
* may failove to peer host checking. * may failove to peer host checking.
*/ */
private static void checkIdentity(SSLSession session, static void checkIdentity(SSLSession session,
X509Certificate cert, X509Certificate[] trustedChain,
String algorithm, String algorithm,
boolean isClient, boolean checkClientTrusted) throws CertificateException {
List<SNIServerName> sniNames,
boolean chainsToPublicCA) throws CertificateException { // check if EE certificate chains to a public root CA (as
// pre-installed in cacerts)
boolean chainsToPublicCA = AnchorCertificates.contains(
trustedChain[trustedChain.length - 1]);
boolean identifiable = false; boolean identifiable = false;
String peerHost = session.getPeerHost(); String peerHost = session.getPeerHost();
if (isClient) { if (!checkClientTrusted) {
String hostname = getHostNameInSNI(sniNames); List<SNIServerName> sniNames = getRequestedServerNames(session);
if (hostname != null) { String sniHostName = getHostNameInSNI(sniNames);
if (sniHostName != null) {
try { try {
checkIdentity(hostname, cert, algorithm, chainsToPublicCA); checkIdentity(sniHostName,
trustedChain[0], algorithm, chainsToPublicCA);
identifiable = true; identifiable = true;
} catch (CertificateException ce) { } catch (CertificateException ce) {
if (hostname.equalsIgnoreCase(peerHost)) { if (sniHostName.equalsIgnoreCase(peerHost)) {
throw ce; throw ce;
} }
@ -428,7 +423,8 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager
} }
if (!identifiable) { if (!identifiable) {
checkIdentity(peerHost, cert, algorithm, chainsToPublicCA); checkIdentity(peerHost,
trustedChain[0], algorithm, chainsToPublicCA);
} }
} }

View File

@ -92,8 +92,6 @@ class DerIndefLenConverter {
* add the current position to the <code>eocList</code> vector. * add the current position to the <code>eocList</code> vector.
*/ */
private void parseTag() throws IOException { private void parseTag() throws IOException {
if (dataPos == dataSize)
return;
if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) { if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) {
int numOfEncapsulatedLenBytes = 0; int numOfEncapsulatedLenBytes = 0;
Object elem = null; Object elem = null;
@ -332,6 +330,10 @@ class DerIndefLenConverter {
// parse and set up the vectors of all the indefinite-lengths // parse and set up the vectors of all the indefinite-lengths
while (dataPos < dataSize) { while (dataPos < dataSize) {
if (dataPos + 2 > dataSize) {
// There should be at least one tag and one length
return null;
}
parseTag(); parseTag();
len = parseLength(); len = parseLength();
if (len < 0) { if (len < 0) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -260,28 +260,35 @@ public class HostnameChecker {
* The matching is performed as per RFC 2818 rules for TLS and * The matching is performed as per RFC 2818 rules for TLS and
* RFC 2830 rules for LDAP.<p> * RFC 2830 rules for LDAP.<p>
* *
* The <code>name</code> parameter should represent a DNS name. * The <code>name</code> parameter should represent a DNS name. The
* The <code>template</code> parameter * <code>template</code> parameter may contain the wildcard character '*'.
* may contain the wildcard character *
*/ */
private boolean isMatched(String name, String template, private boolean isMatched(String name, String template,
boolean chainsToPublicCA) { boolean chainsToPublicCA) {
// Normalize to Unicode, because PSL is in Unicode. // Normalize to Unicode, because PSL is in Unicode.
name = IDN.toUnicode(IDN.toASCII(name)); try {
template = IDN.toUnicode(IDN.toASCII(template)); name = IDN.toUnicode(IDN.toASCII(name));
template = IDN.toUnicode(IDN.toASCII(template));
} catch (RuntimeException re) {
if (SSLLogger.isOn) {
SSLLogger.fine("Failed to normalize to Unicode: " + re);
}
if (hasIllegalWildcard(name, template, chainsToPublicCA)) { return false;
}
if (hasIllegalWildcard(template, chainsToPublicCA)) {
return false; return false;
} }
// check the validity of the domain name template. // check the validity of the domain name template.
try { try {
// Replacing wildcard character '*' with 'x' so as to check // Replacing wildcard character '*' with 'z' so as to check
// the domain name template validity. // the domain name template validity.
// //
// Using the checking implemented in SNIHostName // Using the checking implemented in SNIHostName
new SNIHostName(template.replace('*', 'x')); new SNIHostName(template.replace('*', 'z'));
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
// It would be nice to add debug log if not matching. // It would be nice to add debug log if not matching.
return false; return false;
@ -299,8 +306,8 @@ public class HostnameChecker {
/** /**
* Returns true if the template contains an illegal wildcard character. * Returns true if the template contains an illegal wildcard character.
*/ */
private static boolean hasIllegalWildcard(String domain, String template, private static boolean hasIllegalWildcard(
boolean chainsToPublicCA) { String template, boolean chainsToPublicCA) {
// not ok if it is a single wildcard character or "*." // not ok if it is a single wildcard character or "*."
if (template.equals("*") || template.equals("*.")) { if (template.equals("*") || template.equals("*.")) {
if (SSLLogger.isOn) { if (SSLLogger.isOn) {
@ -331,25 +338,29 @@ public class HostnameChecker {
return true; return true;
} }
// If the wildcarded domain is a top-level domain under which names
// can be registered, then a wildcard is not allowed.
if (!chainsToPublicCA) { if (!chainsToPublicCA) {
return false; // skip check for non-public certificates return false; // skip check for non-public certificates
} }
Optional<RegisteredDomain> rd = RegisteredDomain.from(domain)
.filter(d -> d.type() == RegisteredDomain.Type.ICANN);
if (rd.isPresent()) { // If the wildcarded domain is a top-level domain under which names
String wDomain = afterWildcard.substring(firstDotIndex + 1); // can be registered, then a wildcard is not allowed.
if (rd.get().publicSuffix().equalsIgnoreCase(wDomain)) { String wildcardedDomain = afterWildcard.substring(firstDotIndex + 1);
if (SSLLogger.isOn) { String templateDomainSuffix =
SSLLogger.fine( RegisteredDomain.from("z." + wildcardedDomain)
"Certificate domain name has illegal " + .filter(d -> d.type() == RegisteredDomain.Type.ICANN)
"wildcard for public suffix: " + template); .map(RegisteredDomain::publicSuffix).orElse(null);
} if (templateDomainSuffix == null) {
return true; return false; // skip check if not known public suffix
}
// Is it a top-level domain?
if (wildcardedDomain.equalsIgnoreCase(templateDomainSuffix)) {
if (SSLLogger.isOn) {
SSLLogger.fine(
"Certificate domain name has illegal " +
"wildcard for top-level public suffix: " + template);
} }
return true;
} }
return false; return false;

View File

@ -269,6 +269,8 @@ public class KeyStoreDelegator extends KeyStoreSpi {
throw (CertificateException)e; throw (CertificateException)e;
} else if (e instanceof NoSuchAlgorithmException) { } else if (e instanceof NoSuchAlgorithmException) {
throw (NoSuchAlgorithmException)e; throw (NoSuchAlgorithmException)e;
} else if (e instanceof RuntimeException){
throw (RuntimeException)e;
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -95,7 +95,7 @@ public class Handler extends URLStreamHandler {
path = "\\\\" + host + path; path = "\\\\" + host + path;
File f = new File(path); File f = new File(path);
if (f.exists()) { if (f.exists()) {
return createFileURLConnection(url, f); return new UNCFileURLConnection(url, f, path);
} }
/* /*

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2019, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.net.www.protocol.file;
import java.io.File;
import java.io.FilePermission;
import java.net.URL;
import java.security.Permission;
final class UNCFileURLConnection extends FileURLConnection {
private final String effectivePath;
private volatile Permission permission;
UNCFileURLConnection(URL u, File file, String effectivePath) {
super(u, file);
this.effectivePath = effectivePath;
}
@Override
public Permission getPermission() {
Permission perm = permission;
if (perm == null) {
permission = perm = new FilePermission(effectivePath, "read");
}
return perm;
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -214,7 +214,7 @@ SplashInitPlatform(Splash * splash) {
splash->maskRequired = 0; splash->maskRequired = 0;
//TODO: the following is too much of a hack but should work in 90% cases. //TODO: the following is too much of a hack but should work in 90% cases.
// besides we don't use device-dependent drawing, so probably // besides we don't use device-dependent drawing, so probably
// that's very fine indeed // that's very fine indeed
@ -282,9 +282,11 @@ void
SplashRedrawWindow(Splash * splash) { SplashRedrawWindow(Splash * splash) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SplashUpdateScreenData(splash);
[JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
// drop the reference to the old view and image
[splash->window setContentView: nil];
SplashUpdateScreenData(splash);
// NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ? // NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ?
NSBitmapImageRep * rep = [[NSBitmapImageRep alloc] NSBitmapImageRep * rep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes: (unsigned char**)&splash->screenData initWithBitmapDataPlanes: (unsigned char**)&splash->screenData
@ -311,7 +313,7 @@ SplashRedrawWindow(Splash * splash) {
size.height /= scaleFactor; size.height /= scaleFactor;
[image setSize: size]; [image setSize: size];
} }
NSImageView * view = [[NSImageView alloc] init]; NSImageView * view = [[NSImageView alloc] init];
[view setImage: image]; [view setImage: image];

View File

@ -4622,8 +4622,7 @@ png_image_free(png_imagep image)
if (image != NULL && image->opaque != NULL && if (image != NULL && image->opaque != NULL &&
image->opaque->error_buf == NULL) image->opaque->error_buf == NULL)
{ {
/* Ignore errors here: */ png_image_free_function(image);
(void)png_safe_execute(image, png_image_free_function, image);
image->opaque = NULL; image->opaque = NULL;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -102,7 +102,8 @@ NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) {
for (NSString *realm in realms) { for (NSString *realm in realms) {
CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]); CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) { if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
if (realmInfo) CFRelease(realmInfo);
return nil; return nil;
} }