提交 64615663 编写于 作者: M mduigou

Merge

......@@ -1142,56 +1142,6 @@ $(SCTPAPI_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(SCTPAP
$(prep-target)
$(call PackageFilter,$(SCTPAPI_PKGS))
#############################################################
#
# tracingdocs
#
ALL_OTHER_TARGETS += tracingdocs
TRACING_DOCDIR := $(JRE_API_DOCSDIR)/tracing
TRACING2COREAPI := ../$(JDKJRE2COREAPI)
TRACING_DOCTITLE := Java$(TRADEMARK) Platform Tracing
TRACING_WINDOWTITLE := Platform Tracing
TRACING_HEADER := <strong>Platform Tracing</strong>
TRACING_BOTTOM := $(call CommonBottom,$(TRACING_FIRST_COPYRIGHT_YEAR))
# TRACING_PKGS is located in NON_CORE_PKGS.gmk
TRACING_INDEX_HTML = $(TRACING_DOCDIR)/index.html
TRACING_OPTIONS_FILE = $(DOCSTMPDIR)/tracing.options
TRACING_PACKAGES_FILE = $(DOCSTMPDIR)/tracing.packages
tracingdocs: $(TRACING_INDEX_HTML)
# Set relative location to core api document root
$(TRACING_INDEX_HTML): GET2DOCSDIR=$(TRACING2COREAPI)/..
# Run javadoc if the index file is out of date or missing
$(TRACING_INDEX_HTML): $(TRACING_OPTIONS_FILE) $(TRACING_PACKAGES_FILE)
$(prep-javadoc)
$(call JavadocSummary,$(TRACING_OPTIONS_FILE),$(TRACING_PACKAGES_FILE))
$(JAVADOC_CMD) $(JAVADOC_VM_MEMORY_FLAGS) -d $(@D) \
@$(TRACING_OPTIONS_FILE) @$(TRACING_PACKAGES_FILE)
# Create file with javadoc options in it
$(TRACING_OPTIONS_FILE):
$(prep-target)
@($(call OptionOnly,$(COMMON_JAVADOCFLAGS)) ; \
$(call OptionPair,-sourcepath,$(RELEASEDOCS_SOURCEPATH)) ; \
$(call OptionPair,-encoding,ascii) ; \
$(call OptionOnly,-nodeprecatedlist) ; \
$(call OptionPair,-doctitle,$(TRACING_DOCTITLE)) ; \
$(call OptionPair,-windowtitle,$(TRACING_WINDOWTITLE) $(DRAFT_WINTITLE));\
$(call OptionPair,-header,$(TRACING_HEADER)$(DRAFT_HEADER)) ; \
$(call OptionPair,-bottom,$(TRACING_BOTTOM)$(DRAFT_BOTTOM)) ; \
$(call OptionTrip,-linkoffline,$(TRACING2COREAPI),$(COREAPI_DOCSDIR)/); \
) >> $@
# Create a file with the package names in it
$(TRACING_PACKAGES_FILE): $(DIRECTORY_CACHE) $(call PackageDependencies,$(TRACING_PKGS))
$(prep-target)
$(call PackageFilter,$(TRACING_PKGS))
#############################################################
#
# Get a cache of all the directories
......
......@@ -88,9 +88,6 @@ SMARTCARDIO_PKGS = javax.smartcardio
SCTPAPI_PKGS = com.sun.nio.sctp
TRACING_PKGS = com.sun.tracing \
com.sun.tracing.dtrace
# non-core packages in rt.jar
NON_CORE_PKGS = $(DOMAPI_PKGS) \
$(MGMT_PKGS) \
......@@ -100,6 +97,5 @@ NON_CORE_PKGS = $(DOMAPI_PKGS) \
$(OLD_JSSE_PKGS) \
$(HTTPSERVER_PKGS) \
$(SMARTCARDIO_PKGS) \
$(TRACING_PKGS) \
$(SCTPAPI_PKGS)
......@@ -44,7 +44,6 @@ SUNWprivate_1.1 {
Java_sun_nio_ch_EPollArrayWrapper_interrupt;
Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent;
Java_sun_nio_ch_EPoll_init;
Java_sun_nio_ch_EPoll_eventSize;
Java_sun_nio_ch_EPoll_eventsOffset;
Java_sun_nio_ch_EPoll_dataOffset;
......@@ -129,7 +128,6 @@ SUNWprivate_1.1 {
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
Java_sun_nio_fs_LinuxWatchService_init;
Java_sun_nio_fs_LinuxWatchService_eventSize;
Java_sun_nio_fs_LinuxWatchService_eventOffsets;
Java_sun_nio_fs_LinuxWatchService_inotifyInit;
......
......@@ -143,6 +143,8 @@ import sun.security.action.GetPropertyAction;
*
* <h4>Standard charsets</h4>
*
* <a name="standard">
*
* <p> Every implementation of the Java platform is required to support the
* following standard charsets. Consult the release documentation for your
* implementation to see if any other charsets are supported. The behavior
......@@ -213,6 +215,8 @@ import sun.security.action.GetPropertyAction;
* determined during virtual-machine startup and typically depends upon the
* locale and charset being used by the underlying operating system. </p>
*
* <p>The {@link StandardCharset} class defines constants for each of the
* standard charsets.
*
* <h4>Terminology</h4>
*
......
/*
* Copyright (c) 2011, 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 java.nio.charset;
/**
* Constant definitions for the standard {@link Charset Charsets}. These
* charsets are guaranteed to be available on every implementation of the Java
* platform.
*
* @see <a href="Charset#standard">Standard Charsets</a>
* @since 1.7
*/
public final class StandardCharset {
private StandardCharset() {
throw new AssertionError("No java.nio.charset.StandardCharset instances for you!");
}
/**
* Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
* Unicode character set
*/
public static final Charset US_ASCII = Charset.forName("US-ASCII");
/**
* ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
*/
public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
/**
* Eight-bit UCS Transformation Format
*/
public static final Charset UTF_8 = Charset.forName("UTF-8");
/**
* Sixteen-bit UCS Transformation Format, big-endian byte order
*/
public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
/**
* Sixteen-bit UCS Transformation Format, little-endian byte order
*/
public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
/**
* Sixteen-bit UCS Transformation Format, byte order identified by an
* optional byte-order mark
*/
public static final Charset UTF_16 = Charset.forName("UTF-16");
}
......@@ -72,7 +72,7 @@ import java.util.Iterator;
* directory and is UTF-8 encoded.
* <pre>
* Path path = FileSystems.getDefault().getPath("logs", "access.log");
* BufferReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8"));
* BufferReader reader = Files.newBufferedReader(path, StandardCharset.UTF_8);
* </pre>
*
* <a name="interop"><h4>Interoperability</h4></a>
......
/*
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2011, 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,6 +25,8 @@
package java.sql;
import java.util.Arrays;
/**
* The subclass of {@link SQLException} thrown when an error
* occurs during a batch update operation. In addition to the
......@@ -77,8 +79,7 @@ public class BatchUpdateException extends SQLException {
*/
public BatchUpdateException( String reason, String SQLState, int vendorCode,
int[] updateCounts ) {
super(reason, SQLState, vendorCode);
this.updateCounts = updateCounts;
this(reason, SQLState, vendorCode, updateCounts, null);
}
/**
......@@ -105,8 +106,7 @@ public class BatchUpdateException extends SQLException {
*/
public BatchUpdateException(String reason, String SQLState,
int[] updateCounts) {
super(reason, SQLState);
this.updateCounts = updateCounts;
this(reason, SQLState, 0, updateCounts, null);
}
/**
......@@ -132,8 +132,7 @@ public class BatchUpdateException extends SQLException {
* @since 1.2
*/
public BatchUpdateException(String reason, int[] updateCounts) {
super(reason);
this.updateCounts = updateCounts;
this(reason, null, 0, updateCounts, null);
}
/**
......@@ -156,8 +155,7 @@ public class BatchUpdateException extends SQLException {
* @since 1.2
*/
public BatchUpdateException(int[] updateCounts) {
super();
this.updateCounts = updateCounts;
this(null, null, 0, updateCounts, null);
}
/**
......@@ -172,8 +170,7 @@ public class BatchUpdateException extends SQLException {
* @since 1.2
*/
public BatchUpdateException() {
super();
this.updateCounts = null;
this(null, null, 0, null, null);
}
/**
......@@ -191,8 +188,7 @@ public class BatchUpdateException extends SQLException {
* @since 1.6
*/
public BatchUpdateException(Throwable cause) {
super(cause);
this.updateCounts = null;
this(null, null, 0, null, cause);
}
/**
......@@ -218,8 +214,7 @@ public class BatchUpdateException extends SQLException {
* @since 1.6
*/
public BatchUpdateException(int []updateCounts , Throwable cause) {
super(cause);
this.updateCounts = updateCounts;
this(null, null, 0, updateCounts, cause);
}
/**
......@@ -243,8 +238,7 @@ public class BatchUpdateException extends SQLException {
* @since 1.6
*/
public BatchUpdateException(String reason, int []updateCounts, Throwable cause) {
super(reason,cause);
this.updateCounts = updateCounts;
this(reason, null, 0, updateCounts, cause);
}
/**
......@@ -269,8 +263,7 @@ public class BatchUpdateException extends SQLException {
*/
public BatchUpdateException(String reason, String SQLState,
int []updateCounts, Throwable cause) {
super(reason,SQLState,cause);
this.updateCounts = updateCounts;
this(reason, SQLState, 0, updateCounts, cause);
}
/**
......@@ -297,8 +290,8 @@ public class BatchUpdateException extends SQLException {
*/
public BatchUpdateException(String reason, String SQLState, int vendorCode,
int []updateCounts,Throwable cause) {
super(reason,SQLState,vendorCode,cause);
this.updateCounts = updateCounts;
super(reason, SQLState, vendorCode, cause);
this.updateCounts = (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length);
}
/**
......@@ -332,7 +325,7 @@ public class BatchUpdateException extends SQLException {
* @since 1.3
*/
public int[] getUpdateCounts() {
return updateCounts;
return (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length);
}
/**
......@@ -340,7 +333,7 @@ public class BatchUpdateException extends SQLException {
* @serial
* @since 1.2
*/
private int[] updateCounts;
private final int[] updateCounts;
private static final long serialVersionUID = 5977529877145521757L;
}
......@@ -37,7 +37,6 @@ import java.security.CodeSource;
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.misc.SharedSecrets;
import sun.security.util.SignatureFileVerifier;
/**
* The <code>JarFile</code> class is used to read the contents of a jar file
......@@ -179,7 +178,7 @@ class JarFile extends ZipFile {
byte[] b = getBytes(manEntry);
man = new Manifest(new ByteArrayInputStream(b));
if (!jvInitialized) {
jv = new JarVerifier(b, man);
jv = new JarVerifier(b);
}
} else {
man = new Manifest(super.getInputStream(manEntry));
......@@ -298,7 +297,10 @@ class JarFile extends ZipFile {
if (names != null) {
for (int i = 0; i < names.length; i++) {
String name = names[i].toUpperCase(Locale.ENGLISH);
if (SignatureFileVerifier.isBlockOrSF(name)) {
if (name.endsWith(".DSA") ||
name.endsWith(".RSA") ||
name.endsWith(".EC") ||
name.endsWith(".SF")) {
// Assume since we found a signature-related file
// that the jar is signed and that we therefore
// need a JarVerifier and Manifest
......@@ -327,17 +329,17 @@ class JarFile extends ZipFile {
if (names != null) {
for (int i = 0; i < names.length; i++) {
JarEntry e = getJarEntry(names[i]);
if (!e.isDirectory() &&
SignatureFileVerifier.isBlock(names[i])) {
if (!e.isDirectory()) {
if (mev == null) {
mev = new ManifestEntryVerifier
(getManifestFromReference());
}
String key = names[i].substring(
0, names[i].lastIndexOf("."));
jv.verifyBlock(names[i],
getBytes(e),
super.getInputStream(getJarEntry(key + ".SF")));
byte[] b = getBytes(e);
if (b != null && b.length > 0) {
jv.beginEntry(e, mev);
jv.update(b.length, b, 0, b.length, mev);
jv.update(-1, null, 0, 0, mev);
}
}
}
}
......
......@@ -95,7 +95,7 @@ class JarInputStream extends ZipInputStream {
man.read(new ByteArrayInputStream(bytes));
closeEntry();
if (doVerify) {
jv = new JarVerifier(bytes, man);
jv = new JarVerifier(bytes);
mev = new ManifestEntryVerifier(man);
}
return (JarEntry)super.getNextEntry();
......
......@@ -48,18 +48,35 @@ class JarVerifier {
/* a table mapping names to code signers, for jar entries that have
had their actual hashes verified */
private Map verifiedSigners;
private Hashtable verifiedSigners;
/* a table mapping names to code signers, for jar entries that have
passed the .SF/.DSA/.EC -> MANIFEST check */
private Map sigFileSigners;
private Hashtable sigFileSigners;
/* a hash table to hold .SF bytes */
private Hashtable sigFileData;
/** "queue" of pending PKCS7 blocks that we couldn't parse
* until we parsed the .SF file */
private ArrayList pendingBlocks;
/* cache of CodeSigner objects */
private ArrayList signerCache;
/* Are we parsing a block? */
private boolean parsingBlockOrSF = false;
/* Are we done parsing META-INF entries? */
private boolean parsingMeta = true;
/* Are there are files to verify? */
private boolean anyToVerify = true;
/* The output stream to use when keeping track of files we are interested
in */
private ByteArrayOutputStream baos;
/** The ManifestDigester object */
private volatile ManifestDigester manDig;
......@@ -75,20 +92,20 @@ class JarVerifier {
/** collect -DIGEST-MANIFEST values for blacklist */
private List manifestDigests;
/** The manifest object */
Manifest man = null;
public JarVerifier(byte rawBytes[], Manifest man) {
this.man = man;
public JarVerifier(byte rawBytes[]) {
manifestRawBytes = rawBytes;
sigFileSigners = new HashMap();
verifiedSigners = new HashMap();
sigFileSigners = new Hashtable();
verifiedSigners = new Hashtable();
sigFileData = new Hashtable(11);
pendingBlocks = new ArrayList();
baos = new ByteArrayOutputStream();
manifestDigests = new ArrayList();
}
/**
* This method scans to see which entry we're parsing and keeps
* various state information depending on the file being parsed.
* This method scans to see which entry we're parsing and
* keeps various state information depending on what type of
* file is being parsed.
*/
public void beginEntry(JarEntry je, ManifestEntryVerifier mev)
throws IOException
......@@ -112,6 +129,30 @@ class JarVerifier {
* b. digest mismatch between the actual jar entry and the manifest
*/
if (parsingMeta) {
String uname = name.toUpperCase(Locale.ENGLISH);
if ((uname.startsWith("META-INF/") ||
uname.startsWith("/META-INF/"))) {
if (je.isDirectory()) {
mev.setEntry(null, je);
return;
}
if (SignatureFileVerifier.isBlockOrSF(uname)) {
/* We parse only DSA, RSA or EC PKCS7 blocks. */
parsingBlockOrSF = true;
baos.reset();
mev.setEntry(null, je);
}
return;
}
}
if (parsingMeta) {
doneWithMeta();
}
if (je.isDirectory()) {
mev.setEntry(null, je);
return;
......@@ -147,7 +188,11 @@ class JarVerifier {
throws IOException
{
if (b != -1) {
if (parsingBlockOrSF) {
baos.write(b);
} else {
mev.update((byte)b);
}
} else {
processEntry(mev);
}
......@@ -162,7 +207,11 @@ class JarVerifier {
throws IOException
{
if (n != -1) {
if (parsingBlockOrSF) {
baos.write(b, off, n);
} else {
mev.update(b, off, n);
}
} else {
processEntry(mev);
}
......@@ -174,11 +223,102 @@ class JarVerifier {
private void processEntry(ManifestEntryVerifier mev)
throws IOException
{
if (!parsingBlockOrSF) {
JarEntry je = mev.getEntry();
if ((je != null) && (je.signers == null)) {
je.signers = mev.verify(verifiedSigners, sigFileSigners);
je.certs = mapSignersToCertArray(je.signers);
}
} else {
try {
parsingBlockOrSF = false;
if (debug != null) {
debug.println("processEntry: processing block");
}
String uname = mev.getEntry().getName()
.toUpperCase(Locale.ENGLISH);
if (uname.endsWith(".SF")) {
String key = uname.substring(0, uname.length()-3);
byte bytes[] = baos.toByteArray();
// add to sigFileData in case future blocks need it
sigFileData.put(key, bytes);
// check pending blocks, we can now process
// anyone waiting for this .SF file
Iterator it = pendingBlocks.iterator();
while (it.hasNext()) {
SignatureFileVerifier sfv =
(SignatureFileVerifier) it.next();
if (sfv.needSignatureFile(key)) {
if (debug != null) {
debug.println(
"processEntry: processing pending block");
}
sfv.setSignatureFile(bytes);
sfv.process(sigFileSigners, manifestDigests);
}
}
return;
}
// now we are parsing a signature block file
String key = uname.substring(0, uname.lastIndexOf("."));
if (signerCache == null)
signerCache = new ArrayList();
if (manDig == null) {
synchronized(manifestRawBytes) {
if (manDig == null) {
manDig = new ManifestDigester(manifestRawBytes);
manifestRawBytes = null;
}
}
}
SignatureFileVerifier sfv =
new SignatureFileVerifier(signerCache,
manDig, uname, baos.toByteArray());
if (sfv.needSignatureFileBytes()) {
// see if we have already parsed an external .SF file
byte[] bytes = (byte[]) sigFileData.get(key);
if (bytes == null) {
// put this block on queue for later processing
// since we don't have the .SF bytes yet
// (uname, block);
if (debug != null) {
debug.println("adding pending block");
}
pendingBlocks.add(sfv);
return;
} else {
sfv.setSignatureFile(bytes);
}
}
sfv.process(sigFileSigners, manifestDigests);
} catch (IOException ioe) {
// e.g. sun.security.pkcs.ParsingException
if (debug != null) debug.println("processEntry caught: "+ioe);
// ignore and treat as unsigned
} catch (SignatureException se) {
if (debug != null) debug.println("processEntry caught: "+se);
// ignore and treat as unsigned
} catch (NoSuchAlgorithmException nsae) {
if (debug != null) debug.println("processEntry caught: "+nsae);
// ignore and treat as unsigned
} catch (CertificateException ce) {
if (debug != null) debug.println("processEntry caught: "+ce);
// ignore and treat as unsigned
}
}
}
/**
......@@ -214,15 +354,15 @@ class JarVerifier {
* Force a read of the entry data to generate the
* verification hash.
*/
try (InputStream s = jar.getInputStream(entry)) {
try {
InputStream s = jar.getInputStream(entry);
byte[] buffer = new byte[1024];
int n = buffer.length;
while (n != -1) {
n = s.read(buffer, 0, buffer.length);
}
s.close();
} catch (IOException e) {
// Ignore. When an exception is thrown, code signer
// will not be assigned.
}
}
return getCodeSigners(name);
......@@ -268,7 +408,11 @@ class JarVerifier {
*/
void doneWithMeta()
{
parsingMeta = false;
anyToVerify = !sigFileSigners.isEmpty();
baos = null;
sigFileData = null;
pendingBlocks = null;
signerCache = null;
manDig = null;
// MANIFEST.MF is always treated as signed and verified,
......@@ -279,41 +423,6 @@ class JarVerifier {
}
}
/**
* Verifies a PKCS7 SignedData block
* @param key name of block
* @param block the pkcs7 file
* @param ins the clear data
*/
void verifyBlock(String key, byte[] block, InputStream ins) {
try {
if (signerCache == null)
signerCache = new ArrayList();
if (manDig == null) {
synchronized(manifestRawBytes) {
if (manDig == null) {
manDig = new ManifestDigester(manifestRawBytes);
manifestRawBytes = null;
}
}
}
SignatureFileVerifier sfv =
new SignatureFileVerifier(signerCache, man,
manDig, key, block);
if (sfv.needSignatureFile()) {
// see if we have already parsed an external .SF file
sfv.setSignatureFile(ins);
}
sfv.process(sigFileSigners, manifestDigests);
} catch (Exception e) {
if (debug != null) {
e.printStackTrace();
}
}
}
static class VerifierStream extends java.io.InputStream {
private InputStream is;
......@@ -444,7 +553,10 @@ class JarVerifier {
* but this handles a CodeSource of any type, just in case.
*/
CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
List sourceList = Arrays.asList(sources);
List sourceList = new ArrayList();
for (int i = 0; i < sources.length; i++) {
sourceList.add(sources[i]);
}
int j = sourceList.indexOf(cs);
if (j != -1) {
CodeSigner[] match;
......
......@@ -28,6 +28,7 @@ package java.util.zip;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
......@@ -87,7 +88,7 @@ final class ZipCoder {
if (isutf8)
return getBytes(s);
if (utf8 == null)
utf8 = new ZipCoder(Charset.forName("UTF-8"));
utf8 = new ZipCoder(StandardCharset.UTF_8);
return utf8.getBytes(s);
}
......@@ -96,7 +97,7 @@ final class ZipCoder {
if (isutf8)
return toString(ba, len);
if (utf8 == null)
utf8 = new ZipCoder(Charset.forName("UTF-8"));
utf8 = new ZipCoder(StandardCharset.UTF_8);
return utf8.toString(ba, len);
}
......@@ -112,7 +113,7 @@ final class ZipCoder {
private ZipCoder(Charset cs) {
this.cs = cs;
this.isutf8 = cs.name().equals("UTF-8");
this.isutf8 = cs.name().equals(StandardCharset.UTF_8.name());
}
static ZipCoder get(Charset charset) {
......
......@@ -31,6 +31,7 @@ import java.io.IOException;
import java.io.EOFException;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharset;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Enumeration;
......@@ -140,7 +141,7 @@ class ZipFile implements ZipConstants, Closeable {
* @since 1.3
*/
public ZipFile(File file, int mode) throws IOException {
this(file, mode, Charset.forName("UTF-8"));
this(file, mode, StandardCharset.UTF_8);
}
/**
......
......@@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.EOFException;
import java.io.PushbackInputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharset;
import static java.util.zip.ZipConstants64.*;
/**
......@@ -75,7 +76,7 @@ class ZipInputStream extends InflaterInputStream implements ZipConstants {
* @param in the actual input stream
*/
public ZipInputStream(InputStream in) {
this(in, Charset.forName("UTF-8"));
this(in, StandardCharset.UTF_8);
}
/**
......
......@@ -28,6 +28,7 @@ package java.util.zip;
import java.io.OutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharset;
import java.util.Vector;
import java.util.HashSet;
import static java.util.zip.ZipConstants64.*;
......@@ -100,7 +101,7 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
* @param out the actual output stream
*/
public ZipOutputStream(OutputStream out) {
this(out, Charset.forName("UTF-8"));
this(out, StandardCharset.UTF_8);
}
/**
......
......@@ -26,6 +26,7 @@ package sun.awt;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.StandardCharset;
import sun.nio.cs.HistoricallyNamedCharset;
public class FontDescriptor implements Cloneable {
......@@ -104,8 +105,8 @@ public class FontDescriptor implements Cloneable {
if (useUnicode && unicodeEncoder == null) {
try {
this.unicodeEncoder = isLE?
Charset.forName("UTF_16LE").newEncoder():
Charset.forName("UTF_16BE").newEncoder();
StandardCharset.UTF_16LE.newEncoder():
StandardCharset.UTF_16BE.newEncoder();
} catch (IllegalArgumentException x) {}
}
return useUnicode;
......
......@@ -38,7 +38,6 @@ import java.security.*;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.x509.CertificateIssuerName;
import sun.security.x509.KeyUsageExtension;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
import sun.security.x509.X509CRLImpl;
......@@ -493,7 +492,7 @@ public class PKCS7 {
// CRLs (optional)
if (crls != null && crls.length != 0) {
// cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
Set<X509CRLImpl> implCRLs = new HashSet<>(crls.length);
Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length);
for (X509CRL crl: crls) {
if (crl instanceof X509CRLImpl)
implCRLs.add((X509CRLImpl) crl);
......@@ -530,168 +529,6 @@ public class PKCS7 {
block.encode(out);
}
/**
* Verifying signed data using an external chunked data source.
*/
public static class PKCS7Verifier {
private final SignerInfo si; // Signer to verify
private final MessageDigest md; // MessageDigest object for chunks
private final Signature sig; // Signature object for chunks
private PKCS7Verifier(SignerInfo si, MessageDigest md, Signature sig) {
this.si = si;
this.md = md;
this.sig = sig;
}
public static PKCS7Verifier from(PKCS7 block, SignerInfo si) throws
SignatureException, NoSuchAlgorithmException {
try {
MessageDigest md = null;
Signature sig;
ContentInfo content = block.getContentInfo();
String digestAlgname = si.getDigestAlgorithmId().getName();
// if there are authenticate attributes, feed data chunks to
// the message digest. In this case, pv.md is not null
if (si.authenticatedAttributes != null) {
// first, check content type
ObjectIdentifier contentType = (ObjectIdentifier)
si.authenticatedAttributes.getAttributeValue(
PKCS9Attribute.CONTENT_TYPE_OID);
if (contentType == null ||
!contentType.equals(content.contentType))
return null; // contentType does not match, bad SignerInfo
// now, check message digest
byte[] messageDigest = (byte[])
si.authenticatedAttributes.getAttributeValue(
PKCS9Attribute.MESSAGE_DIGEST_OID);
if (messageDigest == null) // fail if there is no message digest
return null;
md = MessageDigest.getInstance(digestAlgname);
}
// put together digest algorithm and encryption algorithm
// to form signing algorithm
String encryptionAlgname =
si.getDigestEncryptionAlgorithmId().getName();
// Workaround: sometimes the encryptionAlgname is actually
// a signature name
String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
if (tmp != null) encryptionAlgname = tmp;
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
sig = Signature.getInstance(algname);
X509Certificate cert = si.getCertificate(block);
if (cert == null) {
return null;
}
if (cert.hasUnsupportedCriticalExtension()) {
throw new SignatureException("Certificate has unsupported "
+ "critical extension(s)");
}
// Make sure that if the usage of the key in the certificate is
// restricted, it can be used for digital signatures.
// XXX We may want to check for additional extensions in the
// future.
boolean[] keyUsageBits = cert.getKeyUsage();
if (keyUsageBits != null) {
KeyUsageExtension keyUsage;
try {
// We don't care whether or not this extension was marked
// critical in the certificate.
// We're interested only in its value (i.e., the bits set)
// and treat the extension as critical.
keyUsage = new KeyUsageExtension(keyUsageBits);
} catch (IOException ioe) {
throw new SignatureException("Failed to parse keyUsage "
+ "extension");
}
boolean digSigAllowed = ((Boolean)keyUsage.get(
KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue();
boolean nonRepuAllowed = ((Boolean)keyUsage.get(
KeyUsageExtension.NON_REPUDIATION)).booleanValue();
if (!digSigAllowed && !nonRepuAllowed) {
throw new SignatureException("Key usage restricted: "
+ "cannot be used for "
+ "digital signatures");
}
}
PublicKey key = cert.getPublicKey();
sig.initVerify(key);
return new PKCS7Verifier(si, md, sig);
} catch (IOException e) {
throw new SignatureException("IO error verifying signature:\n" +
e.getMessage());
} catch (InvalidKeyException e) {
throw new SignatureException("InvalidKey: " + e.getMessage());
}
}
public void update(byte[] data, int off, int end)
throws SignatureException {
if (md != null) {
md.update(data, off, end-off);
} else {
sig.update(data, off, end-off);
}
}
public SignerInfo verify() throws SignatureException {
try {
// if there are authenticate attributes, get the message
// digest and compare it with the digest of data
if (md != null) {
// now, check message digest
byte[] messageDigest = (byte[])
si.authenticatedAttributes.getAttributeValue(
PKCS9Attribute.MESSAGE_DIGEST_OID);
byte[] computedMessageDigest = md.digest();
if (!MessageDigest.isEqual(
messageDigest, computedMessageDigest)) {
return null;
}
// message digest attribute matched
// digest of original data
// the data actually signed is the DER encoding of
// the authenticated attributes (tagged with
// the "SET OF" tag, not 0xA0).
byte[] dataSigned = si.authenticatedAttributes.getDerEncoding();
sig.update(dataSigned);
}
if (sig.verify(si.getEncryptedDigest())) {
return si;
}
} catch (IOException e) {
throw new SignatureException("IO error verifying signature:\n" +
e.getMessage());
}
return null;
}
}
/**
* This verifies a given SignerInfo.
*
......@@ -717,16 +554,19 @@ public class PKCS7 {
public SignerInfo[] verify(byte[] bytes)
throws NoSuchAlgorithmException, SignatureException {
List<SignerInfo> intResult = new ArrayList<>();
Vector<SignerInfo> intResult = new Vector<SignerInfo>();
for (int i = 0; i < signerInfos.length; i++) {
SignerInfo signerInfo = verify(signerInfos[i], bytes);
if (signerInfo != null) {
intResult.add(signerInfo);
intResult.addElement(signerInfo);
}
}
if (!intResult.isEmpty()) {
return intResult.toArray(new SignerInfo[intResult.size()]);
if (intResult.size() != 0) {
SignerInfo[] result = new SignerInfo[intResult.size()];
intResult.copyInto(result);
return result;
}
return null;
}
......
......@@ -230,7 +230,7 @@ public class SignerInfo implements DerEncoder {
if (userCert == null)
return null;
ArrayList<X509Certificate> certList = new ArrayList<>();
ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>();
certList.add(userCert);
X509Certificate[] pkcsCerts = block.getCertificates();
......@@ -278,18 +278,130 @@ public class SignerInfo implements DerEncoder {
SignerInfo verify(PKCS7 block, byte[] data)
throws NoSuchAlgorithmException, SignatureException {
PKCS7.PKCS7Verifier p7v = PKCS7.PKCS7Verifier.from(block, this);
if (p7v == null) return null;
try {
ContentInfo content = block.getContentInfo();
if (data == null) {
data = content.getContentBytes();
}
String digestAlgname = getDigestAlgorithmId().getName();
byte[] dataSigned;
// if there are authenticate attributes, get the message
// digest and compare it with the digest of data
if (authenticatedAttributes == null) {
dataSigned = data;
} else {
// first, check content type
ObjectIdentifier contentType = (ObjectIdentifier)
authenticatedAttributes.getAttributeValue(
PKCS9Attribute.CONTENT_TYPE_OID);
if (contentType == null ||
!contentType.equals(content.contentType))
return null; // contentType does not match, bad SignerInfo
// now, check message digest
byte[] messageDigest = (byte[])
authenticatedAttributes.getAttributeValue(
PKCS9Attribute.MESSAGE_DIGEST_OID);
if (messageDigest == null) // fail if there is no message digest
return null;
MessageDigest md = MessageDigest.getInstance(digestAlgname);
byte[] computedMessageDigest = md.digest(data);
if (messageDigest.length != computedMessageDigest.length)
return null;
for (int i = 0; i < messageDigest.length; i++) {
if (messageDigest[i] != computedMessageDigest[i])
return null;
}
// message digest attribute matched
// digest of original data
// the data actually signed is the DER encoding of
// the authenticated attributes (tagged with
// the "SET OF" tag, not 0xA0).
dataSigned = authenticatedAttributes.getDerEncoding();
}
// put together digest algorithm and encryption algorithm
// to form signing algorithm
String encryptionAlgname =
getDigestEncryptionAlgorithmId().getName();
// Workaround: sometimes the encryptionAlgname is actually
// a signature name
String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
if (tmp != null) encryptionAlgname = tmp;
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
Signature sig = Signature.getInstance(algname);
X509Certificate cert = getCertificate(block);
if (cert == null) {
return null;
}
if (cert.hasUnsupportedCriticalExtension()) {
throw new SignatureException("Certificate has unsupported "
+ "critical extension(s)");
}
// Make sure that if the usage of the key in the certificate is
// restricted, it can be used for digital signatures.
// XXX We may want to check for additional extensions in the
// future.
boolean[] keyUsageBits = cert.getKeyUsage();
if (keyUsageBits != null) {
KeyUsageExtension keyUsage;
try {
data = block.getContentInfo().getContentBytes();
// We don't care whether or not this extension was marked
// critical in the certificate.
// We're interested only in its value (i.e., the bits set)
// and treat the extension as critical.
keyUsage = new KeyUsageExtension(keyUsageBits);
} catch (IOException ioe) {
throw new SignatureException("Failed to parse keyUsage "
+ "extension");
}
boolean digSigAllowed = ((Boolean)keyUsage.get(
KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue();
boolean nonRepuAllowed = ((Boolean)keyUsage.get(
KeyUsageExtension.NON_REPUDIATION)).booleanValue();
if (!digSigAllowed && !nonRepuAllowed) {
throw new SignatureException("Key usage restricted: "
+ "cannot be used for "
+ "digital signatures");
}
}
PublicKey key = cert.getPublicKey();
sig.initVerify(key);
sig.update(dataSigned);
if (sig.verify(encryptedDigest)) {
return this;
}
} catch (IOException e) {
throw new SignatureException("IO error verifying signature:\n" +
e.getMessage());
} catch (InvalidKeyException e) {
throw new SignatureException("InvalidKey: " + e.getMessage());
}
}
p7v.update(data, 0, data.length);
return p7v.verify();
return null;
}
/* Verify the content of the pkcs7 block. */
......
......@@ -191,8 +191,8 @@ public class ManifestEntryVerifier {
*
*
*/
public CodeSigner[] verify(Map<String, CodeSigner[]> verifiedSigners,
Map<String, CodeSigner[]> sigFileSigners)
public CodeSigner[] verify(Hashtable<String, CodeSigner[]> verifiedSigners,
Hashtable<String, CodeSigner[]> sigFileSigners)
throws JarException
{
if (skip) {
......
/*
* Copyright (c) 2011, 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.security.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
/**
* This class provides streaming mode reading of manifest files.
* Used by {@link SignatureFileVerifier}.
*/
class SignatureFileManifest extends Manifest {
/*
* Reading a manifest into this object by calling update(byte[]) on chunks.
* During the reading, the bytes are saved in (@code current} until a line
* is complete and the key-value pair is saved in {@code currentAttr}. When
* a section is complete, {@code consumeAttr} is called to merge
* {@code currentAttr} into main attributes or a named entry.
*/
// Internal state during update() style reading
// 0. not in update mode
// 1, in update mode but main attributes not completed yet
// 2. main attributes completed, still reading the entries
private int state = 0;
// The partial line read
private byte[] current;
// Number of bytes in current
private int currentPos = 0;
// The current Attribute
private Attributes currentAttr;
/**
* Reads a manifest in chunks.
* <p>
* This method must be called in a row, reading chunks from a single
* manifest file by order. After all chunks are read, caller must call
* {@code update(null)} to fully consume the manifest.
* <p>
* The entry names and attributes read will be merged in with the current
* manifest entries. The {@link #read} method cannot be called inside a
* row of update calls.
* <p>
* Along with the calls, caller can call {@link #getMainAttributes()},
* {@link #getAttributes(java.lang.String)} or {@link #getEntries()}
* to get already available contents. However, in order not to return
* partial result, when the main attributes in the new manifest is not
* consumed completely, {@link #getMainAttributes()} throws an
* {@code IllegalStateException}. When a certain named entry is not
* consumed completely, {@link #getAttributes(java.lang.String)}
* returns the old {@code Attributes} for the name (if it exists).
*
* @param data null for last call, otherwise, feeding chunks
* @param offset offset into data to begin read
* @param length length of data after offset to read
* @exception IOException if an I/O error has occurred
* @exception IllegalStateException if {@code update(null)} is called
* without any previous {@code update(non-null)} call
*/
public void update(byte[] data, int offset, int length) throws IOException {
// The last call
if (data == null) {
if (state == 0) {
throw new IllegalStateException("No data to update");
}
// We accept manifest not ended with \n or \n\n
if (hasLastByte()) {
consumeCurrent();
}
// We accept empty lines at the end
if (!currentAttr.isEmpty()) {
consumeAttr();
}
state = 0; // back to non-update state
current = null;
currentAttr = null;
return;
}
// The first call
if (state == 0) {
current = new byte[1024];
currentAttr = super.getMainAttributes(); // the main attribute
state = 1;
}
int end = offset + length;
while (offset < end) {
switch (data[offset]) {
case '\r':
break; // always skip
case '\n':
if (hasLastByte() && lastByte() == '\n') { // new section
consumeCurrent();
consumeAttr();
if (state == 1) {
state = 2;
}
currentAttr = new Attributes(2);
} else {
if (hasLastByte()) {
// save \n into current but do not parse,
// there might be a continuation later
ensureCapacity();
current[currentPos++] = data[offset];
} else if (state == 1) {
// there can be multiple empty lines between
// sections, but cannot be at the beginning
throw new IOException("invalid manifest format");
}
}
break;
case ' ':
if (!hasLastByte()) {
throw new IOException("invalid manifest format");
} else if (lastByte() == '\n') {
currentPos--; // continuation, remove last \n
} else { // a very normal ' '
ensureCapacity();
current[currentPos++] = data[offset];
}
break;
default:
if (hasLastByte() && lastByte() == '\n') {
// The start of a new pair, not continuation
consumeCurrent(); // the last line read
}
ensureCapacity();
current[currentPos++] = data[offset];
break;
}
offset++;
}
}
/**
* Returns the main Attributes for the Manifest.
* @exception IllegalStateException the main attributes is being read
* @return the main Attributes for the Manifest
*/
public Attributes getMainAttributes() {
if (state == 1) {
throw new IllegalStateException();
}
return super.getMainAttributes();
}
/**
* Reads the Manifest from the specified InputStream. The entry
* names and attributes read will be merged in with the current
* manifest entries.
*
* @param is the input stream
* @exception IOException if an I/O error has occurred
* @exception IllegalStateException if called between two {@link #update}
* calls
*/
public void read(InputStream is) throws IOException {
if (state != 0) {
throw new IllegalStateException("Cannot call read between updates");
}
super.read(is);
}
/*
* ---------- Helper methods -----------------
*/
private void ensureCapacity() {
if (currentPos >= current.length-1) {
current = Arrays.copyOf(current, current.length*2);
}
}
private boolean hasLastByte() {
return currentPos > 0;
}
private byte lastByte() {
return current[currentPos-1];
}
// Parse current as key:value and save into currentAttr.
// There MUST be something inside current.
private void consumeCurrent() throws IOException {
// current normally has a \n end, except for the last line
if (current[currentPos-1] == '\n') currentPos--;
for (int i=0; i<currentPos; i++) {
if (current[i] == ':') {
String key = new String(current, 0, 0, i);
i++;
while (i < currentPos && current[i] == ' ') { i++; }
String value = new String(current, i, currentPos-i, "UTF-8");
currentAttr.putValue(key, value);
currentPos = 0;
return;
}
}
throw new IOException("invalid header field");
}
// Merge currentAttr into Manifest
private void consumeAttr() throws IOException {
// Only needed for named entries. For the main attribute, key/value
// is added into attr directly, but since getMainAttributes() throws
// an exception, the partial data is not leaked.
if (state != 1) {
String name = currentAttr.getValue("Name");
if (name != null) {
currentAttr.remove(new Attributes.Name("Name"));
Attributes old = getAttributes(name);
if (old != null) old.putAll(currentAttr);
else getEntries().put(name, currentAttr);
} else {
throw new IOException("invalid manifest format");
}
}
}
}
......@@ -55,8 +55,8 @@ public class SignatureFileVerifier {
/** the PKCS7 block for this .DSA/.RSA/.EC file */
private PKCS7 block;
// the content of the raw .SF file as an InputStream
private InputStream sfStream;
/** the raw bytes of the .SF file */
private byte sfBytes[];
/** the name of the signature block file, uppercased and without
* the extension (.DSA/.RSA/.EC)
......@@ -66,9 +66,6 @@ public class SignatureFileVerifier {
/** the ManifestDigester */
private ManifestDigester md;
/** The MANIFEST.MF */
private Manifest man;
/** cache of created MessageDigest objects */
private HashMap<String, MessageDigest> createdDigests;
......@@ -86,7 +83,6 @@ public class SignatureFileVerifier {
* @param rawBytes the raw bytes of the signature block file
*/
public SignatureFileVerifier(ArrayList<CodeSigner[]> signerCache,
Manifest man,
ManifestDigester md,
String name,
byte rawBytes[])
......@@ -98,18 +94,13 @@ public class SignatureFileVerifier {
try {
obj = Providers.startJarVerification();
block = new PKCS7(rawBytes);
byte[] contentData = block.getContentInfo().getData();
if (contentData != null) {
sfStream = new ByteArrayInputStream(contentData);
}
sfBytes = block.getContentInfo().getData();
certificateFactory = CertificateFactory.getInstance("X509");
} finally {
Providers.stopJarVerification(obj);
}
this.name = name.substring(0, name.lastIndexOf("."))
.toUpperCase(Locale.ENGLISH);
this.man = man;
this.md = md;
this.signerCache = signerCache;
}
......@@ -117,13 +108,31 @@ public class SignatureFileVerifier {
/**
* returns true if we need the .SF file
*/
public boolean needSignatureFile()
public boolean needSignatureFileBytes()
{
return sfBytes == null;
}
/**
* returns true if we need this .SF file.
*
* @param name the name of the .SF file without the extension
*
*/
public boolean needSignatureFile(String name)
{
return sfStream == null;
return this.name.equalsIgnoreCase(name);
}
public void setSignatureFile(InputStream ins) {
this.sfStream = ins;
/**
* used to set the raw bytes of the .SF file when it
* is external to the signature block file.
*/
public void setSignatureFile(byte sfBytes[])
{
this.sfBytes = sfBytes;
}
/**
......@@ -136,18 +145,12 @@ public class SignatureFileVerifier {
* Signature File or PKCS7 block file name
*/
public static boolean isBlockOrSF(String s) {
return s.endsWith(".SF") || isBlock(s);
// we currently only support DSA and RSA PKCS7 blocks
if (s.endsWith(".SF") || s.endsWith(".DSA") ||
s.endsWith(".RSA") || s.endsWith(".EC")) {
return true;
}
/**
* Utility method used by JarVerifier to determine PKCS7 block
* files names that are supported
*
* @param s file name
* @return true if the input file name is a PKCS7 block file name
*/
public static boolean isBlock(String s) {
return s.endsWith(".DSA") || s.endsWith(".RSA") || s.endsWith(".EC");
return false;
}
/** get digest from cache */
......@@ -177,7 +180,7 @@ public class SignatureFileVerifier {
*
*
*/
public void process(Map<String, CodeSigner[]> signers,
public void process(Hashtable<String, CodeSigner[]> signers,
List manifestDigests)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
......@@ -194,86 +197,31 @@ public class SignatureFileVerifier {
}
private void processImpl(Map<String, CodeSigner[]> signers,
private void processImpl(Hashtable<String, CodeSigner[]> signers,
List manifestDigests)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
SignatureFileManifest sf = new SignatureFileManifest();
InputStream ins = sfStream;
Manifest sf = new Manifest();
sf.read(new ByteArrayInputStream(sfBytes));
byte[] buffer = new byte[4096];
int sLen = block.getSignerInfos().length;
boolean mainOK = false; // main attributes of SF is available...
boolean manifestSigned = false; // and it matches MANIFEST.MF
BASE64Decoder decoder = new BASE64Decoder();
String version =
sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION);
PKCS7.PKCS7Verifier[] pvs = new PKCS7.PKCS7Verifier[sLen];
for (int i=0; i<sLen; i++) {
pvs[i] = PKCS7.PKCS7Verifier.from(block, block.getSignerInfos()[i]);
}
/*
* Verify SF in streaming mode. The chunks of the file are fed into
* the Manifest object sf and all PKCS7Verifiers. As soon as the main
* attributes is available, we'll check if manifestSigned is true. If
* yes, there is no need to fill in sf's entries field, since it should
* be identical to entries in man.
*/
while (true) {
int len = ins.read(buffer);
if (len < 0) {
if (!manifestSigned) {
sf.update(null, 0, 0);
}
break;
} else {
for (int i=0; i<sLen; i++) {
if (pvs[i] != null) pvs[i].update(buffer, 0, len);
}
// Continue reading if verifyManifestHash fails (or, the
// main attributes is not available yet)
if (!manifestSigned) {
sf.update(buffer, 0, len);
if (!mainOK) {
try {
Attributes attr = sf.getMainAttributes();
String version = attr.getValue(
Attributes.Name.SIGNATURE_VERSION);
if ((version == null) ||
!(version.equalsIgnoreCase("1.0"))) {
if ((version == null) || !(version.equalsIgnoreCase("1.0"))) {
// XXX: should this be an exception?
// for now we just ignore this signature file
return;
}
mainOK = true;
manifestSigned = verifyManifestHash(
sf, md, decoder, manifestDigests);
} catch (IllegalStateException ise) {
// main attributes not available yet
}
}
}
}
}
List<SignerInfo> intResult = new ArrayList<>(sLen);
for (int i = 0; i < sLen; i++) {
if (pvs[i] != null) {
SignerInfo signerInfo = pvs[i].verify();
if (signerInfo != null) {
intResult.add(signerInfo);
}
}
}
if (intResult.isEmpty()) {
SignerInfo[] infos = block.verify(sfBytes);
if (infos == null) {
throw new SecurityException("cannot verify signature block file " +
name);
}
SignerInfo[] infos =
intResult.toArray(new SignerInfo[intResult.size()]);
BASE64Decoder decoder = new BASE64Decoder();
CodeSigner[] newSigners = getSigners(infos, block);
......@@ -281,30 +229,19 @@ public class SignatureFileVerifier {
if (newSigners == null)
return;
Iterator<Map.Entry<String,Attributes>> entries =
sf.getEntries().entrySet().iterator();
// see if we can verify the whole manifest first
boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests);
// verify manifest main attributes
if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) {
throw new SecurityException
("Invalid signature file digest for Manifest main attributes");
}
Iterator<Map.Entry<String,Attributes>> entries;
if (manifestSigned) {
if (debug != null) {
debug.println("full manifest signature match, "
+ "update signer info from MANIFEST.MF");
}
entries = man.getEntries().entrySet().iterator();
} else {
if (debug != null) {
debug.println("full manifest signature unmatch, "
+ "update signer info from SF file");
}
entries = sf.getEntries().entrySet().iterator();
}
// go through each section
// go through each section in the signature file
while(entries.hasNext()) {
Map.Entry<String,Attributes> e = entries.next();
......@@ -656,6 +593,7 @@ public class SignatureFileVerifier {
if (set == subset)
return true;
boolean match;
for (int i = 0; i < subset.length; i++) {
if (!contains(set, subset[i]))
return false;
......@@ -675,6 +613,8 @@ public class SignatureFileVerifier {
if ((oldSigners == null) && (signers == newSigners))
return true;
boolean match;
// make sure all oldSigners are in signers
if ((oldSigners != null) && !isSubSet(oldSigners, signers))
return false;
......@@ -698,7 +638,7 @@ public class SignatureFileVerifier {
}
void updateSigners(CodeSigner[] newSigners,
Map<String, CodeSigner[]> signers, String name) {
Hashtable<String, CodeSigner[]> signers, String name) {
CodeSigner[] oldSigners = signers.get(name);
......
......@@ -99,8 +99,6 @@ class EPoll {
// -- Native methods --
private static native void init();
private static native int eventSize();
private static native int eventsOffset();
......@@ -116,6 +114,5 @@ class EPoll {
static {
Util.load();
init();
}
}
......@@ -432,8 +432,6 @@ class LinuxWatchService
// -- native methods --
private static native void init();
// sizeof inotify_event
private static native int eventSize();
......@@ -461,6 +459,5 @@ class LinuxWatchService
System.loadLibrary("nio");
return null;
}});
init();
}
}
......@@ -34,55 +34,7 @@
#include <dlfcn.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/* epoll_wait(2) man page */
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t;
struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
} __attribute__ ((__packed__));
#ifdef __cplusplus
}
#endif
/*
* epoll event notification is new in 2.6 kernel. As the offical build
* platform for the JDK is on a 2.4-based distribution then we must
* obtain the addresses of the epoll functions dynamically.
*/
typedef int (*epoll_create_t)(int size);
typedef int (*epoll_ctl_t) (int epfd, int op, int fd, struct epoll_event *event);
typedef int (*epoll_wait_t) (int epfd, struct epoll_event *events, int maxevents, int timeout);
static epoll_create_t epoll_create_func;
static epoll_ctl_t epoll_ctl_func;
static epoll_wait_t epoll_wait_func;
JNIEXPORT void JNICALL
Java_sun_nio_ch_EPoll_init(JNIEnv *env, jclass this)
{
epoll_create_func = (epoll_create_t) dlsym(RTLD_DEFAULT, "epoll_create");
epoll_ctl_func = (epoll_ctl_t) dlsym(RTLD_DEFAULT, "epoll_ctl");
epoll_wait_func = (epoll_wait_t) dlsym(RTLD_DEFAULT, "epoll_wait");
if ((epoll_create_func == NULL) || (epoll_ctl_func == NULL) ||
(epoll_wait_func == NULL)) {
JNU_ThrowInternalError(env, "unable to get address of epoll functions, pre-2.6 kernel?");
}
}
#include <sys/epoll.h>
JNIEXPORT jint JNICALL
Java_sun_nio_ch_EPoll_eventSize(JNIEnv* env, jclass this)
......@@ -108,7 +60,7 @@ Java_sun_nio_ch_EPoll_epollCreate(JNIEnv *env, jclass c) {
* epoll_create expects a size as a hint to the kernel about how to
* dimension internal structures. We can't predict the size in advance.
*/
int epfd = (*epoll_create_func)(256);
int epfd = epoll_create(256);
if (epfd < 0) {
JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
}
......@@ -125,7 +77,7 @@ Java_sun_nio_ch_EPoll_epollCtl(JNIEnv *env, jclass c, jint epfd,
event.events = events;
event.data.fd = fd;
RESTARTABLE((*epoll_ctl_func)(epfd, (int)opcode, (int)fd, &event), res);
RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res);
return (res == 0) ? 0 : errno;
}
......@@ -137,7 +89,7 @@ Java_sun_nio_ch_EPoll_epollWait(JNIEnv *env, jclass c,
struct epoll_event *events = jlong_to_ptr(address);
int res;
RESTARTABLE((*epoll_wait_func)(epfd, events, numfds, -1), res);
RESTARTABLE(epoll_wait(epfd, events, numfds, -1), res);
if (res < 0) {
JNU_ThrowIOExceptionWithLastError(env, "epoll_wait failed");
}
......
......@@ -33,33 +33,10 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/inotify.h>
#include "sun_nio_fs_LinuxWatchService.h"
/* inotify.h may not be available at build time */
#ifdef __cplusplus
extern "C" {
#endif
struct inotify_event
{
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name __flexarr;
};
#ifdef __cplusplus
}
#endif
typedef int inotify_init_func(void);
typedef int inotify_add_watch_func(int fd, const char* path, uint32_t mask);
typedef int inotify_rm_watch_func(int fd, uint32_t wd);
inotify_init_func* my_inotify_init_func = NULL;
inotify_add_watch_func* my_inotify_add_watch_func = NULL;
inotify_rm_watch_func* my_inotify_rm_watch_func = NULL;
static void throwUnixException(JNIEnv* env, int errnum) {
jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
"(I)V", errnum);
......@@ -68,22 +45,6 @@ static void throwUnixException(JNIEnv* env, int errnum) {
}
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_LinuxWatchService_init(JNIEnv *env, jclass clazz)
{
my_inotify_init_func = (inotify_init_func*)
dlsym(RTLD_DEFAULT, "inotify_init");
my_inotify_add_watch_func =
(inotify_add_watch_func*) dlsym(RTLD_DEFAULT, "inotify_add_watch");
my_inotify_rm_watch_func =
(inotify_rm_watch_func*) dlsym(RTLD_DEFAULT, "inotify_rm_watch");
if ((my_inotify_init_func == NULL) || (my_inotify_add_watch_func == NULL) ||
(my_inotify_rm_watch_func == NULL)) {
JNU_ThrowInternalError(env, "unable to get address of inotify functions");
}
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_LinuxWatchService_eventSize(JNIEnv *env, jclass clazz)
{
......@@ -111,7 +72,7 @@ JNIEXPORT jint JNICALL
Java_sun_nio_fs_LinuxWatchService_inotifyInit
(JNIEnv* env, jclass clazz)
{
int ifd = (*my_inotify_init_func)();
int ifd = inotify_init();
if (ifd == -1) {
throwUnixException(env, errno);
}
......@@ -125,7 +86,7 @@ Java_sun_nio_fs_LinuxWatchService_inotifyAddWatch
int wfd = -1;
const char* path = (const char*)jlong_to_ptr(address);
wfd = (*my_inotify_add_watch_func)((int)fd, path, mask);
wfd = inotify_add_watch((int)fd, path, mask);
if (wfd == -1) {
throwUnixException(env, errno);
}
......@@ -136,7 +97,7 @@ JNIEXPORT void JNICALL
Java_sun_nio_fs_LinuxWatchService_inotifyRmWatch
(JNIEnv* env, jclass clazz, jint fd, jint wd)
{
int err = (*my_inotify_rm_watch_func)((int)fd, (int)wd);
int err = inotify_rm_watch((int)fd, (int)wd);
if (err == -1)
throwUnixException(env, errno);
}
......@@ -166,7 +127,6 @@ Java_sun_nio_fs_LinuxWatchService_socketpair
res[1] = (jint)sp[1];
(*env)->SetIntArrayRegion(env, sv, 0, 2, &res[0]);
}
}
JNIEXPORT jint JNICALL
......@@ -190,6 +150,4 @@ Java_sun_nio_fs_LinuxWatchService_poll
}
}
return (jint)n;
}
......@@ -50,6 +50,9 @@ import sun.security.rsa.RSAKeyFactory;
* following algorithm names:
*
* . "SHA1withRSA"
* . "SHA256withRSA"
* . "SHA384withRSA"
* . "SHA512withRSA"
* . "MD5withRSA"
* . "MD2withRSA"
*
......@@ -63,7 +66,10 @@ abstract class RSASignature extends java.security.SignatureSpi
// message digest implementation we use
private final MessageDigest messageDigest;
// flag indicating whether the digest is reset
// message digest name
private final String messageDigestAlgorithm;
// flag indicating whether the digest has been reset
private boolean needsReset;
// the signing key
......@@ -73,10 +79,15 @@ abstract class RSASignature extends java.security.SignatureSpi
private Key publicKey = null;
/**
* Constructs a new RSASignature. Used by subclasses.
*/
RSASignature(String digestName) {
try {
messageDigest = MessageDigest.getInstance(digestName);
// Get the digest's canonical name
messageDigestAlgorithm = messageDigest.getAlgorithm();
} catch (NoSuchAlgorithmException e) {
throw new ProviderException(e);
......@@ -91,6 +102,24 @@ abstract class RSASignature extends java.security.SignatureSpi
}
}
public static final class SHA256 extends RSASignature {
public SHA256() {
super("SHA-256");
}
}
public static final class SHA384 extends RSASignature {
public SHA384() {
super("SHA-384");
}
}
public static final class SHA512 extends RSASignature {
public SHA512() {
super("SHA-512");
}
}
public static final class MD5 extends RSASignature {
public MD5() {
super("MD5");
......@@ -103,16 +132,7 @@ abstract class RSASignature extends java.security.SignatureSpi
}
}
/**
* Initializes this signature object with the specified
* public key for verification operations.
*
* @param publicKey the public key of the identity whose signature is
* going to be verified.
*
* @exception InvalidKeyException if the key is improperly
* encoded, parameters are missing, and so on.
*/
// initialize for signing. See JCA doc
protected void engineInitVerify(PublicKey key)
throws InvalidKeyException
{
......@@ -158,24 +178,12 @@ abstract class RSASignature extends java.security.SignatureSpi
publicKey = (sun.security.mscapi.RSAPublicKey) key;
}
if (needsReset) {
messageDigest.reset();
needsReset = false;
}
this.privateKey = null;
resetDigest();
}
/**
* Initializes this signature object with the specified
* private key for signing operations.
*
* @param privateKey the private key of the identity whose signature
* will be generated.
*
* @exception InvalidKeyException if the key is improperly
* encoded, parameters are missing, and so on.
*/
protected void engineInitSign(PrivateKey key)
throws InvalidKeyException
// initialize for signing. See JCA doc
protected void engineInitSign(PrivateKey key) throws InvalidKeyException
{
// This signature accepts only RSAPrivateKey
if ((key instanceof sun.security.mscapi.RSAPrivateKey) == false) {
......@@ -189,12 +197,25 @@ abstract class RSASignature extends java.security.SignatureSpi
null, RSAKeyPairGenerator.KEY_SIZE_MIN,
RSAKeyPairGenerator.KEY_SIZE_MAX);
this.publicKey = null;
resetDigest();
}
/**
* Resets the message digest if needed.
*/
private void resetDigest() {
if (needsReset) {
messageDigest.reset();
needsReset = false;
}
}
private byte[] getDigestValue() {
needsReset = false;
return messageDigest.digest();
}
/**
* Updates the data to be signed or verified
* using the specified byte.
......@@ -254,13 +275,12 @@ abstract class RSASignature extends java.security.SignatureSpi
*/
protected byte[] engineSign() throws SignatureException {
byte[] hash = messageDigest.digest();
needsReset = false;
byte[] hash = getDigestValue();
// Sign hash using MS Crypto APIs
byte[] result = signHash(hash, hash.length,
messageDigest.getAlgorithm(), privateKey.getHCryptProvider(),
messageDigestAlgorithm, privateKey.getHCryptProvider(),
privateKey.getHCryptKey());
// Convert signature array from little endian to big endian
......@@ -314,11 +334,10 @@ abstract class RSASignature extends java.security.SignatureSpi
protected boolean engineVerify(byte[] sigBytes)
throws SignatureException
{
byte[] hash = messageDigest.digest();
needsReset = false;
byte[] hash = getDigestValue();
return verifySignedHash(hash, hash.length,
messageDigest.getAlgorithm(), convertEndianArray(sigBytes),
messageDigestAlgorithm, convertEndianArray(sigBytes),
sigBytes.length, publicKey.getHCryptProvider(),
publicKey.getHCryptKey());
}
......
/*
* Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2011, 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
......@@ -81,6 +81,12 @@ public final class SunMSCAPI extends Provider {
*/
map.put("Signature.SHA1withRSA",
"sun.security.mscapi.RSASignature$SHA1");
map.put("Signature.SHA256withRSA",
"sun.security.mscapi.RSASignature$SHA256");
map.put("Signature.SHA384withRSA",
"sun.security.mscapi.RSASignature$SHA384");
map.put("Signature.SHA512withRSA",
"sun.security.mscapi.RSASignature$SHA512");
map.put("Signature.MD5withRSA",
"sun.security.mscapi.RSASignature$MD5");
map.put("Signature.MD2withRSA",
......@@ -89,12 +95,16 @@ public final class SunMSCAPI extends Provider {
// supported key classes
map.put("Signature.SHA1withRSA SupportedKeyClasses",
"sun.security.mscapi.Key");
map.put("Signature.SHA256withRSA SupportedKeyClasses",
"sun.security.mscapi.Key");
map.put("Signature.SHA384withRSA SupportedKeyClasses",
"sun.security.mscapi.Key");
map.put("Signature.SHA512withRSA SupportedKeyClasses",
"sun.security.mscapi.Key");
map.put("Signature.MD5withRSA SupportedKeyClasses",
"sun.security.mscapi.Key");
map.put("Signature.MD2withRSA SupportedKeyClasses",
"sun.security.mscapi.Key");
map.put("Signature.NONEwithRSA SupportedKeyClasses",
"sun.security.mscapi.Key");
/*
* Key Pair Generator engines
......
......@@ -483,6 +483,7 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
jbyte* pHashBuffer = NULL;
jbyte* pSignedHashBuffer = NULL;
jbyteArray jSignedHash = NULL;
HCRYPTPROV hCryptProvAlt = NULL;
__try
{
......@@ -491,10 +492,34 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
// Acquire a hash object handle.
if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash) == FALSE)
{
// Failover to using the PROV_RSA_AES CSP
DWORD cbData = 256;
BYTE pbData[256];
pbData[0] = '\0';
// Get name of the key container
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
(BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle
if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
PROV_RSA_AES, 0) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
}
// Acquire a hash object handle.
if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
&hHash) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
}
}
// Copy hash from Java to native buffer
pHashBuffer = new jbyte[jHashSize];
......@@ -546,6 +571,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash
}
__finally
{
if (hCryptProvAlt)
::CryptReleaseContext(hCryptProvAlt, 0);
if (pSignedHashBuffer)
delete [] pSignedHashBuffer;
......@@ -574,6 +602,7 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas
jbyte* pSignedHashBuffer = NULL;
DWORD dwSignedHashBufferLen = jSignedHashSize;
jboolean result = JNI_FALSE;
HCRYPTPROV hCryptProvAlt = NULL;
__try
{
......@@ -583,10 +612,34 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas
// Acquire a hash object handle.
if (::CryptCreateHash(HCRYPTPROV(hCryptProv), algId, 0, 0, &hHash)
== FALSE)
{
// Failover to using the PROV_RSA_AES CSP
DWORD cbData = 256;
BYTE pbData[256];
pbData[0] = '\0';
// Get name of the key container
::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER,
(BYTE *)pbData, &cbData, 0);
// Acquire an alternative CSP handle
if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL,
PROV_RSA_AES, 0) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
}
// Acquire a hash object handle.
if (::CryptCreateHash(HCRYPTPROV(hCryptProvAlt), algId, 0, 0,
&hHash) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
__leave;
}
}
// Copy hash and signedHash from Java to native buffer
pHashBuffer = new jbyte[jHashSize];
......@@ -616,6 +669,9 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas
__finally
{
if (hCryptProvAlt)
::CryptReleaseContext(hCryptProvAlt, 0);
if (pSignedHashBuffer)
delete [] pSignedHashBuffer;
......@@ -648,6 +704,17 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR
pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
// Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures.
if (::CryptAcquireContext(
&hCryptProv,
pszKeyContainerName,
NULL,
PROV_RSA_AES,
CRYPT_NEWKEYSET) == FALSE)
{
// Failover to using the default CSP (PROV_RSA_FULL)
if (::CryptAcquireContext(
&hCryptProv,
pszKeyContainerName,
......@@ -658,6 +725,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR
ThrowException(env, KEY_EXCEPTION, GetLastError());
__leave;
}
}
// Generate an RSA keypair
if(::CryptGenKey(
......@@ -1849,6 +1917,17 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0);
// Acquire a CSP context (create a new key container).
// Prefer a PROV_RSA_AES CSP, when available, due to its support
// for SHA-2-based signatures.
if (::CryptAcquireContext(
&hCryptProv,
NULL,
NULL,
PROV_RSA_AES,
CRYPT_VERIFYCONTEXT) == FALSE)
{
// Failover to using the default CSP (PROV_RSA_FULL)
if (::CryptAcquireContext(
&hCryptProv,
NULL,
......@@ -1859,6 +1938,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSASignature_importPublicKey
ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
__leave;
}
}
// Import the public key
if (::CryptImportKey(
......
/*
* Copyright (c) 2011, 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.
*
* 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.
*/
/*
* @test
* @bug 4884238
* @summary Test standard charset name constants.
* @author Mike Duigou
* @run main Standard
*/
import java.nio.charset.*;
public class Standard {
public static void realMain(String[] args) {
check(StandardCharset.US_ASCII instanceof Charset);
check(StandardCharset.ISO_8859_1 instanceof Charset);
check(StandardCharset.UTF_8 instanceof Charset);
check(StandardCharset.UTF_16BE instanceof Charset);
check(StandardCharset.UTF_16LE instanceof Charset);
check(StandardCharset.UTF_16 instanceof Charset);
check("US-ASCII".equals(StandardCharset.US_ASCII.name());
check("ISO-8859-1".equals(StandardCharset.ISO_8859_1.name());
check("UTF-8".equals(StandardCharset.UTF_8.name());
check("UTF-16BE".equals(StandardCharset.UTF_16BE.name());
check("UTF-16LE".equals(StandardCharset.UTF_16LE.name());
check("UTF-16".equals(StandardCharset.UTF_16.name());
}
//--------------------- Infrastructure ---------------------------
static volatile int passed = 0, failed = 0;
static void pass() { passed++; }
static void fail() { failed++; Thread.dumpStack(); }
static void fail(String msg) { System.out.println(msg); fail(); }
static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
static void check(boolean cond) { if (cond) pass(); else fail(); }
static void equal(Object x, Object y) {
if (x == null ? y == null : x.equals(y)) pass();
else {System.out.println(x + " not equal to " + y); fail();}}
static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}
public static void main(String[] args) throws Throwable {
try { realMain(args); } catch (Throwable t) { unexpected(t); }
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new Exception("Some tests failed");
}
private static abstract class Fun {abstract void f() throws Throwable;}
private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
for (Fun f : fs)
try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
catch (Throwable t) {
if (k.isAssignableFrom(t.getClass())) pass();
else unexpected(t);}}
static byte[] serializedForm(Object obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(obj);
return baos.toByteArray();
} catch (IOException e) { throw new Error(e); }}
static Object readObject(byte[] bytes)
throws IOException, ClassNotFoundException {
InputStream is = new ByteArrayInputStream(bytes);
return new ObjectInputStream(is).readObject();}
@SuppressWarnings("unchecked")
static <T> T serialClone(T obj) {
try { return (T) readObject(serializedForm(obj)); }
catch (Exception e) { throw new Error(e); }}
}
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2011, 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
......@@ -27,11 +27,9 @@
* @summary Confirm that JarEntry.getCertificates identifies signed entries.
*/
import java.io.*;
import java.net.URL;
import java.security.CodeSigner;
import java.security.cert.Certificate;
import java.util.Enumeration;
import java.util.jar.*;
/*
......@@ -72,6 +70,9 @@ public class ScanSignedJar {
if (signers == null && certificates == null) {
System.out.println("[unsigned]\t" + name + "\t(" + size +
" bytes)");
if (name.equals("Count.class")) {
throw new Exception("Count.class should be signed");
}
} else if (signers != null && certificates != null) {
System.out.println("[" + signers.length +
(signers.length == 1 ? " signer" : " signers") + "]\t" +
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2011, 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
......@@ -37,7 +37,7 @@ public class TestIndexedJarWithBadSignature {
public static void main(String...args) throws Throwable {
try (JarInputStream jis = new JarInputStream(
new FileInputStream(System.getProperty("tst.src", ".") +
new FileInputStream(System.getProperty("test.src", ".") +
System.getProperty("file.separator") +
"BadSignedJar.jar")))
{
......
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2011, 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
......@@ -22,8 +22,14 @@
*/
import java.io.*;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.security.auth.login.LoginException;
import sun.security.krb5.Asn1Exception;
import sun.security.krb5.Config;
public class BadKdc {
......@@ -34,8 +40,51 @@ public class BadKdc {
static final Pattern re = Pattern.compile(
">>> KDCCommunication: kdc=kdc.rabbit.hole UDP:(\\d)...., " +
"timeout=(\\d)000,");
/*
* There are several cases this test fails:
*
* 1. The random selected port is used by another process. No good way to
* prevent this happening, coz krb5.conf must be written before KDC starts.
* There are two different outcomes:
*
* a. Cannot start the KDC. A BindException thrown.
* b. When trying to access a non-existing KDC, a response is received!
* Most likely a Asn1Exception thrown
*
* 2. Even if a KDC is started, and more than 20 seconds pass by, a timeout
* can still happens for the first UDP request. In fact, the KDC did not
* received it at all. This happens on almost all platforms, especially
* solaris-i586 and solaris-x64.
*
* To avoid them:
*
* 1. Catch those exceptions and ignore
*
* 2. a. Make the timeout longer? useless
* b. Read the output carefully, if there is a timeout, it's OK.
* Just make sure the retries times and KDCs are correct.
* This is tough.
* c. Feed the KDC a UDP packet first. The current "solution".
*/
public static void go(int[]... expected)
throws Exception {
try {
go0(expected);
} catch (BindException be) {
System.out.println("The random port is used by another process");
} catch (LoginException le) {
Throwable cause = le.getCause();
if (cause instanceof Asn1Exception) {
System.out.println("Bad packet possibly from another process");
return;
}
throw le;
}
}
public static void go0(int[]... expected)
throws Exception {
System.setProperty("sun.security.krb5.debug", "true");
// Make sure KDCs' ports starts with 1 and 2 and 3,
......@@ -78,20 +127,39 @@ public class BadKdc {
KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p, true);
k.addPrincipal(OneKDC.USER, OneKDC.PASS);
k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
// Feed a packet to newly started KDC to warm it up
System.err.println("-------- IGNORE THIS ERROR MESSAGE --------");
new DatagramSocket().send(
new DatagramPacket("Hello".getBytes(), 5,
InetAddress.getByName(OneKDC.KDCHOST), p));
return k;
}
private static void test(int... expected) throws Exception {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
try {
test0(bo, expected);
} catch (Exception e) {
System.out.println("----------------- ERROR -----------------");
System.out.println(new String(bo.toByteArray()));
System.out.println("--------------- ERROR END ---------------");
throw e;
}
}
/**
* One round of test for max_retries and timeout.
* @param timeout the expected timeout
* @param expected the expected kdc# timeout kdc# timeout...
*/
private static void test(int... expected) throws Exception {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
private static void test0(ByteArrayOutputStream bo, int... expected)
throws Exception {
PrintStream oldout = System.out;
System.setOut(new PrintStream(bo));
Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
try {
Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
} finally {
System.setOut(oldout);
}
String[] lines = new String(bo.toByteArray()).split("\n");
System.out.println("----------------- TEST -----------------");
......
/*
* Copyright (c) 2011, 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.
*
* 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.
*/
/**
* @see SignUsingSHA2withRSA.sh
*/
import java.security.*;
import java.util.*;
public class SignUsingSHA2withRSA {
private static final byte[] toBeSigned = new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10
};
private static List<byte[]> generatedSignatures = new ArrayList<>();
public static void main(String[] args) throws Exception {
Provider[] providers = Security.getProviders("Signature.SHA256withRSA");
if (providers == null) {
System.out.println("No JCE providers support the " +
"'Signature.SHA256withRSA' algorithm");
System.out.println("Skipping this test...");
return;
} else {
System.out.println("The following JCE providers support the " +
"'Signature.SHA256withRSA' algorithm: ");
for (Provider provider : providers) {
System.out.println(" " + provider.getName());
}
}
System.out.println("-------------------------------------------------");
KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
ks.load(null, null);
System.out.println("Loaded keystore: Windows-MY");
Enumeration e = ks.aliases();
PrivateKey privateKey = null;
PublicKey publicKey = null;
while (e.hasMoreElements()) {
String alias = (String) e.nextElement();
if (alias.equals("6753664")) {
System.out.println("Loaded entry: " + alias);
privateKey = (PrivateKey) ks.getKey(alias, null);
publicKey = (PublicKey) ks.getCertificate(alias).getPublicKey();
}
}
if (privateKey == null || publicKey == null) {
throw new Exception("Cannot load the keys need to run this test");
}
System.out.println("-------------------------------------------------");
generatedSignatures.add(signUsing("SHA256withRSA", privateKey));
generatedSignatures.add(signUsing("SHA384withRSA", privateKey));
generatedSignatures.add(signUsing("SHA512withRSA", privateKey));
System.out.println("-------------------------------------------------");
verifyUsing("SHA256withRSA", publicKey, generatedSignatures.get(0));
verifyUsing("SHA384withRSA", publicKey, generatedSignatures.get(1));
verifyUsing("SHA512withRSA", publicKey, generatedSignatures.get(2));
System.out.println("-------------------------------------------------");
}
private static byte[] signUsing(String signAlgorithm,
PrivateKey privateKey) throws Exception {
// Must explicitly specify the SunMSCAPI JCE provider
// (otherwise SunJCE is chosen because it appears earlier in the list)
Signature sig1 = Signature.getInstance(signAlgorithm, "SunMSCAPI");
if (sig1 == null) {
throw new Exception("'" + signAlgorithm + "' is not supported");
}
System.out.println("Using " + signAlgorithm + " signer from the " +
sig1.getProvider().getName() + " JCE provider");
System.out.println("Using key: " + privateKey);
sig1.initSign(privateKey);
sig1.update(toBeSigned);
byte [] sigBytes = null;
try {
sigBytes = sig1.sign();
System.out.println("Generated RSA signature over a " +
toBeSigned.length + "-byte data (signature length: " +
sigBytes.length * 8 + " bits)");
System.out.println(String.format("0x%0" +
(sigBytes.length * 2) + "x",
new java.math.BigInteger(1, sigBytes)));
} catch (SignatureException se) {
System.out.println("Error generating RSA signature: " + se);
}
return sigBytes;
}
private static void verifyUsing(String signAlgorithm, PublicKey publicKey,
byte[] signature) throws Exception {
// Must explicitly specify the SunMSCAPI JCE provider
// (otherwise SunJCE is chosen because it appears earlier in the list)
Signature sig1 = Signature.getInstance(signAlgorithm, "SunMSCAPI");
if (sig1 == null) {
throw new Exception("'" + signAlgorithm + "' is not supported");
}
System.out.println("Using " + signAlgorithm + " verifier from the "
+ sig1.getProvider().getName() + " JCE provider");
System.out.println("Using key: " + publicKey);
System.out.println("\nVerifying RSA Signature over a " +
toBeSigned.length + "-byte data (signature length: " +
signature.length * 8 + " bits)");
System.out.println(String.format("0x%0" + (signature.length * 2) +
"x", new java.math.BigInteger(1, signature)));
sig1.initVerify(publicKey);
sig1.update(toBeSigned);
if (sig1.verify(signature)) {
System.out.println("Verify PASSED\n");
} else {
throw new Exception("Verify FAILED");
}
}
}
#!/bin/sh
#
# Copyright (c) 2011, 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.
#
# 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.
#
# @test
# @bug 6753664
# @run shell SignUsingSHA2withRSA.sh
# @summary Support SHA256 (and higher) in SunMSCAPI
# set a few environment variables so that the shell-script can run stand-alone
# in the source directory
if [ "${TESTSRC}" = "" ] ; then
TESTSRC="."
fi
if [ "${TESTCLASSES}" = "" ] ; then
TESTCLASSES="."
fi
if [ "${TESTJAVA}" = "" ] ; then
echo "TESTJAVA not set. Test cannot execute."
echo "FAILED!!!"
exit 1
fi
OS=`uname -s`
case "$OS" in
Windows* | CYGWIN* )
echo "Creating a temporary RSA keypair in the Windows-My store..."
${TESTJAVA}/bin/keytool \
-genkeypair \
-storetype Windows-My \
-keyalg RSA \
-alias 6753664 \
-dname "cn=6753664,c=US" \
-noprompt
echo
echo "Running the test..."
${TESTJAVA}/bin/javac -d . ${TESTSRC}\\SignUsingSHA2withRSA.java
${TESTJAVA}/bin/java SignUsingSHA2withRSA
rc=$?
echo
echo "Removing the temporary RSA keypair from the Windows-My store..."
${TESTJAVA}/bin/keytool \
-delete \
-storetype Windows-My \
-alias 6753664
echo done.
exit $rc
;;
* )
echo "This test is not intended for '$OS' - passing test"
exit 0
;;
esac
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册