8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,55 @@
/*
* 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 javax.crypto;
/**
* This exception is thrown when a {@link Cipher} operating in
* an AEAD mode (such as GCM/CCM) is unable to verify the supplied
* authentication tag.
*
* @since 1.7
*/
public class AEADBadTagException extends BadPaddingException {
private static final long serialVersionUID = -488059093241685509L;
/**
* Constructs a AEADBadTagException with no detail message.
*/
public AEADBadTagException() {
super();
}
/**
* Constructs a AEADBadTagException with the specified
* detail message.
*
* @param msg the detail message.
*/
public AEADBadTagException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto;
import java.security.GeneralSecurityException;
/**
* This exception is thrown when a particular padding mechanism is
* expected for the input data but the data is not padded properly.
*
* @author Gigi Ankney
* @since 1.4
*/
public class BadPaddingException extends GeneralSecurityException {
private static final long serialVersionUID = -5315033893984728443L;
/**
* Constructs a BadPaddingException with no detail
* message. A detail message is a String that describes this
* particular exception.
*/
public BadPaddingException() {
super();
}
/**
* Constructs a BadPaddingException with the specified
* detail message.
*
* @param msg the detail message.
*/
public BadPaddingException(String msg) {
super(msg);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,338 @@
/*
* Copyright (c) 1997, 2017, 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 javax.crypto;
import java.io.InputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
/**
* A CipherInputStream is composed of an InputStream and a Cipher so
* that read() methods return data that are read in from the
* underlying InputStream but have been additionally processed by the
* Cipher. The Cipher must be fully initialized before being used by
* a CipherInputStream.
*
* <p> For example, if the Cipher is initialized for decryption, the
* CipherInputStream will attempt to read in data and decrypt them,
* before returning the decrypted data.
*
* <p> This class adheres strictly to the semantics, especially the
* failure semantics, of its ancestor classes
* java.io.FilterInputStream and java.io.InputStream. This class has
* exactly those methods specified in its ancestor classes, and
* overrides them all. Moreover, this class catches all exceptions
* that are not thrown by its ancestor classes. In particular, the
* <code>skip</code> method skips, and the <code>available</code>
* method counts only data that have been processed by the encapsulated Cipher.
*
* <p> It is crucial for a programmer using this class not to use
* methods that are not defined or overriden in this class (such as a
* new method or constructor that is later added to one of the super
* classes), because the design and implementation of those methods
* are unlikely to have considered security impact with regard to
* CipherInputStream.
*
* @author Li Gong
* @see java.io.InputStream
* @see java.io.FilterInputStream
* @see javax.crypto.Cipher
* @see javax.crypto.CipherOutputStream
*
* @since 1.4
*/
public class CipherInputStream extends FilterInputStream {
// the cipher engine to use to process stream data
private Cipher cipher;
// the underlying input stream
private InputStream input;
/* the buffer holding data that have been read in from the
underlying stream, but have not been processed by the cipher
engine. the size 512 bytes is somewhat randomly chosen */
private byte[] ibuffer = new byte[512];
// having reached the end of the underlying input stream
private boolean done = false;
/* the buffer holding data that have been processed by the cipher
engine, but have not been read out */
private byte[] obuffer;
// the offset pointing to the next "new" byte
private int ostart = 0;
// the offset pointing to the last "new" byte
private int ofinish = 0;
// stream status
private boolean closed = false;
/*
* private convenience function.
*
* Entry condition: ostart = ofinish
*
* Exit condition: ostart <= ofinish
*
* return (ofinish-ostart) (we have this many bytes for you)
* return 0 (no data now, but could have more later)
* return -1 (absolutely no more data)
*
* Note: Exceptions are only thrown after the stream is completely read.
* For AEAD ciphers a read() of any length will internally cause the
* whole stream to be read fully and verify the authentication tag before
* returning decrypted data or exceptions.
*/
private int getMoreData() throws IOException {
if (done) return -1;
int readin = input.read(ibuffer);
if (readin == -1) {
done = true;
try {
obuffer = cipher.doFinal();
} catch (IllegalBlockSizeException | BadPaddingException e) {
obuffer = null;
throw new IOException(e);
}
if (obuffer == null)
return -1;
else {
ostart = 0;
ofinish = obuffer.length;
return ofinish;
}
}
try {
obuffer = cipher.update(ibuffer, 0, readin);
} catch (IllegalStateException e) {
obuffer = null;
throw e;
}
ostart = 0;
if (obuffer == null)
ofinish = 0;
else ofinish = obuffer.length;
return ofinish;
}
/**
* Constructs a CipherInputStream from an InputStream and a
* Cipher.
* <br>Note: if the specified input stream or cipher is
* null, a NullPointerException may be thrown later when
* they are used.
* @param is the to-be-processed input stream
* @param c an initialized Cipher object
*/
public CipherInputStream(InputStream is, Cipher c) {
super(is);
input = is;
cipher = c;
}
/**
* Constructs a CipherInputStream from an InputStream without
* specifying a Cipher. This has the effect of constructing a
* CipherInputStream using a NullCipher.
* <br>Note: if the specified input stream is null, a
* NullPointerException may be thrown later when it is used.
* @param is the to-be-processed input stream
*/
protected CipherInputStream(InputStream is) {
super(is);
input = is;
cipher = new NullCipher();
}
/**
* Reads the next byte of data from this input stream. The value
* byte is returned as an <code>int</code> in the range
* <code>0</code> to <code>255</code>. If no byte is available
* because the end of the stream has been reached, the value
* <code>-1</code> is returned. This method blocks until input data
* is available, the end of the stream is detected, or an exception
* is thrown.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
*/
public int read() throws IOException {
if (ostart >= ofinish) {
// we loop for new data as the spec says we are blocking
int i = 0;
while (i == 0) i = getMoreData();
if (i == -1) return -1;
}
return ((int) obuffer[ostart++] & 0xff);
};
/**
* Reads up to <code>b.length</code> bytes of data from this input
* stream into an array of bytes.
* <p>
* The <code>read</code> method of <code>InputStream</code> calls
* the <code>read</code> method of three arguments with the arguments
* <code>b</code>, <code>0</code>, and <code>b.length</code>.
*
* @param b the buffer into which the data is read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> is there is no more data because the end of
* the stream has been reached.
* @exception IOException if an I/O error occurs.
* @see java.io.InputStream#read(byte[], int, int)
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads up to <code>len</code> bytes of data from this input stream
* into an array of bytes. This method blocks until some input is
* available. If the first argument is <code>null,</code> up to
* <code>len</code> bytes are read and discarded.
*
* @param b the buffer into which the data is read.
* @param off the start offset in the destination array
* <code>buf</code>
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or
* <code>-1</code> if there is no more data because the end of
* the stream has been reached.
* @exception IOException if an I/O error occurs.
* @see java.io.InputStream#read()
*/
public int read(byte b[], int off, int len) throws IOException {
if (ostart >= ofinish) {
// we loop for new data as the spec says we are blocking
int i = 0;
while (i == 0) i = getMoreData();
if (i == -1) return -1;
}
if (len <= 0) {
return 0;
}
int available = ofinish - ostart;
if (len < available) available = len;
if (b != null) {
System.arraycopy(obuffer, ostart, b, off, available);
}
ostart = ostart + available;
return available;
}
/**
* Skips <code>n</code> bytes of input from the bytes that can be read
* from this input stream without blocking.
*
* <p>Fewer bytes than requested might be skipped.
* The actual number of bytes skipped is equal to <code>n</code> or
* the result of a call to
* {@link #available() available},
* whichever is smaller.
* If <code>n</code> is less than zero, no bytes are skipped.
*
* <p>The actual number of bytes skipped is returned.
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped.
* @exception IOException if an I/O error occurs.
*/
public long skip(long n) throws IOException {
int available = ofinish - ostart;
if (n > available) {
n = available;
}
if (n < 0) {
return 0;
}
ostart += n;
return n;
}
/**
* Returns the number of bytes that can be read from this input
* stream without blocking. The <code>available</code> method of
* <code>InputStream</code> returns <code>0</code>. This method
* <B>should</B> be overridden by subclasses.
*
* @return the number of bytes that can be read from this input stream
* without blocking.
* @exception IOException if an I/O error occurs.
*/
public int available() throws IOException {
return (ofinish - ostart);
}
/**
* Closes this input stream and releases any system resources
* associated with the stream.
* <p>
* The <code>close</code> method of <code>CipherInputStream</code>
* calls the <code>close</code> method of its underlying input
* stream.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
if (closed) {
return;
}
closed = true;
input.close();
// Throw away the unprocessed data and throw no crypto exceptions.
// AEAD ciphers are fully readed before closing. Any authentication
// exceptions would occur while reading.
if (!done) {
try {
cipher.doFinal();
}
catch (BadPaddingException | IllegalBlockSizeException ex) {
// Catch exceptions as the rest of the stream is unused.
}
}
ostart = 0;
ofinish = 0;
}
/**
* Tests if this input stream supports the <code>mark</code>
* and <code>reset</code> methods, which it does not.
*
* @return <code>false</code>, since this class does not support the
* <code>mark</code> and <code>reset</code> methods.
* @see java.io.InputStream#mark(int)
* @see java.io.InputStream#reset()
*/
public boolean markSupported() {
return false;
}
}

View file

@ -0,0 +1,214 @@
/*
* Copyright (c) 1997, 2013, 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 javax.crypto;
import java.io.*;
/**
* A CipherOutputStream is composed of an OutputStream and a Cipher so
* that write() methods first process the data before writing them out
* to the underlying OutputStream. The cipher must be fully
* initialized before being used by a CipherOutputStream.
*
* <p> For example, if the cipher is initialized for encryption, the
* CipherOutputStream will attempt to encrypt data before writing out the
* encrypted data.
*
* <p> This class adheres strictly to the semantics, especially the
* failure semantics, of its ancestor classes
* java.io.OutputStream and java.io.FilterOutputStream. This class
* has exactly those methods specified in its ancestor classes, and
* overrides them all. Moreover, this class catches all exceptions
* that are not thrown by its ancestor classes.
*
* <p> It is crucial for a programmer using this class not to use
* methods that are not defined or overriden in this class (such as a
* new method or constructor that is later added to one of the super
* classes), because the design and implementation of those methods
* are unlikely to have considered security impact with regard to
* CipherOutputStream.
*
* @author Li Gong
* @see java.io.OutputStream
* @see java.io.FilterOutputStream
* @see javax.crypto.Cipher
* @see javax.crypto.CipherInputStream
*
* @since 1.4
*/
public class CipherOutputStream extends FilterOutputStream {
// the cipher engine to use to process stream data
private Cipher cipher;
// the underlying output stream
private OutputStream output;
/* the buffer holding one byte of incoming data */
private byte[] ibuffer = new byte[1];
// the buffer holding data ready to be written out
private byte[] obuffer;
// stream status
private boolean closed = false;
/**
*
* Constructs a CipherOutputStream from an OutputStream and a
* Cipher.
* <br>Note: if the specified output stream or cipher is
* null, a NullPointerException may be thrown later when
* they are used.
*
* @param os the OutputStream object
* @param c an initialized Cipher object
*/
public CipherOutputStream(OutputStream os, Cipher c) {
super(os);
output = os;
cipher = c;
};
/**
* Constructs a CipherOutputStream from an OutputStream without
* specifying a Cipher. This has the effect of constructing a
* CipherOutputStream using a NullCipher.
* <br>Note: if the specified output stream is null, a
* NullPointerException may be thrown later when it is used.
*
* @param os the OutputStream object
*/
protected CipherOutputStream(OutputStream os) {
super(os);
output = os;
cipher = new NullCipher();
}
/**
* Writes the specified byte to this output stream.
*
* @param b the <code>byte</code>.
* @exception IOException if an I/O error occurs.
*/
public void write(int b) throws IOException {
ibuffer[0] = (byte) b;
obuffer = cipher.update(ibuffer, 0, 1);
if (obuffer != null) {
output.write(obuffer);
obuffer = null;
}
};
/**
* Writes <code>b.length</code> bytes from the specified byte array
* to this output stream.
* <p>
* The <code>write</code> method of
* <code>CipherOutputStream</code> calls the <code>write</code>
* method of three arguments with the three arguments
* <code>b</code>, <code>0</code>, and <code>b.length</code>.
*
* @param b the data.
* @exception NullPointerException if <code>b</code> is null.
* @exception IOException if an I/O error occurs.
* @see javax.crypto.CipherOutputStream#write(byte[], int, int)
*/
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
/**
* Writes <code>len</code> bytes from the specified byte array
* starting at offset <code>off</code> to this output stream.
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
obuffer = cipher.update(b, off, len);
if (obuffer != null) {
output.write(obuffer);
obuffer = null;
}
}
/**
* Flushes this output stream by forcing any buffered output bytes
* that have already been processed by the encapsulated cipher object
* to be written out.
*
* <p>Any bytes buffered by the encapsulated cipher
* and waiting to be processed by it will not be written out. For example,
* if the encapsulated cipher is a block cipher, and the total number of
* bytes written using one of the <code>write</code> methods is less than
* the cipher's block size, no bytes will be written out.
*
* @exception IOException if an I/O error occurs.
*/
public void flush() throws IOException {
if (obuffer != null) {
output.write(obuffer);
obuffer = null;
}
output.flush();
}
/**
* Closes this output stream and releases any system resources
* associated with this stream.
* <p>
* This method invokes the <code>doFinal</code> method of the encapsulated
* cipher object, which causes any bytes buffered by the encapsulated
* cipher to be processed. The result is written out by calling the
* <code>flush</code> method of this output stream.
* <p>
* This method resets the encapsulated cipher object to its initial state
* and calls the <code>close</code> method of the underlying output
* stream.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
if (closed) {
return;
}
closed = true;
try {
obuffer = cipher.doFinal();
} catch (IllegalBlockSizeException | BadPaddingException e) {
obuffer = null;
}
try {
flush();
} catch (IOException ignored) {}
out.close();
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,177 @@
/*
* Copyright (c) 1999, 2012, 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 javax.crypto;
import java.security.*;
import java.util.Enumeration;
import java.util.Vector;
/**
* The CryptoAllPermission is a permission that implies
* any other crypto permissions.
* <p>
*
* @see java.security.Permission
* @see java.security.AllPermission
*
* @author Sharon Liu
* @since 1.4
*/
final class CryptoAllPermission extends CryptoPermission {
private static final long serialVersionUID = -5066513634293192112L;
// This class is similar to java.security.AllPermission.
static final String ALG_NAME = "CryptoAllPermission";
static final CryptoAllPermission INSTANCE =
new CryptoAllPermission();
private CryptoAllPermission() {
super(ALG_NAME);
}
/**
* Checks if the specified permission is implied by
* this object.
*
* @param p the permission to check against.
*
* @return true if the specified permission is an
* instance of CryptoPermission.
*/
public boolean implies(Permission p) {
return (p instanceof CryptoPermission);
}
/**
* Checks two CryptoAllPermission objects for equality.
* Two CryptoAllPermission objects are always equal.
*
* @param obj the object to test for equality with this object.
*
* @return true if <i>obj</i> is a CryptoAllPermission object.
*/
public boolean equals(Object obj) {
return (obj == INSTANCE);
}
/**
*
* Returns the hash code value for this object.
*
* @return a hash code value for this object.
*/
public int hashCode() {
return 1;
}
/**
* Returns a new PermissionCollection object for storing
* CryptoAllPermission objects.
* <p>
*
* @return a new PermissionCollection object suitable for
* storing CryptoAllPermissions.
*/
public PermissionCollection newPermissionCollection() {
return new CryptoAllPermissionCollection();
}
}
/**
* A CryptoAllPermissionCollection stores a collection
* of CryptoAllPermission permissions.
*
* @see java.security.Permission
* @see java.security.Permissions
* @see javax.crypto.CryptoPermission
*
* @author Sharon Liu
*/
final class CryptoAllPermissionCollection extends PermissionCollection
implements java.io.Serializable
{
private static final long serialVersionUID = 7450076868380144072L;
// true if a CryptoAllPermission has been added
private boolean all_allowed;
/**
* Create an empty CryptoAllPermissions object.
*/
CryptoAllPermissionCollection() {
all_allowed = false;
}
/**
* Adds a permission to the CryptoAllPermissions.
*
* @param permission the Permission object to add.
*
* @exception SecurityException - if this CryptoAllPermissionCollection
* object has been marked readonly
*/
public void add(Permission permission) {
if (isReadOnly())
throw new SecurityException("attempt to add a Permission to " +
"a readonly PermissionCollection");
if (permission != CryptoAllPermission.INSTANCE)
return;
all_allowed = true;
}
/**
* Check and see if this set of permissions implies the permissions
* expressed in "permission".
*
* @param permission the Permission object to compare
*
* @return true if the given permission is implied by this
* CryptoAllPermissionCollection.
*/
public boolean implies(Permission permission) {
if (!(permission instanceof CryptoPermission)) {
return false;
}
return all_allowed;
}
/**
* Returns an enumeration of all the CryptoAllPermission
* objects in the container.
*
* @return an enumeration of all the CryptoAllPermission objects.
*/
public Enumeration<Permission> elements() {
Vector<Permission> v = new Vector<>(1);
if (all_allowed) v.add(CryptoAllPermission.INSTANCE);
return v.elements();
}
}

View file

@ -0,0 +1,543 @@
/*
* Copyright (c) 1999, 2017, 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 javax.crypto;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Vector;
import javax.crypto.spec.*;
/**
* The CryptoPermission class extends the
* java.security.Permission class. A
* CryptoPermission object is used to represent
* the ability of an application/applet to use certain
* algorithms with certain key sizes and other
* restrictions in certain environments. <p>
*
* @see java.security.Permission
*
* @author Jan Luehe
* @author Sharon Liu
* @since 1.4
*/
class CryptoPermission extends java.security.Permission {
private static final long serialVersionUID = 8987399626114087514L;
private String alg;
private int maxKeySize = Integer.MAX_VALUE; // no restriction on maxKeySize
private String exemptionMechanism = null;
private AlgorithmParameterSpec algParamSpec = null;
private boolean checkParam = false; // no restriction on param
static final String ALG_NAME_WILDCARD = "*";
/**
* Constructor that takes an algorithm name.
*
* This constructor implies that the given algorithm can be
* used without any restrictions.
*
* @param alg the algorithm name.
*/
CryptoPermission(String alg) {
super(null);
this.alg = alg;
}
/**
* Constructor that takes an algorithm name and a maximum
* key size.
*
* This constructor implies that the given algorithm can be
* used with a key size up to <code>maxKeySize</code>.
*
* @param alg the algorithm name.
*
* @param maxKeySize the maximum allowable key size,
* specified in number of bits.
*/
CryptoPermission(String alg, int maxKeySize) {
super(null);
this.alg = alg;
this.maxKeySize = maxKeySize;
}
/**
* Constructor that takes an algorithm name, a maximum
* key size, and an AlgorithmParameterSpec object.
*
* This constructor implies that the given algorithm can be
* used with a key size up to <code>maxKeySize</code>, and
* algorithm
* parameters up to the limits set in <code>algParamSpec</code>.
*
* @param alg the algorithm name.
*
* @param maxKeySize the maximum allowable key size,
* specified in number of bits.
*
* @param algParamSpec the limits for allowable algorithm
* parameters.
*/
CryptoPermission(String alg,
int maxKeySize,
AlgorithmParameterSpec algParamSpec) {
super(null);
this.alg = alg;
this.maxKeySize = maxKeySize;
this.checkParam = true;
this.algParamSpec = algParamSpec;
}
/**
* Constructor that takes an algorithm name and the name of
* an exemption mechanism.
*
* This constructor implies that the given algorithm can be
* used without any key size or algorithm parameter restrictions
* provided that the specified exemption mechanism is enforced.
*
* @param alg the algorithm name.
*
* @param exemptionMechanism the name of the exemption mechanism.
*/
CryptoPermission(String alg,
String exemptionMechanism) {
super(null);
this.alg = alg;
this.exemptionMechanism = exemptionMechanism;
}
/**
* Constructor that takes an algorithm name, a maximum key
* size, and the name of an exemption mechanism.
*
* This constructor implies that the given algorithm can be
* used with a key size up to <code>maxKeySize</code>
* provided that the
* specified exemption mechanism is enforced.
*
* @param alg the algorithm name.
* @param maxKeySize the maximum allowable key size,
* specified in number of bits.
* @param exemptionMechanism the name of the exemption
* mechanism.
*/
CryptoPermission(String alg,
int maxKeySize,
String exemptionMechanism) {
super(null);
this.alg = alg;
this.exemptionMechanism = exemptionMechanism;
this.maxKeySize = maxKeySize;
}
/**
* Constructor that takes an algorithm name, a maximum key
* size, the name of an exemption mechanism, and an
* AlgorithmParameterSpec object.
*
* This constructor implies that the given algorithm can be
* used with a key size up to <code>maxKeySize</code>
* and algorithm
* parameters up to the limits set in <code>algParamSpec</code>
* provided that
* the specified exemption mechanism is enforced.
*
* @param alg the algorithm name.
* @param maxKeySize the maximum allowable key size,
* specified in number of bits.
* @param algParamSpec the limit for allowable algorithm
* parameter spec.
* @param exemptionMechanism the name of the exemption
* mechanism.
*/
CryptoPermission(String alg,
int maxKeySize,
AlgorithmParameterSpec algParamSpec,
String exemptionMechanism) {
super(null);
this.alg = alg;
this.exemptionMechanism = exemptionMechanism;
this.maxKeySize = maxKeySize;
this.checkParam = true;
this.algParamSpec = algParamSpec;
}
/**
* Checks if the specified permission is "implied" by
* this object.
* <p>
* More specifically, this method returns true if:
* <ul>
* <li> <i>p</i> is an instance of CryptoPermission, and</li>
* <li> <i>p</i>'s algorithm name equals or (in the case of wildcards)
* is implied by this permission's algorithm name, and</li>
* <li> <i>p</i>'s maximum allowable key size is less or
* equal to this permission's maximum allowable key size, and</li>
* <li> <i>p</i>'s algorithm parameter spec equals or is
* implied by this permission's algorithm parameter spec, and</li>
* <li> <i>p</i>'s exemptionMechanism equals or
* is implied by this permission's
* exemptionMechanism (a <code>null</code> exemption mechanism
* implies any other exemption mechanism).</li>
* </ul>
*
* @param p the permission to check against.
*
* @return true if the specified permission is equal to or
* implied by this permission, false otherwise.
*/
public boolean implies(Permission p) {
if (!(p instanceof CryptoPermission))
return false;
CryptoPermission cp = (CryptoPermission)p;
if ((!alg.equalsIgnoreCase(cp.alg)) &&
(!alg.equalsIgnoreCase(ALG_NAME_WILDCARD))) {
return false;
}
// alg is the same as cp's alg or
// alg is a wildcard.
if (cp.maxKeySize <= this.maxKeySize) {
// check algParamSpec.
if (!impliesParameterSpec(cp.checkParam, cp.algParamSpec)) {
return false;
}
// check exemptionMechanism.
if (impliesExemptionMechanism(cp.exemptionMechanism)) {
return true;
}
}
return false;
}
/**
* Checks two CryptoPermission objects for equality. Checks that
* <code>obj</code> is a CryptoPermission, and has the same
* algorithm name,
* exemption mechanism name, maximum allowable key size and
* algorithm parameter spec
* as this object.
* <P>
* @param obj the object to test for equality with this object.
* @return true if <code>obj</code> is equal to this object.
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CryptoPermission))
return false;
CryptoPermission that = (CryptoPermission) obj;
if (!(alg.equalsIgnoreCase(that.alg)) ||
(maxKeySize != that.maxKeySize)) {
return false;
}
if (this.checkParam != that.checkParam) {
return false;
}
return (equalObjects(this.exemptionMechanism,
that.exemptionMechanism) &&
equalObjects(this.algParamSpec,
that.algParamSpec));
}
/**
* Returns the hash code value for this object.
*
* @return a hash code value for this object.
*/
public int hashCode() {
int retval = alg.hashCode();
retval ^= maxKeySize;
if (exemptionMechanism != null) {
retval ^= exemptionMechanism.hashCode();
}
if (checkParam) retval ^= 100;
if (algParamSpec != null) {
retval ^= algParamSpec.hashCode();
}
return retval;
}
/**
* There is no action defined for a CryptoPermission
* onject.
*/
public String getActions()
{
return null;
}
/**
* Returns a new PermissionCollection object for storing
* CryptoPermission objects.
*
* @return a new PermissionCollection object suitable for storing
* CryptoPermissions.
*/
public PermissionCollection newPermissionCollection() {
return new CryptoPermissionCollection();
}
/**
* Returns the algorithm name associated with
* this CryptoPermission object.
*/
final String getAlgorithm() {
return alg;
}
/**
* Returns the exemption mechanism name
* associated with this CryptoPermission
* object.
*/
final String getExemptionMechanism() {
return exemptionMechanism;
}
/**
* Returns the maximum allowable key size associated
* with this CryptoPermission object.
*/
final int getMaxKeySize() {
return maxKeySize;
}
/**
* Returns true if there is a limitation on the
* AlgorithmParameterSpec associated with this
* CryptoPermission object and false if otherwise.
*/
final boolean getCheckParam() {
return checkParam;
}
/**
* Returns the AlgorithmParameterSpec
* associated with this CryptoPermission
* object.
*/
final AlgorithmParameterSpec getAlgorithmParameterSpec() {
return algParamSpec;
}
/**
* Returns a string describing this CryptoPermission. The convention is to
* specify the class name, the algorithm name, the maximum allowable
* key size, and the name of the exemption mechanism, in the following
* format: '("ClassName" "algorithm" "keysize" "exemption_mechanism")'.
*
* @return information about this CryptoPermission.
*/
public String toString() {
StringBuilder buf = new StringBuilder(100);
buf.append("(CryptoPermission " + alg + " " + maxKeySize);
if (algParamSpec != null) {
if (algParamSpec instanceof RC2ParameterSpec) {
buf.append(" , effective " +
((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits());
} else if (algParamSpec instanceof RC5ParameterSpec) {
buf.append(" , rounds " +
((RC5ParameterSpec)algParamSpec).getRounds());
}
}
if (exemptionMechanism != null) { // OPTIONAL
buf.append(" " + exemptionMechanism);
}
buf.append(")");
return buf.toString();
}
private boolean impliesExemptionMechanism(String exemptionMechanism) {
if (this.exemptionMechanism == null) {
return true;
}
if (exemptionMechanism == null) {
return false;
}
if (this.exemptionMechanism.equals(exemptionMechanism)) {
return true;
}
return false;
}
private boolean impliesParameterSpec(boolean checkParam,
AlgorithmParameterSpec algParamSpec) {
if ((this.checkParam) && checkParam) {
if (algParamSpec == null) {
return true;
} else if (this.algParamSpec == null) {
return false;
}
if (this.algParamSpec.getClass() != algParamSpec.getClass()) {
return false;
}
if (algParamSpec instanceof RC2ParameterSpec) {
if (((RC2ParameterSpec)algParamSpec).getEffectiveKeyBits() <=
((RC2ParameterSpec)
(this.algParamSpec)).getEffectiveKeyBits()) {
return true;
}
}
if (algParamSpec instanceof RC5ParameterSpec) {
if (((RC5ParameterSpec)algParamSpec).getRounds() <=
((RC5ParameterSpec)this.algParamSpec).getRounds()) {
return true;
}
}
if (algParamSpec instanceof PBEParameterSpec) {
if (((PBEParameterSpec)algParamSpec).getIterationCount() <=
((PBEParameterSpec)this.algParamSpec).getIterationCount()) {
return true;
}
}
// For classes we don't know, the following
// may be the best try.
if (this.algParamSpec.equals(algParamSpec)) {
return true;
}
return false;
} else if (this.checkParam) {
return false;
} else {
return true;
}
}
private boolean equalObjects(Object obj1, Object obj2) {
if (obj1 == null) {
return (obj2 == null ? true : false);
}
return obj1.equals(obj2);
}
}
/**
* A CryptoPermissionCollection stores a set of CryptoPermission
* permissions.
*
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
*
* @author Sharon Liu
*/
final class CryptoPermissionCollection extends PermissionCollection
implements Serializable
{
private static final long serialVersionUID = -511215555898802763L;
private Vector<Permission> permissions;
/**
* Creates an empty CryptoPermissionCollection
* object.
*/
CryptoPermissionCollection() {
permissions = new Vector<Permission>(3);
}
/**
* Adds a permission to the CryptoPermissionCollection.
*
* @param permission the Permission object to add.
*
* @exception SecurityException - if this CryptoPermissionCollection
* object has been marked <i>readOnly</i>.
*/
public void add(Permission permission) {
if (isReadOnly())
throw new SecurityException("attempt to add a Permission " +
"to a readonly PermissionCollection");
if (!(permission instanceof CryptoPermission))
return;
permissions.addElement(permission);
}
/**
* Check and see if this CryptoPermission object implies
* the given Permission object.
*
* @param permission the Permission object to compare
*
* @return true if the given permission is implied by this
* CryptoPermissionCollection, false if not.
*/
public boolean implies(Permission permission) {
if (!(permission instanceof CryptoPermission))
return false;
CryptoPermission cp = (CryptoPermission)permission;
Enumeration<Permission> e = permissions.elements();
while (e.hasMoreElements()) {
CryptoPermission x = (CryptoPermission) e.nextElement();
if (x.implies(cp)) {
return true;
}
}
return false;
}
/**
* Returns an enumeration of all the CryptoPermission objects
* in the container.
*
* @return an enumeration of all the CryptoPermission objects.
*/
public Enumeration<Permission> elements() {
return permissions.elements();
}
}

View file

@ -0,0 +1,518 @@
/*
* Copyright (c) 1999, 2016, 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 javax.crypto;
import java.security.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import java.io.Serializable;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.ObjectStreamField;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
/**
* This class contains CryptoPermission objects, organized into
* PermissionCollections according to algorithm names.
*
* <p>When the <code>add</code> method is called to add a
* CryptoPermission, the CryptoPermission is stored in the
* appropriate PermissionCollection. If no such
* collection exists yet, the algorithm name associated with
* the CryptoPermission object is
* determined and the <code>newPermissionCollection</code> method
* is called on the CryptoPermission or CryptoAllPermission class to
* create the PermissionCollection and add it to the Permissions object.
*
* @see javax.crypto.CryptoPermission
* @see java.security.PermissionCollection
* @see java.security.Permissions
*
* @author Sharon Liu
* @since 1.4
*/
final class CryptoPermissions extends PermissionCollection
implements Serializable {
private static final long serialVersionUID = 4946547168093391015L;
/**
* @serialField perms java.util.Hashtable
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("perms", Hashtable.class),
};
// Switched from Hashtable to ConcurrentHashMap to improve scalability.
// To maintain serialization compatibility, this field is made transient
// and custom readObject/writeObject methods are used.
private transient ConcurrentHashMap<String,PermissionCollection> perms;
/**
* Creates a new CryptoPermissions object containing
* no CryptoPermissionCollections.
*/
CryptoPermissions() {
perms = new ConcurrentHashMap<>(7);
}
/**
* Populates the crypto policy from the specified
* InputStream into this CryptoPermissions object.
*
* @param in the InputStream to load from.
*
* @exception SecurityException if cannot load
* successfully.
*/
void load(InputStream in)
throws IOException, CryptoPolicyParser.ParsingException {
CryptoPolicyParser parser = new CryptoPolicyParser();
parser.read(new BufferedReader(new InputStreamReader(in, "UTF-8")));
CryptoPermission[] parsingResult = parser.getPermissions();
for (int i = 0; i < parsingResult.length; i++) {
this.add(parsingResult[i]);
}
}
/**
* Returns true if this CryptoPermissions object doesn't
* contain any CryptoPermission objects; otherwise, returns
* false.
*/
boolean isEmpty() {
return perms.isEmpty();
}
/**
* Adds a permission object to the PermissionCollection for the
* algorithm returned by
* <code>(CryptoPermission)permission.getAlgorithm()</code>.
*
* This method creates
* a new PermissionCollection object (and adds the permission to it)
* if an appropriate collection does not yet exist. <p>
*
* @param permission the Permission object to add.
*
* @exception SecurityException if this CryptoPermissions object is
* marked as readonly.
*
* @see isReadOnly
*/
@Override
public void add(Permission permission) {
if (isReadOnly()) {
throw new SecurityException("Attempt to add a Permission " +
"to a readonly CryptoPermissions " +
"object");
}
if (!(permission instanceof CryptoPermission)) {
return;
}
CryptoPermission cryptoPerm = (CryptoPermission)permission;
PermissionCollection pc =
getPermissionCollection(cryptoPerm);
pc.add(cryptoPerm);
String alg = cryptoPerm.getAlgorithm();
perms.putIfAbsent(alg, pc);
}
/**
* Checks if this object's PermissionCollection for permissons
* of the specified permission's algorithm implies the specified
* permission. Returns true if the checking succeeded.
*
* @param permission the Permission object to check.
*
* @return true if "permission" is implied by the permissions
* in the PermissionCollection it belongs to, false if not.
*
*/
@Override
public boolean implies(Permission permission) {
if (!(permission instanceof CryptoPermission)) {
return false;
}
CryptoPermission cryptoPerm = (CryptoPermission)permission;
PermissionCollection pc =
getPermissionCollection(cryptoPerm.getAlgorithm());
if (pc != null) {
return pc.implies(cryptoPerm);
} else {
// none found
return false;
}
}
/**
* Returns an enumeration of all the Permission objects in all the
* PermissionCollections in this CryptoPermissions object.
*
* @return an enumeration of all the Permissions.
*/
@Override
public Enumeration<Permission> elements() {
// go through each Permissions in the hash table
// and call their elements() function.
return new PermissionsEnumerator(perms.elements());
}
/**
* Returns a CryptoPermissions object which
* represents the minimum of the specified
* CryptoPermissions object and this
* CryptoPermissions object.
*
* @param other the CryptoPermission
* object to compare with this object.
*/
CryptoPermissions getMinimum(CryptoPermissions other) {
if (other == null) {
return null;
}
if (this.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
return other;
}
if (other.perms.containsKey(CryptoAllPermission.ALG_NAME)) {
return this;
}
CryptoPermissions ret = new CryptoPermissions();
PermissionCollection thatWildcard =
other.perms.get(CryptoPermission.ALG_NAME_WILDCARD);
int maxKeySize = 0;
if (thatWildcard != null) {
maxKeySize = ((CryptoPermission)
thatWildcard.elements().nextElement()).getMaxKeySize();
}
// For each algorithm in this CryptoPermissions,
// find out if there is anything we should add into
// ret.
Enumeration<String> thisKeys = this.perms.keys();
while (thisKeys.hasMoreElements()) {
String alg = thisKeys.nextElement();
PermissionCollection thisPc = this.perms.get(alg);
PermissionCollection thatPc = other.perms.get(alg);
CryptoPermission[] partialResult;
if (thatPc == null) {
if (thatWildcard == null) {
// The other CryptoPermissions
// doesn't allow this given
// algorithm at all. Just skip this
// algorithm.
continue;
}
partialResult = getMinimum(maxKeySize, thisPc);
} else {
partialResult = getMinimum(thisPc, thatPc);
}
for (int i = 0; i < partialResult.length; i++) {
ret.add(partialResult[i]);
}
}
PermissionCollection thisWildcard =
this.perms.get(CryptoPermission.ALG_NAME_WILDCARD);
// If this CryptoPermissions doesn't
// have a wildcard, we are done.
if (thisWildcard == null) {
return ret;
}
// Deal with the algorithms only appear
// in the other CryptoPermissions.
maxKeySize =
((CryptoPermission)
thisWildcard.elements().nextElement()).getMaxKeySize();
Enumeration<String> thatKeys = other.perms.keys();
while (thatKeys.hasMoreElements()) {
String alg = thatKeys.nextElement();
if (this.perms.containsKey(alg)) {
continue;
}
PermissionCollection thatPc = other.perms.get(alg);
CryptoPermission[] partialResult;
partialResult = getMinimum(maxKeySize, thatPc);
for (int i = 0; i < partialResult.length; i++) {
ret.add(partialResult[i]);
}
}
return ret;
}
/**
* Get the minimum of the two given PermissionCollection
* <code>thisPc</code> and <code>thatPc</code>.
*
* @param thisPc the first given PermissionColloection
* object.
*
* @param thatPc the second given PermissionCollection
* object.
*/
private CryptoPermission[] getMinimum(PermissionCollection thisPc,
PermissionCollection thatPc) {
Vector<CryptoPermission> permVector = new Vector<>(2);
Enumeration<Permission> thisPcPermissions = thisPc.elements();
// For each CryptoPermission in
// thisPc object, do the following:
// 1) if this CryptoPermission is implied
// by thatPc, this CryptoPermission
// should be returned, and we can
// move on to check the next
// CryptoPermission in thisPc.
// 2) otherwise, we should return
// all CryptoPermissions in thatPc
// which
// are implied by this CryptoPermission.
// Then we can move on to the
// next CryptoPermission in thisPc.
while (thisPcPermissions.hasMoreElements()) {
CryptoPermission thisCp =
(CryptoPermission)thisPcPermissions.nextElement();
Enumeration<Permission> thatPcPermissions = thatPc.elements();
while (thatPcPermissions.hasMoreElements()) {
CryptoPermission thatCp =
(CryptoPermission)thatPcPermissions.nextElement();
if (thatCp.implies(thisCp)) {
permVector.addElement(thisCp);
break;
}
if (thisCp.implies(thatCp)) {
permVector.addElement(thatCp);
}
}
}
CryptoPermission[] ret = new CryptoPermission[permVector.size()];
permVector.copyInto(ret);
return ret;
}
/**
* Returns all the CryptoPermission objects in the given
* PermissionCollection object
* whose maximum keysize no greater than <code>maxKeySize</code>.
* For all CryptoPermission objects with a maximum keysize greater
* than <code>maxKeySize</code>, this method constructs a
* corresponding CryptoPermission object whose maximum keysize is
* set to <code>maxKeySize</code>, and includes that in the result.
*
* @param maxKeySize the given maximum key size.
*
* @param pc the given PermissionCollection object.
*/
private CryptoPermission[] getMinimum(int maxKeySize,
PermissionCollection pc) {
Vector<CryptoPermission> permVector = new Vector<>(1);
Enumeration<Permission> enum_ = pc.elements();
while (enum_.hasMoreElements()) {
CryptoPermission cp =
(CryptoPermission)enum_.nextElement();
if (cp.getMaxKeySize() <= maxKeySize) {
permVector.addElement(cp);
} else {
if (cp.getCheckParam()) {
permVector.addElement(
new CryptoPermission(cp.getAlgorithm(),
maxKeySize,
cp.getAlgorithmParameterSpec(),
cp.getExemptionMechanism()));
} else {
permVector.addElement(
new CryptoPermission(cp.getAlgorithm(),
maxKeySize,
cp.getExemptionMechanism()));
}
}
}
CryptoPermission[] ret = new CryptoPermission[permVector.size()];
permVector.copyInto(ret);
return ret;
}
/**
* Returns the PermissionCollection for the
* specified algorithm. Returns null if there
* isn't such a PermissionCollection.
*
* @param alg the algorithm name.
*/
PermissionCollection getPermissionCollection(String alg) {
// If this CryptoPermissions includes CryptoAllPermission,
// we should return CryptoAllPermission.
PermissionCollection pc = perms.get(CryptoAllPermission.ALG_NAME);
if (pc == null) {
pc = perms.get(alg);
// If there isn't a PermissionCollection for
// the given algorithm,we should return the
// PermissionCollection for the wildcard
// if there is one.
if (pc == null) {
pc = perms.get(CryptoPermission.ALG_NAME_WILDCARD);
}
}
return pc;
}
/**
* Returns the PermissionCollection for the algorithm
* associated with the specified CryptoPermission
* object. Creates such a PermissionCollection
* if such a PermissionCollection does not
* exist yet.
*
* @param cryptoPerm the CryptoPermission object.
*/
private PermissionCollection getPermissionCollection(
CryptoPermission cryptoPerm) {
String alg = cryptoPerm.getAlgorithm();
PermissionCollection pc = perms.get(alg);
if (pc == null) {
pc = cryptoPerm.newPermissionCollection();
}
return pc;
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = s.readFields();
@SuppressWarnings("unchecked")
Hashtable<String,PermissionCollection> permTable =
(Hashtable<String,PermissionCollection>)
(fields.get("perms", null));
if (permTable != null) {
perms = new ConcurrentHashMap<>(permTable);
} else {
perms = new ConcurrentHashMap<>();
}
}
private void writeObject(ObjectOutputStream s) throws IOException {
Hashtable<String,PermissionCollection> permTable =
new Hashtable<>(perms);
ObjectOutputStream.PutField fields = s.putFields();
fields.put("perms", permTable);
s.writeFields();
}
}
final class PermissionsEnumerator implements Enumeration<Permission> {
// all the perms
private final Enumeration<PermissionCollection> perms;
// the current set
private Enumeration<Permission> permset;
PermissionsEnumerator(Enumeration<PermissionCollection> e) {
perms = e;
permset = getNextEnumWithMore();
}
@Override
public synchronized boolean hasMoreElements() {
// if we enter with permissionimpl null, we know
// there are no more left.
if (permset == null) {
return false;
}
// try to see if there are any left in the current one
if (permset.hasMoreElements()) {
return true;
}
// get the next one that has something in it...
permset = getNextEnumWithMore();
// if it is null, we are done!
return (permset != null);
}
@Override
public synchronized Permission nextElement() {
// hasMoreElements will update permset to the next permset
// with something in it...
if (hasMoreElements()) {
return permset.nextElement();
} else {
throw new NoSuchElementException("PermissionsEnumerator");
}
}
private Enumeration<Permission> getNextEnumWithMore() {
while (perms.hasMoreElements()) {
PermissionCollection pc = perms.nextElement();
Enumeration<Permission> next = pc.elements();
if (next.hasMoreElements()) {
return next;
}
}
return null;
}
}

View file

@ -0,0 +1,706 @@
/*
* Copyright (c) 1999, 2017, 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 javax.crypto;
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import static java.util.Locale.ENGLISH;
import java.security.GeneralSecurityException;
import java.security.spec.AlgorithmParameterSpec;
import java.lang.reflect.*;
/**
* JCE has two pairs of jurisdiction policy files: one represents U.S. export
* laws, and the other represents the local laws of the country where the
* JCE will be used.
*
* The jurisdiction policy file has the same syntax as JDK policy files except
* that JCE has new permission classes called javax.crypto.CryptoPermission
* and javax.crypto.CryptoAllPermission.
*
* The format of a permission entry in the jurisdiction policy file is:
*
* <pre>{@code
* permission <crypto permission class name>[, <algorithm name>
* [[, <exemption mechanism name>][, <maxKeySize>
* [, <AlgrithomParameterSpec class name>, <parameters
* for constructing an AlgrithomParameterSpec object>]]]];
* }</pre>
*
* @author Sharon Liu
*
* @see java.security.Permissions
* @see java.security.spec.AlgorithmParameterSpec
* @see javax.crypto.CryptoPermission
* @see javax.crypto.CryptoAllPermission
* @see javax.crypto.CryptoPermissions
* @since 1.4
*/
final class CryptoPolicyParser {
private Vector<GrantEntry> grantEntries;
// Convenience variables for parsing
private StreamTokenizer st;
private int lookahead;
/**
* Creates a CryptoPolicyParser object.
*/
CryptoPolicyParser() {
grantEntries = new Vector<GrantEntry>();
}
/**
* Reads a policy configuration using a Reader object. <p>
*
* @param policy the policy Reader object.
*
* @exception ParsingException if the policy configuration
* contains a syntax error.
*
* @exception IOException if an error occurs while reading
* the policy configuration.
*/
void read(Reader policy)
throws ParsingException, IOException
{
if (!(policy instanceof BufferedReader)) {
policy = new BufferedReader(policy);
}
/*
* Configure the stream tokenizer:
* Recognize strings between "..."
* Don't convert words to lowercase
* Recognize both C-style and C++-style comments
* Treat end-of-line as white space, not as a token
*/
st = new StreamTokenizer(policy);
st.resetSyntax();
st.wordChars('a', 'z');
st.wordChars('A', 'Z');
st.wordChars('.', '.');
st.wordChars('0', '9');
st.wordChars('_', '_');
st.wordChars('$', '$');
st.wordChars(128 + 32, 255);
st.whitespaceChars(0, ' ');
st.commentChar('/');
st.quoteChar('\'');
st.quoteChar('"');
st.lowerCaseMode(false);
st.ordinaryChar('/');
st.slashSlashComments(true);
st.slashStarComments(true);
st.parseNumbers();
/*
* The crypto jurisdiction policy must be consistent. The
* following hashtable is used for checking consistency.
*/
Hashtable<String, Vector<String>> processedPermissions = null;
/*
* The main parsing loop. The loop is executed once for each entry
* in the policy file. The entries are delimited by semicolons. Once
* we've read in the information for an entry, go ahead and try to
* add it to the grantEntries.
*/
lookahead = st.nextToken();
while (lookahead != StreamTokenizer.TT_EOF) {
if (peek("grant")) {
GrantEntry ge = parseGrantEntry(processedPermissions);
if (ge != null)
grantEntries.addElement(ge);
} else {
throw new ParsingException(st.lineno(), "expected grant " +
"statement");
}
match(";");
}
}
/**
* parse a Grant entry
*/
private GrantEntry parseGrantEntry(
Hashtable<String, Vector<String>> processedPermissions)
throws ParsingException, IOException
{
GrantEntry e = new GrantEntry();
match("grant");
match("{");
while(!peek("}")) {
if (peek("Permission")) {
CryptoPermissionEntry pe =
parsePermissionEntry(processedPermissions);
e.add(pe);
match(";");
} else {
throw new
ParsingException(st.lineno(), "expected permission entry");
}
}
match("}");
return e;
}
/**
* parse a CryptoPermission entry
*/
private CryptoPermissionEntry parsePermissionEntry(
Hashtable<String, Vector<String>> processedPermissions)
throws ParsingException, IOException
{
CryptoPermissionEntry e = new CryptoPermissionEntry();
match("Permission");
e.cryptoPermission = match("permission type");
if (e.cryptoPermission.equals("javax.crypto.CryptoAllPermission")) {
// Done with the CryptoAllPermission entry.
e.alg = CryptoAllPermission.ALG_NAME;
e.maxKeySize = Integer.MAX_VALUE;
return e;
}
// Should see the algorithm name.
if (peek("\"")) {
// Algorithm name - always convert to upper case after parsing.
e.alg = match("quoted string").toUpperCase(ENGLISH);
} else {
// The algorithm name can be a wildcard.
if (peek("*")) {
match("*");
e.alg = CryptoPermission.ALG_NAME_WILDCARD;
} else {
throw new ParsingException(st.lineno(),
"Missing the algorithm name");
}
}
peekAndMatch(",");
// May see the exemption mechanism name.
if (peek("\"")) {
// Exemption mechanism name - convert to upper case too.
e.exemptionMechanism = match("quoted string").toUpperCase(ENGLISH);
}
peekAndMatch(",");
// Check whether this entry is consistent with other permission entries
// that have been read.
if (!isConsistent(e.alg, e.exemptionMechanism, processedPermissions)) {
throw new ParsingException(st.lineno(), "Inconsistent policy");
}
// Should see the maxKeySize if not at the end of this entry yet.
if (peek("number")) {
e.maxKeySize = match();
} else {
if (peek("*")) {
match("*");
e.maxKeySize = Integer.MAX_VALUE;
} else {
if (!peek(";")) {
throw new ParsingException(st.lineno(),
"Missing the maximum " +
"allowable key size");
} else {
// At the end of this permission entry
e.maxKeySize = Integer.MAX_VALUE;
}
}
}
peekAndMatch(",");
// May see an AlgorithmParameterSpec class name.
if (peek("\"")) {
// AlgorithmParameterSpec class name.
String algParamSpecClassName = match("quoted string");
Vector<Integer> paramsV = new Vector<>(1);
while (peek(",")) {
match(",");
if (peek("number")) {
paramsV.addElement(match());
} else {
if (peek("*")) {
match("*");
paramsV.addElement(Integer.MAX_VALUE);
} else {
throw new ParsingException(st.lineno(),
"Expecting an integer");
}
}
}
Integer[] params = new Integer[paramsV.size()];
paramsV.copyInto(params);
e.checkParam = true;
e.algParamSpec = getInstance(algParamSpecClassName, params);
}
return e;
}
private static final AlgorithmParameterSpec getInstance(String type,
Integer[] params)
throws ParsingException
{
AlgorithmParameterSpec ret = null;
try {
Class<?> apsClass = Class.forName(type);
Class<?>[] paramClasses = new Class<?>[params.length];
for (int i = 0; i < params.length; i++) {
paramClasses[i] = int.class;
}
Constructor<?> c = apsClass.getConstructor(paramClasses);
ret = (AlgorithmParameterSpec) c.newInstance((Object[]) params);
} catch (Exception e) {
throw new ParsingException("Cannot call the constructor of " +
type + e);
}
return ret;
}
private boolean peekAndMatch(String expect)
throws ParsingException, IOException
{
if (peek(expect)) {
match(expect);
return true;
}
return false;
}
private boolean peek(String expect) {
boolean found = false;
switch (lookahead) {
case StreamTokenizer.TT_WORD:
if (expect.equalsIgnoreCase(st.sval))
found = true;
break;
case StreamTokenizer.TT_NUMBER:
if (expect.equalsIgnoreCase("number")) {
found = true;
}
break;
case ',':
if (expect.equals(","))
found = true;
break;
case '{':
if (expect.equals("{"))
found = true;
break;
case '}':
if (expect.equals("}"))
found = true;
break;
case '"':
if (expect.equals("\""))
found = true;
break;
case '*':
if (expect.equals("*"))
found = true;
break;
case ';':
if (expect.equals(";"))
found = true;
break;
default:
break;
}
return found;
}
/**
* Excepts to match a non-negative number.
*/
private int match()
throws ParsingException, IOException
{
int value = -1;
int lineno = st.lineno();
String sValue = null;
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
value = (int)st.nval;
if (value < 0) {
sValue = String.valueOf(st.nval);
}
lookahead = st.nextToken();
break;
default:
sValue = st.sval;
break;
}
if (value <= 0) {
throw new ParsingException(lineno, "a non-negative number",
sValue);
}
return value;
}
private String match(String expect)
throws ParsingException, IOException
{
String value = null;
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
throw new ParsingException(st.lineno(), expect,
"number "+String.valueOf(st.nval));
case StreamTokenizer.TT_EOF:
throw new ParsingException("expected "+expect+", read end of file");
case StreamTokenizer.TT_WORD:
if (expect.equalsIgnoreCase(st.sval)) {
lookahead = st.nextToken();
}
else if (expect.equalsIgnoreCase("permission type")) {
value = st.sval;
lookahead = st.nextToken();
}
else
throw new ParsingException(st.lineno(), expect, st.sval);
break;
case '"':
if (expect.equalsIgnoreCase("quoted string")) {
value = st.sval;
lookahead = st.nextToken();
} else if (expect.equalsIgnoreCase("permission type")) {
value = st.sval;
lookahead = st.nextToken();
}
else
throw new ParsingException(st.lineno(), expect, st.sval);
break;
case ',':
if (expect.equals(","))
lookahead = st.nextToken();
else
throw new ParsingException(st.lineno(), expect, ",");
break;
case '{':
if (expect.equals("{"))
lookahead = st.nextToken();
else
throw new ParsingException(st.lineno(), expect, "{");
break;
case '}':
if (expect.equals("}"))
lookahead = st.nextToken();
else
throw new ParsingException(st.lineno(), expect, "}");
break;
case ';':
if (expect.equals(";"))
lookahead = st.nextToken();
else
throw new ParsingException(st.lineno(), expect, ";");
break;
case '*':
if (expect.equals("*"))
lookahead = st.nextToken();
else
throw new ParsingException(st.lineno(), expect, "*");
break;
default:
throw new ParsingException(st.lineno(), expect,
new String(new char[] {(char)lookahead}));
}
return value;
}
CryptoPermission[] getPermissions() {
Vector<CryptoPermission> result = new Vector<>();
Enumeration<GrantEntry> grantEnum = grantEntries.elements();
while (grantEnum.hasMoreElements()) {
GrantEntry ge = grantEnum.nextElement();
Enumeration<CryptoPermissionEntry> permEnum =
ge.permissionElements();
while (permEnum.hasMoreElements()) {
CryptoPermissionEntry pe = permEnum.nextElement();
if (pe.cryptoPermission.equals(
"javax.crypto.CryptoAllPermission")) {
result.addElement(CryptoAllPermission.INSTANCE);
} else {
if (pe.checkParam) {
result.addElement(new CryptoPermission(
pe.alg,
pe.maxKeySize,
pe.algParamSpec,
pe.exemptionMechanism));
} else {
result.addElement(new CryptoPermission(
pe.alg,
pe.maxKeySize,
pe.exemptionMechanism));
}
}
}
}
CryptoPermission[] ret = new CryptoPermission[result.size()];
result.copyInto(ret);
return ret;
}
private boolean isConsistent(String alg, String exemptionMechanism,
Hashtable<String, Vector<String>> processedPermissions) {
String thisExemptionMechanism =
exemptionMechanism == null ? "none" : exemptionMechanism;
if (processedPermissions == null) {
processedPermissions = new Hashtable<String, Vector<String>>();
Vector<String> exemptionMechanisms = new Vector<>(1);
exemptionMechanisms.addElement(thisExemptionMechanism);
processedPermissions.put(alg, exemptionMechanisms);
return true;
}
if (processedPermissions.containsKey(CryptoAllPermission.ALG_NAME)) {
return false;
}
Vector<String> exemptionMechanisms;
if (processedPermissions.containsKey(alg)) {
exemptionMechanisms = processedPermissions.get(alg);
if (exemptionMechanisms.contains(thisExemptionMechanism)) {
return false;
}
} else {
exemptionMechanisms = new Vector<String>(1);
}
exemptionMechanisms.addElement(thisExemptionMechanism);
processedPermissions.put(alg, exemptionMechanisms);
return true;
}
/**
* Each grant entry in the policy configuration file is represented by a
* GrantEntry object.
* <p>
* For example, the entry
* <pre>
* grant {
* permission javax.crypto.CryptoPermission "DES", 56;
* };
*
* </pre>
* is represented internally
* <pre>
*
* pe = new CryptoPermissionEntry("javax.crypto.CryptoPermission",
* "DES", 56);
*
* ge = new GrantEntry();
*
* ge.add(pe);
*
* </pre>
*
* @see java.security.Permission
* @see javax.crypto.CryptoPermission
* @see javax.crypto.CryptoPermissions
*/
private static class GrantEntry {
private Vector<CryptoPermissionEntry> permissionEntries;
GrantEntry() {
permissionEntries = new Vector<CryptoPermissionEntry>();
}
void add(CryptoPermissionEntry pe)
{
permissionEntries.addElement(pe);
}
boolean remove(CryptoPermissionEntry pe)
{
return permissionEntries.removeElement(pe);
}
boolean contains(CryptoPermissionEntry pe)
{
return permissionEntries.contains(pe);
}
/**
* Enumerate all the permission entries in this GrantEntry.
*/
Enumeration<CryptoPermissionEntry> permissionElements(){
return permissionEntries.elements();
}
}
/**
* Each crypto permission entry in the policy configuration file is
* represented by a CryptoPermissionEntry object.
* <p>
* For example, the entry
* <pre>
* permission javax.crypto.CryptoPermission "DES", 56;
* </pre>
* is represented internally
* <pre>
*
* pe = new CryptoPermissionEntry("javax.crypto.cryptoPermission",
* "DES", 56);
* </pre>
*
* @see java.security.Permissions
* @see javax.crypto.CryptoPermission
* @see javax.crypto.CryptoAllPermission
*/
private static class CryptoPermissionEntry {
String cryptoPermission;
String alg;
String exemptionMechanism;
int maxKeySize;
boolean checkParam;
AlgorithmParameterSpec algParamSpec;
CryptoPermissionEntry() {
// Set default values.
maxKeySize = 0;
alg = null;
exemptionMechanism = null;
checkParam = false;
algParamSpec = null;
}
/**
* Calculates a hash code value for the object. Objects
* which are equal will also have the same hashcode.
*/
public int hashCode() {
int retval = cryptoPermission.hashCode();
if (alg != null) retval ^= alg.hashCode();
if (exemptionMechanism != null) {
retval ^= exemptionMechanism.hashCode();
}
retval ^= maxKeySize;
if (checkParam) retval ^= 100;
if (algParamSpec != null) {
retval ^= algParamSpec.hashCode();
}
return retval;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CryptoPermissionEntry))
return false;
CryptoPermissionEntry that = (CryptoPermissionEntry) obj;
if (this.cryptoPermission == null) {
if (that.cryptoPermission != null) return false;
} else {
if (!this.cryptoPermission.equals(
that.cryptoPermission))
return false;
}
if (this.alg == null) {
if (that.alg != null) return false;
} else {
if (!this.alg.equalsIgnoreCase(that.alg))
return false;
}
if (!(this.maxKeySize == that.maxKeySize)) return false;
if (this.checkParam != that.checkParam) return false;
if (this.algParamSpec == null) {
if (that.algParamSpec != null) return false;
} else {
if (!this.algParamSpec.equals(that.algParamSpec))
return false;
}
// everything matched -- the 2 objects are equal
return true;
}
}
static final class ParsingException extends GeneralSecurityException {
private static final long serialVersionUID = 7147241245566588374L;
/**
* Constructs a ParsingException with the specified
* detail message.
* @param msg the detail message.
*/
ParsingException(String msg) {
super(msg);
}
ParsingException(int line, String msg) {
super("line " + line + ": " + msg);
}
ParsingException(int line, String expect, String actual) {
super("line "+line+": expected '"+expect+"', found '"+actual+"'");
}
}
}

View file

@ -0,0 +1,426 @@
/*
* Copyright (c) 2001, 2017, 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 javax.crypto;
import java.io.*;
import java.security.*;
import java.security.spec.*;
import sun.security.x509.AlgorithmId;
import sun.security.util.DerValue;
import sun.security.util.DerInputStream;
import sun.security.util.DerOutputStream;
/**
* This class implements the <code>EncryptedPrivateKeyInfo</code> type
* as defined in PKCS #8.
* <p>Its ASN.1 definition is as follows:
*
* <pre>
* EncryptedPrivateKeyInfo ::= SEQUENCE {
* encryptionAlgorithm AlgorithmIdentifier,
* encryptedData OCTET STRING }
*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL }
* </pre>
*
* @author Valerie Peng
*
* @see java.security.spec.PKCS8EncodedKeySpec
*
* @since 1.4
*/
public class EncryptedPrivateKeyInfo {
// the "encryptionAlgorithm" field
private AlgorithmId algid;
// the algorithm name of the encrypted private key
private String keyAlg;
// the "encryptedData" field
private byte[] encryptedData;
// the ASN.1 encoded contents of this class
private byte[] encoded = null;
/**
* Constructs (i.e., parses) an <code>EncryptedPrivateKeyInfo</code> from
* its ASN.1 encoding.
* @param encoded the ASN.1 encoding of this object. The contents of
* the array are copied to protect against subsequent modification.
* @exception NullPointerException if the <code>encoded</code> is null.
* @exception IOException if error occurs when parsing the ASN.1 encoding.
*/
public EncryptedPrivateKeyInfo(byte[] encoded)
throws IOException {
if (encoded == null) {
throw new NullPointerException("the encoded parameter " +
"must be non-null");
}
this.encoded = encoded.clone();
DerValue val = new DerValue(this.encoded);
DerValue[] seq = new DerValue[2];
seq[0] = val.data.getDerValue();
seq[1] = val.data.getDerValue();
if (val.data.available() != 0) {
throw new IOException("overrun, bytes = " + val.data.available());
}
this.algid = AlgorithmId.parse(seq[0]);
if (seq[0].data.available() != 0) {
throw new IOException("encryptionAlgorithm field overrun");
}
this.encryptedData = seq[1].getOctetString();
if (seq[1].data.available() != 0) {
throw new IOException("encryptedData field overrun");
}
}
/**
* Constructs an <code>EncryptedPrivateKeyInfo</code> from the
* encryption algorithm name and the encrypted data.
*
* <p>Note: This constructor will use null as the value of the
* algorithm parameters. If the encryption algorithm has
* parameters whose value is not null, a different constructor,
* e.g. EncryptedPrivateKeyInfo(AlgorithmParameters, byte[]),
* should be used.
*
* @param algName encryption algorithm name. See the
* <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard Cipher algorithm names.
* @param encryptedData encrypted data. The contents of
* <code>encrypedData</code> are copied to protect against subsequent
* modification when constructing this object.
* @exception NullPointerException if <code>algName</code> or
* <code>encryptedData</code> is null.
* @exception IllegalArgumentException if <code>encryptedData</code>
* is empty, i.e. 0-length.
* @exception NoSuchAlgorithmException if the specified algName is
* not supported.
*/
public EncryptedPrivateKeyInfo(String algName, byte[] encryptedData)
throws NoSuchAlgorithmException {
if (algName == null)
throw new NullPointerException("the algName parameter " +
"must be non-null");
this.algid = AlgorithmId.get(algName);
if (encryptedData == null) {
throw new NullPointerException("the encryptedData " +
"parameter must be non-null");
} else if (encryptedData.length == 0) {
throw new IllegalArgumentException("the encryptedData " +
"parameter must not be empty");
} else {
this.encryptedData = encryptedData.clone();
}
// delay the generation of ASN.1 encoding until
// getEncoded() is called
this.encoded = null;
}
/**
* Constructs an <code>EncryptedPrivateKeyInfo</code> from the
* encryption algorithm parameters and the encrypted data.
*
* @param algParams the algorithm parameters for the encryption
* algorithm. <code>algParams.getEncoded()</code> should return
* the ASN.1 encoded bytes of the <code>parameters</code> field
* of the <code>AlgorithmIdentifer</code> component of the
* <code>EncryptedPrivateKeyInfo</code> type.
* @param encryptedData encrypted data. The contents of
* <code>encrypedData</code> are copied to protect against
* subsequent modification when constructing this object.
* @exception NullPointerException if <code>algParams</code> or
* <code>encryptedData</code> is null.
* @exception IllegalArgumentException if <code>encryptedData</code>
* is empty, i.e. 0-length.
* @exception NoSuchAlgorithmException if the specified algName of
* the specified <code>algParams</code> parameter is not supported.
*/
public EncryptedPrivateKeyInfo(AlgorithmParameters algParams,
byte[] encryptedData) throws NoSuchAlgorithmException {
if (algParams == null) {
throw new NullPointerException("algParams must be non-null");
}
this.algid = AlgorithmId.get(algParams);
if (encryptedData == null) {
throw new NullPointerException("encryptedData must be non-null");
} else if (encryptedData.length == 0) {
throw new IllegalArgumentException("the encryptedData " +
"parameter must not be empty");
} else {
this.encryptedData = encryptedData.clone();
}
// delay the generation of ASN.1 encoding until
// getEncoded() is called
this.encoded = null;
}
/**
* Returns the encryption algorithm.
* <p>Note: Standard name is returned instead of the specified one
* in the constructor when such mapping is available.
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard Cipher algorithm names.
*
* @return the encryption algorithm name.
*/
public String getAlgName() {
return this.algid.getName();
}
/**
* Returns the algorithm parameters used by the encryption algorithm.
* @return the algorithm parameters.
*/
public AlgorithmParameters getAlgParameters() {
return this.algid.getParameters();
}
/**
* Returns the encrypted data.
* @return the encrypted data. Returns a new array
* each time this method is called.
*/
public byte[] getEncryptedData() {
return this.encryptedData.clone();
}
/**
* Extract the enclosed PKCS8EncodedKeySpec object from the
* encrypted data and return it.
* <br>Note: In order to successfully retrieve the enclosed
* PKCS8EncodedKeySpec object, <code>cipher</code> needs
* to be initialized to either Cipher.DECRYPT_MODE or
* Cipher.UNWRAP_MODE, with the same key and parameters used
* for generating the encrypted data.
*
* @param cipher the initialized cipher object which will be
* used for decrypting the encrypted data.
* @return the PKCS8EncodedKeySpec object.
* @exception NullPointerException if <code>cipher</code>
* is null.
* @exception InvalidKeySpecException if the given cipher is
* inappropriate for the encrypted data or the encrypted
* data is corrupted and cannot be decrypted.
*/
public PKCS8EncodedKeySpec getKeySpec(Cipher cipher)
throws InvalidKeySpecException {
byte[] encoded = null;
try {
encoded = cipher.doFinal(encryptedData);
checkPKCS8Encoding(encoded);
} catch (GeneralSecurityException |
IOException |
IllegalStateException ex) {
throw new InvalidKeySpecException(
"Cannot retrieve the PKCS8EncodedKeySpec", ex);
}
return new PKCS8EncodedKeySpec(encoded, keyAlg);
}
private PKCS8EncodedKeySpec getKeySpecImpl(Key decryptKey,
Provider provider) throws NoSuchAlgorithmException,
InvalidKeyException {
byte[] encoded = null;
Cipher c;
try {
if (provider == null) {
// use the most preferred one
c = Cipher.getInstance(algid.getName());
} else {
c = Cipher.getInstance(algid.getName(), provider);
}
c.init(Cipher.DECRYPT_MODE, decryptKey, algid.getParameters());
encoded = c.doFinal(encryptedData);
checkPKCS8Encoding(encoded);
} catch (NoSuchAlgorithmException nsae) {
// rethrow
throw nsae;
} catch (GeneralSecurityException | IOException ex) {
throw new InvalidKeyException(
"Cannot retrieve the PKCS8EncodedKeySpec", ex);
}
return new PKCS8EncodedKeySpec(encoded, keyAlg);
}
/**
* Extract the enclosed PKCS8EncodedKeySpec object from the
* encrypted data and return it.
* @param decryptKey key used for decrypting the encrypted data.
* @return the PKCS8EncodedKeySpec object.
* @exception NullPointerException if <code>decryptKey</code>
* is null.
* @exception NoSuchAlgorithmException if cannot find appropriate
* cipher to decrypt the encrypted data.
* @exception InvalidKeyException if <code>decryptKey</code>
* cannot be used to decrypt the encrypted data or the decryption
* result is not a valid PKCS8KeySpec.
*
* @since 1.5
*/
public PKCS8EncodedKeySpec getKeySpec(Key decryptKey)
throws NoSuchAlgorithmException, InvalidKeyException {
if (decryptKey == null) {
throw new NullPointerException("decryptKey is null");
}
return getKeySpecImpl(decryptKey, null);
}
/**
* Extract the enclosed PKCS8EncodedKeySpec object from the
* encrypted data and return it.
* @param decryptKey key used for decrypting the encrypted data.
* @param providerName the name of provider whose Cipher
* implementation will be used.
* @return the PKCS8EncodedKeySpec object.
* @exception NullPointerException if <code>decryptKey</code>
* or <code>providerName</code> is null.
* @exception NoSuchProviderException if no provider
* <code>providerName</code> is registered.
* @exception NoSuchAlgorithmException if cannot find appropriate
* cipher to decrypt the encrypted data.
* @exception InvalidKeyException if <code>decryptKey</code>
* cannot be used to decrypt the encrypted data or the decryption
* result is not a valid PKCS8KeySpec.
*
* @since 1.5
*/
public PKCS8EncodedKeySpec getKeySpec(Key decryptKey,
String providerName) throws NoSuchProviderException,
NoSuchAlgorithmException, InvalidKeyException {
if (decryptKey == null) {
throw new NullPointerException("decryptKey is null");
}
if (providerName == null) {
throw new NullPointerException("provider is null");
}
Provider provider = Security.getProvider(providerName);
if (provider == null) {
throw new NoSuchProviderException("provider " +
providerName + " not found");
}
return getKeySpecImpl(decryptKey, provider);
}
/**
* Extract the enclosed PKCS8EncodedKeySpec object from the
* encrypted data and return it.
* @param decryptKey key used for decrypting the encrypted data.
* @param provider the name of provider whose Cipher implementation
* will be used.
* @return the PKCS8EncodedKeySpec object.
* @exception NullPointerException if <code>decryptKey</code>
* or <code>provider</code> is null.
* @exception NoSuchAlgorithmException if cannot find appropriate
* cipher to decrypt the encrypted data in <code>provider</code>.
* @exception InvalidKeyException if <code>decryptKey</code>
* cannot be used to decrypt the encrypted data or the decryption
* result is not a valid PKCS8KeySpec.
*
* @since 1.5
*/
public PKCS8EncodedKeySpec getKeySpec(Key decryptKey,
Provider provider) throws NoSuchAlgorithmException,
InvalidKeyException {
if (decryptKey == null) {
throw new NullPointerException("decryptKey is null");
}
if (provider == null) {
throw new NullPointerException("provider is null");
}
return getKeySpecImpl(decryptKey, provider);
}
/**
* Returns the ASN.1 encoding of this object.
* @return the ASN.1 encoding. Returns a new array
* each time this method is called.
* @exception IOException if error occurs when constructing its
* ASN.1 encoding.
*/
public byte[] getEncoded() throws IOException {
if (this.encoded == null) {
DerOutputStream out = new DerOutputStream();
DerOutputStream tmp = new DerOutputStream();
// encode encryption algorithm
algid.encode(tmp);
// encode encrypted data
tmp.putOctetString(encryptedData);
// wrap everything into a SEQUENCE
out.write(DerValue.tag_Sequence, tmp);
this.encoded = out.toByteArray();
}
return this.encoded.clone();
}
private static void checkTag(DerValue val, byte tag, String valName)
throws IOException {
if (val.getTag() != tag) {
throw new IOException("invalid key encoding - wrong tag for " +
valName);
}
}
@SuppressWarnings("fallthrough")
private void checkPKCS8Encoding(byte[] encodedKey)
throws IOException {
DerInputStream in = new DerInputStream(encodedKey);
DerValue[] values = in.getSequence(3);
switch (values.length) {
case 4:
checkTag(values[3], DerValue.TAG_CONTEXT, "attributes");
/* fall through */
case 3:
checkTag(values[0], DerValue.tag_Integer, "version");
keyAlg = AlgorithmId.parse(values[1]).getName();
checkTag(values[2], DerValue.tag_OctetString, "privateKey");
break;
default:
throw new IOException("invalid key encoding");
}
}
}

View file

@ -0,0 +1,486 @@
/*
* Copyright (c) 1999, 2017, 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 javax.crypto;
import java.security.AlgorithmParameters;
import java.security.Provider;
import java.security.Key;
import java.security.Security;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Objects;
import sun.security.jca.GetInstance.Instance;
/**
* This class provides the functionality of an exemption mechanism, examples
* of which are <i>key recovery</i>, <i>key weakening</i>, and
* <i>key escrow</i>.
*
* <p>Applications or applets that use an exemption mechanism may be granted
* stronger encryption capabilities than those which don't.
*
* @since 1.4
*/
public class ExemptionMechanism {
// The provider
private Provider provider;
// The provider implementation (delegate)
private ExemptionMechanismSpi exmechSpi;
// The name of the exemption mechanism.
private String mechanism;
// Flag which indicates whether this ExemptionMechanism
// result is generated successfully.
private boolean done = false;
// State information
private boolean initialized = false;
// Store away the key at init() time for later comparison.
private Key keyStored = null;
/**
* Creates a ExemptionMechanism object.
*
* @param exmechSpi the delegate
* @param provider the provider
* @param mechanism the exemption mechanism
*/
protected ExemptionMechanism(ExemptionMechanismSpi exmechSpi,
Provider provider,
String mechanism) {
this.exmechSpi = exmechSpi;
this.provider = provider;
this.mechanism = mechanism;
}
/**
* Returns the exemption mechanism name of this
* <code>ExemptionMechanism</code> object.
*
* <p>This is the same name that was specified in one of the
* <code>getInstance</code> calls that created this
* <code>ExemptionMechanism</code> object.
*
* @return the exemption mechanism name of this
* <code>ExemptionMechanism</code> object.
*/
public final String getName() {
return this.mechanism;
}
/**
* Returns an <code>ExemptionMechanism</code> object that implements the
* specified exemption mechanism algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new ExemptionMechanism object encapsulating the
* ExemptionMechanismSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard name of the requested exemption
* mechanism.
* See the ExemptionMechanism section in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#exemption-mechanisms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard exemption mechanism names.
*
* @return the new {@code ExemptionMechanism} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports an
* {@code ExemptionMechanismSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final ExemptionMechanism getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("ExemptionMechanism",
ExemptionMechanismSpi.class, algorithm);
return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns an <code>ExemptionMechanism</code> object that implements the
* specified exemption mechanism algorithm.
*
* <p> A new ExemptionMechanism object encapsulating the
* ExemptionMechanismSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
* @param algorithm the standard name of the requested exemption mechanism.
* See the ExemptionMechanism section in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#exemption-mechanisms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard exemption mechanism names.
*
* @param provider the name of the provider.
*
* @return the new {@code ExemptionMechanism} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null} or empty
*
* @throws NoSuchAlgorithmException if an {@code ExemptionMechanismSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final ExemptionMechanism getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("ExemptionMechanism",
ExemptionMechanismSpi.class, algorithm, provider);
return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns an <code>ExemptionMechanism</code> object that implements the
* specified exemption mechanism algorithm.
*
* <p> A new ExemptionMechanism object encapsulating the
* ExemptionMechanismSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested exemption mechanism.
* See the ExemptionMechanism section in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#exemption-mechanisms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard exemption mechanism names.
*
* @param provider the provider.
*
* @return the new {@code ExemptionMechanism} object
*
* @throws IllegalArgumentException if the {@code provider}
* is null
*
* @throws NoSuchAlgorithmException if an {@code ExemptionMechanismSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider object}
*
* @exception NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final ExemptionMechanism getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("ExemptionMechanism",
ExemptionMechanismSpi.class, algorithm, provider);
return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the provider of this <code>ExemptionMechanism</code> object.
*
* @return the provider of this <code>ExemptionMechanism</code> object.
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Returns whether the result blob has been generated successfully by this
* exemption mechanism.
*
* <p>The method also makes sure that the key passed in is the same as
* the one this exemption mechanism used in initializing and generating
* phases.
*
* @param key the key the crypto is going to use.
*
* @return whether the result blob of the same key has been generated
* successfully by this exemption mechanism; false if <code>key</code>
* is null.
*
* @exception ExemptionMechanismException if problem(s) encountered
* while determining whether the result blob has been generated successfully
* by this exemption mechanism object.
*/
public final boolean isCryptoAllowed(Key key)
throws ExemptionMechanismException {
boolean ret = false;
if (done && (key != null)) {
// Check if the key passed in is the same as the one
// this exemption mechanism used.
ret = keyStored.equals(key);
}
return ret;
}
/**
* Returns the length in bytes that an output buffer would need to be in
* order to hold the result of the next
* {@link #genExemptionBlob(byte[]) genExemptionBlob}
* operation, given the input length <code>inputLen</code> (in bytes).
*
* <p>The actual output length of the next
* {@link #genExemptionBlob(byte[]) genExemptionBlob}
* call may be smaller than the length returned by this method.
*
* @param inputLen the input length (in bytes)
*
* @return the required output buffer size (in bytes)
*
* @exception IllegalStateException if this exemption mechanism is in a
* wrong state (e.g., has not yet been initialized)
*/
public final int getOutputSize(int inputLen) throws IllegalStateException {
if (!initialized) {
throw new IllegalStateException(
"ExemptionMechanism not initialized");
}
if (inputLen < 0) {
throw new IllegalArgumentException(
"Input size must be equal to " + "or greater than zero");
}
return exmechSpi.engineGetOutputSize(inputLen);
}
/**
* Initializes this exemption mechanism with a key.
*
* <p>If this exemption mechanism requires any algorithm parameters
* that cannot be derived from the given <code>key</code>, the
* underlying exemption mechanism implementation is supposed to
* generate the required parameters itself (using provider-specific
* default values); in the case that algorithm parameters must be
* specified by the caller, an <code>InvalidKeyException</code> is raised.
*
* @param key the key for this exemption mechanism
*
* @exception InvalidKeyException if the given key is inappropriate for
* this exemption mechanism.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of initializing.
*/
public final void init(Key key)
throws InvalidKeyException, ExemptionMechanismException {
done = false;
initialized = false;
keyStored = key;
exmechSpi.engineInit(key);
initialized = true;
}
/**
* Initializes this exemption mechanism with a key and a set of algorithm
* parameters.
*
* <p>If this exemption mechanism requires any algorithm parameters
* and <code>params</code> is null, the underlying exemption
* mechanism implementation is supposed to generate the required
* parameters itself (using provider-specific default values); in the case
* that algorithm parameters must be specified by the caller, an
* <code>InvalidAlgorithmParameterException</code> is raised.
*
* @param key the key for this exemption mechanism
* @param params the algorithm parameters
*
* @exception InvalidKeyException if the given key is inappropriate for
* this exemption mechanism.
* @exception InvalidAlgorithmParameterException if the given algorithm
* parameters are inappropriate for this exemption mechanism.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of initializing.
*/
public final void init(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException,
ExemptionMechanismException {
done = false;
initialized = false;
keyStored = key;
exmechSpi.engineInit(key, params);
initialized = true;
}
/**
* Initializes this exemption mechanism with a key and a set of algorithm
* parameters.
*
* <p>If this exemption mechanism requires any algorithm parameters
* and <code>params</code> is null, the underlying exemption mechanism
* implementation is supposed to generate the required parameters itself
* (using provider-specific default values); in the case that algorithm
* parameters must be specified by the caller, an
* <code>InvalidAlgorithmParameterException</code> is raised.
*
* @param key the key for this exemption mechanism
* @param params the algorithm parameters
*
* @exception InvalidKeyException if the given key is inappropriate for
* this exemption mechanism.
* @exception InvalidAlgorithmParameterException if the given algorithm
* parameters are inappropriate for this exemption mechanism.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of initializing.
*/
public final void init(Key key, AlgorithmParameters params)
throws InvalidKeyException, InvalidAlgorithmParameterException,
ExemptionMechanismException {
done = false;
initialized = false;
keyStored = key;
exmechSpi.engineInit(key, params);
initialized = true;
}
/**
* Generates the exemption mechanism key blob.
*
* @return the new buffer with the result key blob.
*
* @exception IllegalStateException if this exemption mechanism is in
* a wrong state (e.g., has not been initialized).
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of generating.
*/
public final byte[] genExemptionBlob() throws IllegalStateException,
ExemptionMechanismException {
if (!initialized) {
throw new IllegalStateException(
"ExemptionMechanism not initialized");
}
byte[] blob = exmechSpi.engineGenExemptionBlob();
done = true;
return blob;
}
/**
* Generates the exemption mechanism key blob, and stores the result in
* the <code>output</code> buffer.
*
* <p>If the <code>output</code> buffer is too small to hold the result,
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
* call with a larger output buffer. Use
* {@link #getOutputSize(int) getOutputSize} to determine how big
* the output buffer should be.
*
* @param output the buffer for the result
*
* @return the number of bytes stored in <code>output</code>
*
* @exception IllegalStateException if this exemption mechanism is in
* a wrong state (e.g., has not been initialized).
* @exception ShortBufferException if the given output buffer is too small
* to hold the result.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of generating.
*/
public final int genExemptionBlob(byte[] output)
throws IllegalStateException, ShortBufferException,
ExemptionMechanismException {
if (!initialized) {
throw new IllegalStateException
("ExemptionMechanism not initialized");
}
int n = exmechSpi.engineGenExemptionBlob(output, 0);
done = true;
return n;
}
/**
* Generates the exemption mechanism key blob, and stores the result in
* the <code>output</code> buffer, starting at <code>outputOffset</code>
* inclusive.
*
* <p>If the <code>output</code> buffer is too small to hold the result,
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
* call with a larger output buffer. Use
* {@link #getOutputSize(int) getOutputSize} to determine how big
* the output buffer should be.
*
* @param output the buffer for the result
* @param outputOffset the offset in <code>output</code> where the result
* is stored
*
* @return the number of bytes stored in <code>output</code>
*
* @exception IllegalStateException if this exemption mechanism is in
* a wrong state (e.g., has not been initialized).
* @exception ShortBufferException if the given output buffer is too small
* to hold the result.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of generating.
*/
public final int genExemptionBlob(byte[] output, int outputOffset)
throws IllegalStateException, ShortBufferException,
ExemptionMechanismException {
if (!initialized) {
throw new IllegalStateException
("ExemptionMechanism not initialized");
}
int n = exmechSpi.engineGenExemptionBlob(output, outputOffset);
done = true;
return n;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 1999, 2007, 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 javax.crypto;
import java.security.GeneralSecurityException;
/**
* This is the generic ExemptionMechanism exception.
*
* @since 1.4
*/
public class ExemptionMechanismException extends GeneralSecurityException {
private static final long serialVersionUID = 1572699429277957109L;
/**
* Constructs a ExemptionMechanismException with no detailed message.
* (A detailed message is a String that describes this particular
* exception.)
*/
public ExemptionMechanismException() {
super();
}
/**
* Constructs a ExemptionMechanismException with the specified
* detailed message. (A detailed message is a String that describes
* this particular exception.)
*
* @param msg the detailed message.
*/
public ExemptionMechanismException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 1999, 2007, 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 javax.crypto;
import java.security.Key;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>ExemptionMechanism</code> class.
* All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a particular exemption mechanism.
*
* @author Sharon Liu
*
* @since 1.4
*/
public abstract class ExemptionMechanismSpi {
/**
* Returns the length in bytes that an output buffer would need to be in
* order to hold the result of the next
* {@link #engineGenExemptionBlob(byte[], int) engineGenExemptionBlob}
* operation, given the input length <code>inputLen</code> (in bytes).
*
* <p>The actual output length of the next
* {@link #engineGenExemptionBlob(byte[], int) engineGenExemptionBlob}
* call may be smaller than the length returned by this method.
*
* @param inputLen the input length (in bytes)
*
* @return the required output buffer size (in bytes)
*/
protected abstract int engineGetOutputSize(int inputLen);
/**
* Initializes this exemption mechanism with a key.
*
* <p>If this exemption mechanism requires any algorithm parameters
* that cannot be derived from the given <code>key</code>, the underlying
* exemption mechanism implementation is supposed to generate the required
* parameters itself (using provider-specific default values); in the case
* that algorithm parameters must be specified by the caller, an
* <code>InvalidKeyException</code> is raised.
*
* @param key the key for this exemption mechanism
*
* @exception InvalidKeyException if the given key is inappropriate for
* this exemption mechanism.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of initializing.
*/
protected abstract void engineInit(Key key)
throws InvalidKeyException, ExemptionMechanismException;
/**
* Initializes this exemption mechanism with a key and a set of algorithm
* parameters.
*
* <p>If this exemption mechanism requires any algorithm parameters and
* <code>params</code> is null, the underlying exemption mechanism
* implementation is supposed to generate the required parameters
* itself (using provider-specific default values); in the case that
* algorithm parameters must be specified by the caller, an
* <code>InvalidAlgorithmParameterException</code> is raised.
*
* @param key the key for this exemption mechanism
* @param params the algorithm parameters
*
* @exception InvalidKeyException if the given key is inappropriate for
* this exemption mechanism.
* @exception InvalidAlgorithmParameterException if the given algorithm
* parameters are inappropriate for this exemption mechanism.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of initializing.
*/
protected abstract void engineInit(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException,
ExemptionMechanismException;
/**
* Initializes this exemption mechanism with a key and a set of algorithm
* parameters.
*
* <p>If this exemption mechanism requires any algorithm parameters
* and <code>params</code> is null, the underlying exemption mechanism
* implementation is supposed to generate the required parameters
* itself (using provider-specific default values); in the case that
* algorithm parameters must be specified by the caller, an
* <code>InvalidAlgorithmParameterException</code> is raised.
*
* @param key the key for this exemption mechanism
* @param params the algorithm parameters
*
* @exception InvalidKeyException if the given key is inappropriate for
* this exemption mechanism.
* @exception InvalidAlgorithmParameterException if the given algorithm
* parameters are inappropriate for this exemption mechanism.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of initializing.
*/
protected abstract void engineInit(Key key, AlgorithmParameters params)
throws InvalidKeyException, InvalidAlgorithmParameterException,
ExemptionMechanismException;
/**
* Generates the exemption mechanism key blob.
*
* @return the new buffer with the result key blob.
*
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of generating.
*/
protected abstract byte[] engineGenExemptionBlob()
throws ExemptionMechanismException;
/**
* Generates the exemption mechanism key blob, and stores the result in
* the <code>output</code> buffer, starting at <code>outputOffset</code>
* inclusive.
*
* <p>If the <code>output</code> buffer is too small to hold the result,
* a <code>ShortBufferException</code> is thrown. In this case, repeat this
* call with a larger output buffer. Use
* {@link #engineGetOutputSize(int) engineGetOutputSize} to determine
* how big the output buffer should be.
*
* @param output the buffer for the result
* @param outputOffset the offset in <code>output</code> where the result
* is stored
*
* @return the number of bytes stored in <code>output</code>
*
* @exception ShortBufferException if the given output buffer is too small
* to hold the result.
* @exception ExemptionMechanismException if problem(s) encountered in the
* process of generating.
*/
protected abstract int engineGenExemptionBlob
(byte[] output, int outputOffset)
throws ShortBufferException, ExemptionMechanismException;
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto;
/**
* This exception is thrown when the length of data provided to a block
* cipher is incorrect, i.e., does not match the block size of the cipher.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class IllegalBlockSizeException
extends java.security.GeneralSecurityException {
private static final long serialVersionUID = -1965144811953540392L;
/**
* Constructs an IllegalBlockSizeException with no detail message.
* A detail message is a String that describes this particular
* exception.
*/
public IllegalBlockSizeException() {
super();
}
/**
* Constructs an IllegalBlockSizeException with the specified
* detail message.
*
* @param msg the detail message.
*/
public IllegalBlockSizeException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,392 @@
/*
* Copyright (c) 1997, 2016, 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.
*/
/*
* README README README README README README README README README
*
* This file is the template for generating the JceSecurity.java source
* file.
*
* In the current jdk builds, this file is first preprocessed to replace
* @@JCE_DEFAULT_POLICY@ [sic] with "limited" or "unlimited" which is
* determined by the $(UNLIMTED_CRYPTO) make variable. This variable is
* set by top-level configure script, using either
* --disable-unlimited-crypto or --enable-unlimited-crypto [default].
*
* Since this file is a generated source, incremental changes to
* this file require regenerating the source. Compilation options:
*
* (fewer dependencies/"faster" ones first)
*
* 1. make JDK_FILTER=javax/crypto java.base-gensrc-only java.base-java-only
* 2. make java.base-gensrc-only java.base-java-only
* 3. make java.base-gensrc-only java.base-only
* 4. make java.base-only
* 5. make
*/
package javax.crypto;
import java.util.*;
import java.io.*;
import java.net.URL;
import java.nio.file.*;
import java.security.*;
import java.security.Provider.Service;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
import sun.security.util.Debug;
/**
* This class instantiates implementations of JCE engine classes from
* providers registered with the java.security.Security object.
*
* @author Jan Luehe
* @author Sharon Liu
* @since 1.4
*/
final class JceSecurity {
private static final Debug debug = Debug.getInstance("jca");
static final SecureRandom RANDOM = new SecureRandom();
// The defaultPolicy and exemptPolicy will be set up
// in the static initializer.
private static CryptoPermissions defaultPolicy = null;
private static CryptoPermissions exemptPolicy = null;
// Map<Provider,?> of the providers we already have verified
// value == PROVIDER_VERIFIED is successfully verified
// value is failure cause Exception in error case
private static final Map<Provider, Object> verificationResults =
new IdentityHashMap<>();
// Map<Provider,?> of the providers currently being verified
private static final Map<Provider, Object> verifyingProviders =
new IdentityHashMap<>();
private static final boolean isRestricted;
/*
* Don't let anyone instantiate this.
*/
private JceSecurity() {
}
static {
try {
AccessController.doPrivileged(
new PrivilegedExceptionAction<> () {
@Override
public Void run() throws Exception {
setupJurisdictionPolicies();
return null;
}
}
);
isRestricted = defaultPolicy.implies(
CryptoAllPermission.INSTANCE) ? false : true;
} catch (Exception e) {
throw new SecurityException(
"Can not initialize cryptographic mechanism", e);
}
}
static Instance getInstance(String type, Class<?> clazz, String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Service s = GetInstance.getService(type, algorithm, provider);
Exception ve = getVerificationResult(s.getProvider());
if (ve != null) {
String msg = "JCE cannot authenticate the provider " + provider;
throw (NoSuchProviderException)
new NoSuchProviderException(msg).initCause(ve);
}
return GetInstance.getInstance(s, clazz);
}
static Instance getInstance(String type, Class<?> clazz, String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Service s = GetInstance.getService(type, algorithm, provider);
Exception ve = JceSecurity.getVerificationResult(provider);
if (ve != null) {
String msg = "JCE cannot authenticate the provider "
+ provider.getName();
throw new SecurityException(msg, ve);
}
return GetInstance.getInstance(s, clazz);
}
static Instance getInstance(String type, Class<?> clazz, String algorithm)
throws NoSuchAlgorithmException {
List<Service> services = GetInstance.getServices(type, algorithm);
NoSuchAlgorithmException failure = null;
for (Service s : services) {
if (canUseProvider(s.getProvider()) == false) {
// allow only signed providers
continue;
}
try {
Instance instance = GetInstance.getInstance(s, clazz);
return instance;
} catch (NoSuchAlgorithmException e) {
failure = e;
}
}
throw new NoSuchAlgorithmException("Algorithm " + algorithm
+ " not available", failure);
}
/**
* Verify if the JAR at URL codeBase is a signed exempt application
* JAR file and returns the permissions bundled with the JAR.
*
* @throws Exception on error
*/
static CryptoPermissions verifyExemptJar(URL codeBase) throws Exception {
ProviderVerifier pv = new ProviderVerifier(codeBase, true);
pv.verify();
return pv.getPermissions();
}
/**
* Verify if the JAR at URL codeBase is a signed provider JAR file.
*
* @throws Exception on error
*/
static void verifyProvider(URL codeBase, Provider p) throws Exception {
// Verify the provider JAR file and all
// supporting JAR files if there are any.
ProviderVerifier pv = new ProviderVerifier(codeBase, p, false);
pv.verify();
}
private static final Object PROVIDER_VERIFIED = Boolean.TRUE;
/*
* Verify that the provider JAR files are signed properly, which
* means the signer's certificate can be traced back to a
* JCE trusted CA.
* Return null if ok, failure Exception if verification failed.
*/
static synchronized Exception getVerificationResult(Provider p) {
Object o = verificationResults.get(p);
if (o == PROVIDER_VERIFIED) {
return null;
} else if (o != null) {
return (Exception)o;
}
if (verifyingProviders.get(p) != null) {
// this method is static synchronized, must be recursion
// return failure now but do not save the result
return new NoSuchProviderException("Recursion during verification");
}
try {
verifyingProviders.put(p, Boolean.FALSE);
URL providerURL = getCodeBase(p.getClass());
verifyProvider(providerURL, p);
// Verified ok, cache result
verificationResults.put(p, PROVIDER_VERIFIED);
return null;
} catch (Exception e) {
verificationResults.put(p, e);
return e;
} finally {
verifyingProviders.remove(p);
}
}
// return whether this provider is properly signed and can be used by JCE
static boolean canUseProvider(Provider p) {
return getVerificationResult(p) == null;
}
// dummy object to represent null
private static final URL NULL_URL;
static {
try {
NULL_URL = new URL("http://null.oracle.com/");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// reference to a Map we use as a cache for codebases
private static final Map<Class<?>, URL> codeBaseCacheRef =
new WeakHashMap<>();
/*
* Returns the CodeBase for the given class.
*/
static URL getCodeBase(final Class<?> clazz) {
synchronized (codeBaseCacheRef) {
URL url = codeBaseCacheRef.get(clazz);
if (url == null) {
url = AccessController.doPrivileged(
new PrivilegedAction<>() {
@Override
public URL run() {
ProtectionDomain pd = clazz.getProtectionDomain();
if (pd != null) {
CodeSource cs = pd.getCodeSource();
if (cs != null) {
return cs.getLocation();
}
}
return NULL_URL;
}
});
codeBaseCacheRef.put(clazz, url);
}
return (url == NULL_URL) ? null : url;
}
}
// This is called from within an doPrivileged block.
private static void setupJurisdictionPolicies() throws Exception {
// Sanity check the crypto.policy Security property. Single
// directory entry, no pseudo-directories (".", "..", leading/trailing
// path separators). normalize()/getParent() will help later.
String cryptoPolicyProperty = Security.getProperty("crypto.policy");
/*
* In case no property is present, rather than fail catastrophically,
* we at least try for a "sane" value, which is what we were
* built with. We first preprocess this file to plug in that
* value, then compile the result gensrc.
*
* Log the warning first.
*/
if (cryptoPolicyProperty == null) {
cryptoPolicyProperty = "@@JCE_DEFAULT_POLICY@@";
if (debug != null) {
debug.println(
"Security Property 'crypto.policy' not found: "
+ "using '" + cryptoPolicyProperty + "' as fallback");
}
}
Path cpPath = Paths.get(cryptoPolicyProperty);
if ((cpPath.getNameCount() != 1) ||
(cpPath.compareTo(cpPath.getFileName()) != 0)) {
throw new SecurityException(
"Invalid policy directory name format: " +
cryptoPolicyProperty);
}
// Prepend java.home to get the full path. normalize() in
// case an extra "." or ".." snuck in somehow.
String javaHomeProperty = System.getProperty("java.home");
Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf",
"security", "policy").normalize();
Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security",
"policy", cryptoPolicyProperty).normalize();
if (cryptoPolicyPath.getParent().compareTo(javaHomePolicyPath) != 0) {
throw new SecurityException(
"Invalid cryptographic jurisdiction policy directory path: " +
cryptoPolicyProperty);
}
if (!Files.isDirectory(cryptoPolicyPath)
|| !Files.isReadable(cryptoPolicyPath)) {
throw new SecurityException(
"Can't read cryptographic policy directory: " +
cryptoPolicyProperty);
}
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
cryptoPolicyPath, "{default,exempt}_*.policy")) {
for (Path entry : stream) {
try (InputStream is = new BufferedInputStream(
Files.newInputStream(entry))) {
String filename = entry.getFileName().toString();
CryptoPermissions tmpPerms = new CryptoPermissions();
tmpPerms.load(is);
if (filename.startsWith("default_")) {
// Did we find a default perms?
defaultPolicy = ((defaultPolicy == null) ? tmpPerms :
defaultPolicy.getMinimum(tmpPerms));
} else if (filename.startsWith("exempt_")) {
// Did we find a exempt perms?
exemptPolicy = ((exemptPolicy == null) ? tmpPerms :
exemptPolicy.getMinimum(tmpPerms));
} else {
// This should never happen. newDirectoryStream
// should only throw return "{default,exempt}_*.policy"
throw new SecurityException(
"Unexpected jurisdiction policy files in : " +
cryptoPolicyProperty);
}
} catch (Exception e) {
throw new SecurityException(
"Couldn't parse jurisdiction policy files in: " +
cryptoPolicyProperty);
}
}
} catch (DirectoryIteratorException ex) {
// I/O error encountered during the iteration,
// the cause is an IOException
throw new SecurityException(
"Couldn't iterate through the jurisdiction policy files: " +
cryptoPolicyProperty);
}
// Must have a default policy
if ((defaultPolicy == null) || defaultPolicy.isEmpty()) {
throw new SecurityException(
"Missing mandatory jurisdiction policy files: " +
cryptoPolicyProperty);
}
// If there was an empty exempt policy file, ignore it.
if ((exemptPolicy != null) && exemptPolicy.isEmpty()) {
exemptPolicy = null;
}
}
static CryptoPermissions getDefaultPolicy() {
return defaultPolicy;
}
static CryptoPermissions getExemptPolicy() {
return exemptPolicy;
}
static boolean isRestricted() {
return isRestricted;
}
}

View file

@ -0,0 +1,281 @@
/*
* Copyright (c) 1999, 2017, 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 javax.crypto;
import java.security.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* The JCE security manager.
*
* <p>The JCE security manager is responsible for determining the maximum
* allowable cryptographic strength for a given applet/application, for a given
* algorithm, by consulting the configured jurisdiction policy files and
* the cryptographic permissions bundled with the applet/application.
*
* <p>Note that this security manager is never installed, only instantiated.
*
* @author Jan Luehe
*
* @since 1.4
*/
final class JceSecurityManager extends SecurityManager {
private static final CryptoPermissions defaultPolicy;
private static final CryptoPermissions exemptPolicy;
private static final CryptoAllPermission allPerm;
private static final Vector<Class<?>> TrustedCallersCache =
new Vector<>(2);
private static final ConcurrentMap<URL,CryptoPermissions> exemptCache =
new ConcurrentHashMap<>();
private static final CryptoPermissions CACHE_NULL_MARK =
new CryptoPermissions();
// singleton instance
static final JceSecurityManager INSTANCE;
static {
defaultPolicy = JceSecurity.getDefaultPolicy();
exemptPolicy = JceSecurity.getExemptPolicy();
allPerm = CryptoAllPermission.INSTANCE;
INSTANCE = AccessController.doPrivileged(
new PrivilegedAction<>() {
public JceSecurityManager run() {
return new JceSecurityManager();
}
});
}
private JceSecurityManager() {
// empty
}
/**
* Returns the maximum allowable crypto strength for the given
* applet/application, for the given algorithm.
*/
CryptoPermission getCryptoPermission(String alg) {
// Need to convert to uppercase since the crypto perm
// lookup is case sensitive.
alg = alg.toUpperCase(Locale.ENGLISH);
// If CryptoAllPermission is granted by default, we return that.
// Otherwise, this will be the permission we return if anything goes
// wrong.
CryptoPermission defaultPerm = getDefaultPermission(alg);
if (defaultPerm == CryptoAllPermission.INSTANCE) {
return defaultPerm;
}
// Determine the codebase of the caller of the JCE API.
// This is the codebase of the first class which is not in
// javax.crypto.* packages.
// NOTE: javax.crypto.* package maybe subject to package
// insertion, so need to check its classloader as well.
Class<?>[] context = getClassContext();
URL callerCodeBase = null;
int i;
for (i=0; i<context.length; i++) {
Class<?> cls = context[i];
callerCodeBase = JceSecurity.getCodeBase(cls);
if (callerCodeBase != null) {
break;
} else {
if (cls.getName().startsWith("javax.crypto.")) {
// skip jce classes since they aren't the callers
continue;
}
// use default permission when the caller is system classes
return defaultPerm;
}
}
if (i == context.length) {
return defaultPerm;
}
CryptoPermissions appPerms = exemptCache.get(callerCodeBase);
if (appPerms == null) {
// no match found in cache
synchronized (this.getClass()) {
appPerms = exemptCache.get(callerCodeBase);
if (appPerms == null) {
appPerms = getAppPermissions(callerCodeBase);
exemptCache.putIfAbsent(callerCodeBase,
(appPerms == null? CACHE_NULL_MARK:appPerms));
}
}
}
if (appPerms == null || appPerms == CACHE_NULL_MARK) {
return defaultPerm;
}
// If the app was granted the special CryptoAllPermission, return that.
if (appPerms.implies(allPerm)) {
return allPerm;
}
// Check if the crypto permissions granted to the app contain a
// crypto permission for the requested algorithm that does not require
// any exemption mechanism to be enforced.
// Return that permission, if present.
PermissionCollection appPc = appPerms.getPermissionCollection(alg);
if (appPc == null) {
return defaultPerm;
}
Enumeration<Permission> enum_ = appPc.elements();
while (enum_.hasMoreElements()) {
CryptoPermission cp = (CryptoPermission)enum_.nextElement();
if (cp.getExemptionMechanism() == null) {
return cp;
}
}
// Check if the jurisdiction file for exempt applications contains
// any entries for the requested algorithm.
// If not, return the default permission.
PermissionCollection exemptPc =
exemptPolicy.getPermissionCollection(alg);
if (exemptPc == null) {
return defaultPerm;
}
// In the jurisdiction file for exempt applications, go through the
// list of CryptoPermission entries for the requested algorithm, and
// stop at the first entry:
// - that is implied by the collection of crypto permissions granted
// to the app, and
// - whose exemption mechanism is available from one of the
// registered CSPs
enum_ = exemptPc.elements();
while (enum_.hasMoreElements()) {
CryptoPermission cp = (CryptoPermission)enum_.nextElement();
try {
ExemptionMechanism.getInstance(cp.getExemptionMechanism());
if (cp.getAlgorithm().equals(
CryptoPermission.ALG_NAME_WILDCARD)) {
CryptoPermission newCp;
if (cp.getCheckParam()) {
newCp = new CryptoPermission(
alg, cp.getMaxKeySize(),
cp.getAlgorithmParameterSpec(),
cp.getExemptionMechanism());
} else {
newCp = new CryptoPermission(
alg, cp.getMaxKeySize(),
cp.getExemptionMechanism());
}
if (appPerms.implies(newCp)) {
return newCp;
}
}
if (appPerms.implies(cp)) {
return cp;
}
} catch (Exception e) {
continue;
}
}
return defaultPerm;
}
private static CryptoPermissions getAppPermissions(URL callerCodeBase) {
// Check if app is exempt, and retrieve the permissions bundled with it
try {
return JceSecurity.verifyExemptJar(callerCodeBase);
} catch (Exception e) {
// Jar verification fails
return null;
}
}
/**
* Returns the default permission for the given algorithm.
*/
private CryptoPermission getDefaultPermission(String alg) {
Enumeration<Permission> enum_ =
defaultPolicy.getPermissionCollection(alg).elements();
return (CryptoPermission)enum_.nextElement();
}
// Only used by javax.crypto.Cipher constructor to disallow Cipher
// objects being constructed by untrusted code (See bug 4341369 &
// 4334690 for more info).
boolean isCallerTrusted(Provider provider) {
// Get the caller and its codebase.
Class<?>[] context = getClassContext();
if (context.length >= 3) {
// context[0]: class javax.crypto.JceSecurityManager
// context[1]: class javax.crypto.Cipher (or other JCE API class)
// context[2]: this is what we are gonna check
Class<?> caller = context[2];
URL callerCodeBase = JceSecurity.getCodeBase(caller);
if (callerCodeBase == null) {
return true;
}
// The caller has been verified.
if (TrustedCallersCache.contains(caller)) {
return true;
}
// Check the association between caller and provider
Class<?> pCls = provider.getClass();
Module pMod = pCls.getModule();
// If they are in the same named module or share
// the same codebase, then they are associated
boolean sameOrigin = (pMod.isNamed()?
caller.getModule().equals(pMod) :
callerCodeBase.equals(JceSecurity.getCodeBase(pCls)));
if (sameOrigin) {
// The caller is from trusted provider
if (ProviderVerifier.isTrustedCryptoProvider(provider)) {
TrustedCallersCache.addElement(caller);
return true;
}
} else {
// Don't include the provider in the subsequent
// JceSecurity.verifyProvider(...) call
provider = null;
}
// Check whether the caller is a trusted provider.
try {
JceSecurity.verifyProvider(callerCodeBase, provider);
} catch (Exception e2) {
return false;
}
TrustedCallersCache.addElement(caller);
return true;
}
return false;
}
}

View file

@ -0,0 +1,662 @@
/*
* Copyright (c) 1997, 2017, 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 javax.crypto;
import java.util.*;
import java.security.*;
import java.security.Provider.Service;
import java.security.spec.*;
import sun.security.util.Debug;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* This class provides the functionality of a key agreement (or key
* exchange) protocol.
* <p>
* The keys involved in establishing a shared secret are created by one of the
* key generators ({@code KeyPairGenerator} or
* {@code KeyGenerator}), a {@code KeyFactory}, or as a result from
* an intermediate phase of the key agreement protocol.
*
* <p> For each of the correspondents in the key exchange, {@code doPhase}
* needs to be called. For example, if this key exchange is with one other
* party, {@code doPhase} needs to be called once, with the
* {@code lastPhase} flag set to {@code true}.
* If this key exchange is
* with two other parties, {@code doPhase} needs to be called twice,
* the first time setting the {@code lastPhase} flag to
* {@code false}, and the second time setting it to {@code true}.
* There may be any number of parties involved in a key exchange.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code KeyAgreement} algorithm:
* <ul>
* <li>{@code DiffieHellman}</li>
* </ul>
* This algorithm is described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyagreement-algorithms">
* KeyAgreement section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Jan Luehe
*
* @see KeyGenerator
* @see SecretKey
* @since 1.4
*/
public class KeyAgreement {
private static final Debug debug =
Debug.getInstance("jca", "KeyAgreement");
private static final Debug pdebug =
Debug.getInstance("provider", "Provider");
private static final boolean skipDebug =
Debug.isOn("engine=") && !Debug.isOn("keyagreement");
// The provider
private Provider provider;
// The provider implementation (delegate)
private KeyAgreementSpi spi;
// The name of the key agreement algorithm.
private final String algorithm;
// next service to try in provider selection
// null once provider is selected
private Service firstService;
// remaining services to try in provider selection
// null once provider is selected
private Iterator<Service> serviceIterator;
private final Object lock;
/**
* Creates a KeyAgreement object.
*
* @param keyAgreeSpi the delegate
* @param provider the provider
* @param algorithm the algorithm
*/
protected KeyAgreement(KeyAgreementSpi keyAgreeSpi, Provider provider,
String algorithm) {
this.spi = keyAgreeSpi;
this.provider = provider;
this.algorithm = algorithm;
lock = null;
}
private KeyAgreement(Service s, Iterator<Service> t, String algorithm) {
firstService = s;
serviceIterator = t;
this.algorithm = algorithm;
lock = new Object();
}
/**
* Returns the algorithm name of this {@code KeyAgreement} object.
*
* <p>This is the same name that was specified in one of the
* {@code getInstance} calls that created this
* {@code KeyAgreement} object.
*
* @return the algorithm name of this {@code KeyAgreement} object.
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns a {@code KeyAgreement} object that implements the
* specified key agreement algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new KeyAgreement object encapsulating the
* KeyAgreementSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
* See the KeyAgreement section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyagreement-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new {@code KeyAgreement} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code KeyAgreementSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyAgreement getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
List<Service> services =
GetInstance.getServices("KeyAgreement", algorithm);
// make sure there is at least one service from a signed provider
Iterator<Service> t = services.iterator();
while (t.hasNext()) {
Service s = t.next();
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
return new KeyAgreement(s, t, algorithm);
}
throw new NoSuchAlgorithmException
("Algorithm " + algorithm + " not available");
}
/**
* Returns a {@code KeyAgreement} object that implements the
* specified key agreement algorithm.
*
* <p> A new KeyAgreement object encapsulating the
* KeyAgreementSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
* See the KeyAgreement section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyagreement-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new {@code KeyAgreement} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code KeyAgreementSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyAgreement getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
return new KeyAgreement((KeyAgreementSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a {@code KeyAgreement} object that implements the
* specified key agreement algorithm.
*
* <p> A new KeyAgreement object encapsulating the
* KeyAgreementSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested key agreement
* algorithm.
* See the KeyAgreement section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyagreement-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return the new {@code KeyAgreement} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null}
*
* @throws NoSuchAlgorithmException if a {@code KeyAgreementSpi}
* implementation for the specified algorithm is not available
* from the specified Provider object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyAgreement getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("KeyAgreement", KeyAgreementSpi.class, algorithm, provider);
return new KeyAgreement((KeyAgreementSpi)instance.impl,
instance.provider, algorithm);
}
// max number of debug warnings to print from chooseFirstProvider()
private static int warnCount = 10;
/**
* Choose the Spi from the first provider available. Used if
* delayed provider selection is not possible because init()
* is not the first method called.
*/
void chooseFirstProvider() {
if (spi != null) {
return;
}
synchronized (lock) {
if (spi != null) {
return;
}
if (debug != null) {
int w = --warnCount;
if (w >= 0) {
debug.println("KeyAgreement.init() not first method "
+ "called, disabling delayed provider selection");
if (w == 0) {
debug.println("Further warnings of this type will "
+ "be suppressed");
}
new Exception("Call trace").printStackTrace();
}
}
Exception lastException = null;
while ((firstService != null) || serviceIterator.hasNext()) {
Service s;
if (firstService != null) {
s = firstService;
firstService = null;
} else {
s = serviceIterator.next();
}
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
try {
Object obj = s.newInstance(null);
if (obj instanceof KeyAgreementSpi == false) {
continue;
}
spi = (KeyAgreementSpi)obj;
provider = s.getProvider();
// not needed any more
firstService = null;
serviceIterator = null;
return;
} catch (Exception e) {
lastException = e;
}
}
ProviderException e = new ProviderException
("Could not construct KeyAgreementSpi instance");
if (lastException != null) {
e.initCause(lastException);
}
throw e;
}
}
private static final int I_NO_PARAMS = 1;
private static final int I_PARAMS = 2;
private void implInit(KeyAgreementSpi spi, int type, Key key,
AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
if (type == I_NO_PARAMS) {
spi.engineInit(key, random);
} else { // I_PARAMS
spi.engineInit(key, params, random);
}
}
private void chooseProvider(int initType, Key key,
AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
synchronized (lock) {
if (spi != null) {
implInit(spi, initType, key, params, random);
return;
}
Exception lastException = null;
while ((firstService != null) || serviceIterator.hasNext()) {
Service s;
if (firstService != null) {
s = firstService;
firstService = null;
} else {
s = serviceIterator.next();
}
// if provider says it does not support this key, ignore it
if (s.supportsParameter(key) == false) {
continue;
}
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
try {
KeyAgreementSpi spi = (KeyAgreementSpi)s.newInstance(null);
implInit(spi, initType, key, params, random);
provider = s.getProvider();
this.spi = spi;
firstService = null;
serviceIterator = null;
return;
} catch (Exception e) {
// NoSuchAlgorithmException from newInstance()
// InvalidKeyException from init()
// RuntimeException (ProviderException) from init()
if (lastException == null) {
lastException = e;
}
}
}
// no working provider found, fail
if (lastException instanceof InvalidKeyException) {
throw (InvalidKeyException)lastException;
}
if (lastException instanceof InvalidAlgorithmParameterException) {
throw (InvalidAlgorithmParameterException)lastException;
}
if (lastException instanceof RuntimeException) {
throw (RuntimeException)lastException;
}
String kName = (key != null) ? key.getClass().getName() : "(null)";
throw new InvalidKeyException
("No installed provider supports this key: "
+ kName, lastException);
}
}
/**
* Returns the provider of this {@code KeyAgreement} object.
*
* @return the provider of this {@code KeyAgreement} object
*/
public final Provider getProvider() {
chooseFirstProvider();
return this.provider;
}
/**
* Initializes this key agreement with the given key, which is required to
* contain all the algorithm parameters required for this key agreement.
*
* <p> If this key agreement requires any random bytes, it will get
* them using the
* {@link java.security.SecureRandom}
* implementation of the highest-priority
* installed provider as the source of randomness.
* (If none of the installed providers supply an implementation of
* SecureRandom, a system-provided source of randomness will be used.)
*
* @param key the party's private information. For example, in the case
* of the Diffie-Hellman key agreement, this would be the party's own
* Diffie-Hellman private key.
*
* @exception InvalidKeyException if the given key is
* inappropriate for this key agreement, e.g., is of the wrong type or
* has an incompatible algorithm type.
*/
public final void init(Key key) throws InvalidKeyException {
init(key, JceSecurity.RANDOM);
}
/**
* Initializes this key agreement with the given key and source of
* randomness. The given key is required to contain all the algorithm
* parameters required for this key agreement.
*
* <p> If the key agreement algorithm requires random bytes, it gets them
* from the given source of randomness, {@code random}.
* However, if the underlying
* algorithm implementation does not require any random bytes,
* {@code random} is ignored.
*
* @param key the party's private information. For example, in the case
* of the Diffie-Hellman key agreement, this would be the party's own
* Diffie-Hellman private key.
* @param random the source of randomness
*
* @exception InvalidKeyException if the given key is
* inappropriate for this key agreement, e.g., is of the wrong type or
* has an incompatible algorithm type.
*/
public final void init(Key key, SecureRandom random)
throws InvalidKeyException {
if (spi != null) {
spi.engineInit(key, random);
} else {
try {
chooseProvider(I_NO_PARAMS, key, null, random);
} catch (InvalidAlgorithmParameterException e) {
// should never occur
throw new InvalidKeyException(e);
}
}
if (!skipDebug && pdebug != null) {
pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
getProviderName());
}
}
/**
* Initializes this key agreement with the given key and set of
* algorithm parameters.
*
* <p> If this key agreement requires any random bytes, it will get
* them using the
* {@link java.security.SecureRandom}
* implementation of the highest-priority
* installed provider as the source of randomness.
* (If none of the installed providers supply an implementation of
* SecureRandom, a system-provided source of randomness will be used.)
*
* @param key the party's private information. For example, in the case
* of the Diffie-Hellman key agreement, this would be the party's own
* Diffie-Hellman private key.
* @param params the key agreement parameters
*
* @exception InvalidKeyException if the given key is
* inappropriate for this key agreement, e.g., is of the wrong type or
* has an incompatible algorithm type.
* @exception InvalidAlgorithmParameterException if the given parameters
* are inappropriate for this key agreement.
*/
public final void init(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
init(key, params, JceSecurity.RANDOM);
}
private String getProviderName() {
return (provider == null) ? "(no provider)" : provider.getName();
}
/**
* Initializes this key agreement with the given key, set of
* algorithm parameters, and source of randomness.
*
* @param key the party's private information. For example, in the case
* of the Diffie-Hellman key agreement, this would be the party's own
* Diffie-Hellman private key.
* @param params the key agreement parameters
* @param random the source of randomness
*
* @exception InvalidKeyException if the given key is
* inappropriate for this key agreement, e.g., is of the wrong type or
* has an incompatible algorithm type.
* @exception InvalidAlgorithmParameterException if the given parameters
* are inappropriate for this key agreement.
*/
public final void init(Key key, AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
if (spi != null) {
spi.engineInit(key, params, random);
} else {
chooseProvider(I_PARAMS, key, params, random);
}
if (!skipDebug && pdebug != null) {
pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
getProviderName());
}
}
/**
* Executes the next phase of this key agreement with the given
* key that was received from one of the other parties involved in this key
* agreement.
*
* @param key the key for this phase. For example, in the case of
* Diffie-Hellman between 2 parties, this would be the other party's
* Diffie-Hellman public key.
* @param lastPhase flag which indicates whether or not this is the last
* phase of this key agreement.
*
* @return the (intermediate) key resulting from this phase, or null
* if this phase does not yield a key
*
* @exception InvalidKeyException if the given key is inappropriate for
* this phase.
* @exception IllegalStateException if this key agreement has not been
* initialized.
*/
public final Key doPhase(Key key, boolean lastPhase)
throws InvalidKeyException, IllegalStateException
{
chooseFirstProvider();
return spi.engineDoPhase(key, lastPhase);
}
/**
* Generates the shared secret and returns it in a new buffer.
*
* <p>This method resets this {@code KeyAgreement} object, so that it
* can be reused for further key agreements. Unless this key agreement is
* reinitialized with one of the {@code init} methods, the same
* private information and algorithm parameters will be used for
* subsequent key agreements.
*
* @return the new buffer with the shared secret
*
* @exception IllegalStateException if this key agreement has not been
* completed yet
*/
public final byte[] generateSecret() throws IllegalStateException {
chooseFirstProvider();
return spi.engineGenerateSecret();
}
/**
* Generates the shared secret, and places it into the buffer
* {@code sharedSecret}, beginning at {@code offset} inclusive.
*
* <p>If the {@code sharedSecret} buffer is too small to hold the
* result, a {@code ShortBufferException} is thrown.
* In this case, this call should be repeated with a larger output buffer.
*
* <p>This method resets this {@code KeyAgreement} object, so that it
* can be reused for further key agreements. Unless this key agreement is
* reinitialized with one of the {@code init} methods, the same
* private information and algorithm parameters will be used for
* subsequent key agreements.
*
* @param sharedSecret the buffer for the shared secret
* @param offset the offset in {@code sharedSecret} where the
* shared secret will be stored
*
* @return the number of bytes placed into {@code sharedSecret}
*
* @exception IllegalStateException if this key agreement has not been
* completed yet
* @exception ShortBufferException if the given output buffer is too small
* to hold the secret
*/
public final int generateSecret(byte[] sharedSecret, int offset)
throws IllegalStateException, ShortBufferException
{
chooseFirstProvider();
return spi.engineGenerateSecret(sharedSecret, offset);
}
/**
* Creates the shared secret and returns it as a {@code SecretKey}
* object of the specified algorithm.
*
* <p>This method resets this {@code KeyAgreement} object, so that it
* can be reused for further key agreements. Unless this key agreement is
* reinitialized with one of the {@code init} methods, the same
* private information and algorithm parameters will be used for
* subsequent key agreements.
*
* @param algorithm the requested secret-key algorithm
*
* @return the shared secret key
*
* @exception IllegalStateException if this key agreement has not been
* completed yet
* @exception NoSuchAlgorithmException if the specified secret-key
* algorithm is not available
* @exception InvalidKeyException if the shared secret-key material cannot
* be used to generate a secret key of the specified algorithm (e.g.,
* the key material is too short)
*/
public final SecretKey generateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException
{
chooseFirstProvider();
return spi.engineGenerateSecret(algorithm);
}
}

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto;
import java.security.*;
import java.security.spec.*;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>KeyAgreement</code> class.
* All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a particular key agreement algorithm.
*
* <p> The keys involved in establishing a shared secret are created by one
* of the
* key generators (<code>KeyPairGenerator</code> or
* <code>KeyGenerator</code>), a <code>KeyFactory</code>, or as a result from
* an intermediate phase of the key agreement protocol
* ({@link #engineDoPhase(java.security.Key, boolean) engineDoPhase}).
*
* <p> For each of the correspondents in the key exchange,
* <code>engineDoPhase</code>
* needs to be called. For example, if the key exchange is with one other
* party, <code>engineDoPhase</code> needs to be called once, with the
* <code>lastPhase</code> flag set to <code>true</code>.
* If the key exchange is
* with two other parties, <code>engineDoPhase</code> needs to be called twice,
* the first time setting the <code>lastPhase</code> flag to
* <code>false</code>, and the second time setting it to <code>true</code>.
* There may be any number of parties involved in a key exchange.
*
* @author Jan Luehe
*
* @see KeyGenerator
* @see SecretKey
* @since 1.4
*/
public abstract class KeyAgreementSpi {
/**
* Initializes this key agreement with the given key and source of
* randomness. The given key is required to contain all the algorithm
* parameters required for this key agreement.
*
* <p> If the key agreement algorithm requires random bytes, it gets them
* from the given source of randomness, <code>random</code>.
* However, if the underlying
* algorithm implementation does not require any random bytes,
* <code>random</code> is ignored.
*
* @param key the party's private information. For example, in the case
* of the Diffie-Hellman key agreement, this would be the party's own
* Diffie-Hellman private key.
* @param random the source of randomness
*
* @exception InvalidKeyException if the given key is
* inappropriate for this key agreement, e.g., is of the wrong type or
* has an incompatible algorithm type.
*/
protected abstract void engineInit(Key key, SecureRandom random)
throws InvalidKeyException;
/**
* Initializes this key agreement with the given key, set of
* algorithm parameters, and source of randomness.
*
* @param key the party's private information. For example, in the case
* of the Diffie-Hellman key agreement, this would be the party's own
* Diffie-Hellman private key.
* @param params the key agreement parameters
* @param random the source of randomness
*
* @exception InvalidKeyException if the given key is
* inappropriate for this key agreement, e.g., is of the wrong type or
* has an incompatible algorithm type.
* @exception InvalidAlgorithmParameterException if the given parameters
* are inappropriate for this key agreement.
*/
protected abstract void engineInit(Key key, AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException;
/**
* Executes the next phase of this key agreement with the given
* key that was received from one of the other parties involved in this key
* agreement.
*
* @param key the key for this phase. For example, in the case of
* Diffie-Hellman between 2 parties, this would be the other party's
* Diffie-Hellman public key.
* @param lastPhase flag which indicates whether or not this is the last
* phase of this key agreement.
*
* @return the (intermediate) key resulting from this phase, or null if
* this phase does not yield a key
*
* @exception InvalidKeyException if the given key is inappropriate for
* this phase.
* @exception IllegalStateException if this key agreement has not been
* initialized.
*/
protected abstract Key engineDoPhase(Key key, boolean lastPhase)
throws InvalidKeyException, IllegalStateException;
/**
* Generates the shared secret and returns it in a new buffer.
*
* <p>This method resets this <code>KeyAgreementSpi</code> object,
* so that it
* can be reused for further key agreements. Unless this key agreement is
* reinitialized with one of the <code>engineInit</code> methods, the same
* private information and algorithm parameters will be used for
* subsequent key agreements.
*
* @return the new buffer with the shared secret
*
* @exception IllegalStateException if this key agreement has not been
* completed yet
*/
protected abstract byte[] engineGenerateSecret()
throws IllegalStateException;
/**
* Generates the shared secret, and places it into the buffer
* <code>sharedSecret</code>, beginning at <code>offset</code> inclusive.
*
* <p>If the <code>sharedSecret</code> buffer is too small to hold the
* result, a <code>ShortBufferException</code> is thrown.
* In this case, this call should be repeated with a larger output buffer.
*
* <p>This method resets this <code>KeyAgreementSpi</code> object,
* so that it
* can be reused for further key agreements. Unless this key agreement is
* reinitialized with one of the <code>engineInit</code> methods, the same
* private information and algorithm parameters will be used for
* subsequent key agreements.
*
* @param sharedSecret the buffer for the shared secret
* @param offset the offset in <code>sharedSecret</code> where the
* shared secret will be stored
*
* @return the number of bytes placed into <code>sharedSecret</code>
*
* @exception IllegalStateException if this key agreement has not been
* completed yet
* @exception ShortBufferException if the given output buffer is too small
* to hold the secret
*/
protected abstract int engineGenerateSecret(byte[] sharedSecret,
int offset)
throws IllegalStateException, ShortBufferException;
/**
* Creates the shared secret and returns it as a secret key object
* of the requested algorithm type.
*
* <p>This method resets this <code>KeyAgreementSpi</code> object,
* so that it
* can be reused for further key agreements. Unless this key agreement is
* reinitialized with one of the <code>engineInit</code> methods, the same
* private information and algorithm parameters will be used for
* subsequent key agreements.
*
* @param algorithm the requested secret key algorithm
*
* @return the shared secret key
*
* @exception IllegalStateException if this key agreement has not been
* completed yet
* @exception NoSuchAlgorithmException if the requested secret key
* algorithm is not available
* @exception InvalidKeyException if the shared secret key material cannot
* be used to generate a secret key of the requested algorithm type (e.g.,
* the key material is too short)
*/
protected abstract SecretKey engineGenerateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException;
}

View file

@ -0,0 +1,579 @@
/*
* Copyright (c) 1997, 2017, 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 javax.crypto;
import java.util.*;
import java.security.*;
import java.security.Provider.Service;
import java.security.spec.*;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
import sun.security.util.Debug;
/**
* This class provides the functionality of a secret (symmetric) key generator.
*
* <p>Key generators are constructed using one of the {@code getInstance}
* class methods of this class.
*
* <p>KeyGenerator objects are reusable, i.e., after a key has been
* generated, the same KeyGenerator object can be re-used to generate further
* keys.
*
* <p>There are two ways to generate a key: in an algorithm-independent
* manner, and in an algorithm-specific manner.
* The only difference between the two is the initialization of the object:
*
* <ul>
* <li><b>Algorithm-Independent Initialization</b>
* <p>All key generators share the concepts of a <i>keysize</i> and a
* <i>source of randomness</i>.
* There is an
* {@link #init(int, java.security.SecureRandom) init}
* method in this KeyGenerator class that takes these two universally
* shared types of arguments. There is also one that takes just a
* {@code keysize} argument, and uses the SecureRandom implementation
* of the highest-priority installed provider as the source of randomness
* (or a system-provided source of randomness if none of the installed
* providers supply a SecureRandom implementation), and one that takes just a
* source of randomness.
*
* <p>Since no other parameters are specified when you call the above
* algorithm-independent {@code init} methods, it is up to the
* provider what to do about the algorithm-specific parameters (if any) to be
* associated with each of the keys.
*
* <li><b>Algorithm-Specific Initialization</b>
* <p>For situations where a set of algorithm-specific parameters already
* exists, there are two
* {@link #init(java.security.spec.AlgorithmParameterSpec) init}
* methods that have an {@code AlgorithmParameterSpec}
* argument. One also has a {@code SecureRandom} argument, while the
* other uses the SecureRandom implementation
* of the highest-priority installed provider as the source of randomness
* (or a system-provided source of randomness if none of the installed
* providers supply a SecureRandom implementation).
* </ul>
*
* <p>In case the client does not explicitly initialize the KeyGenerator
* (via a call to an {@code init} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.
* Additionally, the default value for a provider may change in a future
* version. Therefore, it is recommended to explicitly initialize the
* KeyGenerator instead of relying on provider-specific defaults.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code KeyGenerator} algorithms with the keysizes in
* parentheses:
* <ul>
* <li>{@code AES} (128)</li>
* <li>{@code DES} (56)</li>
* <li>{@code DESede} (168)</li>
* <li>{@code HmacSHA1}</li>
* <li>{@code HmacSHA256}</li>
* </ul>
* These algorithms are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keygenerator-algorithms">
* KeyGenerator section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Jan Luehe
*
* @see SecretKey
* @since 1.4
*/
public class KeyGenerator {
private static final Debug pdebug =
Debug.getInstance("provider", "Provider");
private static final boolean skipDebug =
Debug.isOn("engine=") && !Debug.isOn("keygenerator");
// see java.security.KeyPairGenerator for failover notes
private static final int I_NONE = 1;
private static final int I_RANDOM = 2;
private static final int I_PARAMS = 3;
private static final int I_SIZE = 4;
// The provider
private Provider provider;
// The provider implementation (delegate)
private volatile KeyGeneratorSpi spi;
// The algorithm
private final String algorithm;
private final Object lock = new Object();
private Iterator<Service> serviceIterator;
private int initType;
private int initKeySize;
private AlgorithmParameterSpec initParams;
private SecureRandom initRandom;
/**
* Creates a KeyGenerator object.
*
* @param keyGenSpi the delegate
* @param provider the provider
* @param algorithm the algorithm
*/
protected KeyGenerator(KeyGeneratorSpi keyGenSpi, Provider provider,
String algorithm) {
this.spi = keyGenSpi;
this.provider = provider;
this.algorithm = algorithm;
if (!skipDebug && pdebug != null) {
pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
getProviderName());
}
}
private KeyGenerator(String algorithm) throws NoSuchAlgorithmException {
this.algorithm = algorithm;
List<Service> list =
GetInstance.getServices("KeyGenerator", algorithm);
serviceIterator = list.iterator();
initType = I_NONE;
// fetch and instantiate initial spi
if (nextSpi(null, false) == null) {
throw new NoSuchAlgorithmException
(algorithm + " KeyGenerator not available");
}
if (!skipDebug && pdebug != null) {
pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
getProviderName());
}
}
private String getProviderName() {
return (provider == null) ? "(no provider)" : provider.getName();
}
/**
* Returns the algorithm name of this {@code KeyGenerator} object.
*
* <p>This is the same name that was specified in one of the
* {@code getInstance} calls that created this
* {@code KeyGenerator} object.
*
* @return the algorithm name of this {@code KeyGenerator} object.
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns a {@code KeyGenerator} object that generates secret keys
* for the specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new KeyGenerator object encapsulating the
* KeyGeneratorSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard name of the requested key algorithm.
* See the KeyGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keygenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new {@code KeyGenerator} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code KeyGeneratorSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
return new KeyGenerator(algorithm);
}
/**
* Returns a {@code KeyGenerator} object that generates secret keys
* for the specified algorithm.
*
* <p> A new KeyGenerator object encapsulating the
* KeyGeneratorSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested key algorithm.
* See the KeyGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keygenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new {@code KeyGenerator} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code KeyGeneratorSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyGenerator getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("KeyGenerator",
KeyGeneratorSpi.class, algorithm, provider);
return new KeyGenerator((KeyGeneratorSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a {@code KeyGenerator} object that generates secret keys
* for the specified algorithm.
*
* <p> A new KeyGenerator object encapsulating the
* KeyGeneratorSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested key algorithm.
* See the KeyGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keygenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return the new {@code KeyGenerator} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null}
*
* @throws NoSuchAlgorithmException if a {@code KeyGeneratorSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyGenerator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("KeyGenerator",
KeyGeneratorSpi.class, algorithm, provider);
return new KeyGenerator((KeyGeneratorSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the provider of this {@code KeyGenerator} object.
*
* @return the provider of this {@code KeyGenerator} object
*/
public final Provider getProvider() {
synchronized (lock) {
disableFailover();
return provider;
}
}
/**
* Update the active spi of this class and return the next
* implementation for failover. If no more implementations are
* available, this method returns null. However, the active spi of
* this class is never set to null.
*/
private KeyGeneratorSpi nextSpi(KeyGeneratorSpi oldSpi,
boolean reinit) {
synchronized (lock) {
// somebody else did a failover concurrently
// try that spi now
if ((oldSpi != null) && (oldSpi != spi)) {
return spi;
}
if (serviceIterator == null) {
return null;
}
while (serviceIterator.hasNext()) {
Service s = serviceIterator.next();
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
try {
Object inst = s.newInstance(null);
// ignore non-spis
if (inst instanceof KeyGeneratorSpi == false) {
continue;
}
KeyGeneratorSpi spi = (KeyGeneratorSpi)inst;
if (reinit) {
if (initType == I_SIZE) {
spi.engineInit(initKeySize, initRandom);
} else if (initType == I_PARAMS) {
spi.engineInit(initParams, initRandom);
} else if (initType == I_RANDOM) {
spi.engineInit(initRandom);
} else if (initType != I_NONE) {
throw new AssertionError
("KeyGenerator initType: " + initType);
}
}
provider = s.getProvider();
this.spi = spi;
return spi;
} catch (Exception e) {
// ignore
}
}
disableFailover();
return null;
}
}
void disableFailover() {
serviceIterator = null;
initType = 0;
initParams = null;
initRandom = null;
}
/**
* Initializes this key generator.
*
* @param random the source of randomness for this generator
*/
public final void init(SecureRandom random) {
if (serviceIterator == null) {
spi.engineInit(random);
return;
}
RuntimeException failure = null;
KeyGeneratorSpi mySpi = spi;
do {
try {
mySpi.engineInit(random);
initType = I_RANDOM;
initKeySize = 0;
initParams = null;
initRandom = random;
return;
} catch (RuntimeException e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi, false);
}
} while (mySpi != null);
throw failure;
}
/**
* Initializes this key generator with the specified parameter set.
*
* <p> If this key generator requires any random bytes, it will get them
* using the
* {@link java.security.SecureRandom}
* implementation of the highest-priority installed
* provider as the source of randomness.
* (If none of the installed providers supply an implementation of
* SecureRandom, a system-provided source of randomness will be used.)
*
* @param params the key generation parameters
*
* @exception InvalidAlgorithmParameterException if the given parameters
* are inappropriate for this key generator
*/
public final void init(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
{
init(params, JceSecurity.RANDOM);
}
/**
* Initializes this key generator with the specified parameter
* set and a user-provided source of randomness.
*
* @param params the key generation parameters
* @param random the source of randomness for this key generator
*
* @exception InvalidAlgorithmParameterException if {@code params} is
* inappropriate for this key generator
*/
public final void init(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException
{
if (serviceIterator == null) {
spi.engineInit(params, random);
return;
}
Exception failure = null;
KeyGeneratorSpi mySpi = spi;
do {
try {
mySpi.engineInit(params, random);
initType = I_PARAMS;
initKeySize = 0;
initParams = params;
initRandom = random;
return;
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi, false);
}
} while (mySpi != null);
if (failure instanceof InvalidAlgorithmParameterException) {
throw (InvalidAlgorithmParameterException)failure;
}
if (failure instanceof RuntimeException) {
throw (RuntimeException)failure;
}
throw new InvalidAlgorithmParameterException("init() failed", failure);
}
/**
* Initializes this key generator for a certain keysize.
*
* <p> If this key generator requires any random bytes, it will get them
* using the
* {@link java.security.SecureRandom}
* implementation of the highest-priority installed
* provider as the source of randomness.
* (If none of the installed providers supply an implementation of
* SecureRandom, a system-provided source of randomness will be used.)
*
* @param keysize the keysize. This is an algorithm-specific metric,
* specified in number of bits.
*
* @exception InvalidParameterException if the keysize is wrong or not
* supported.
*/
public final void init(int keysize) {
init(keysize, JceSecurity.RANDOM);
}
/**
* Initializes this key generator for a certain keysize, using a
* user-provided source of randomness.
*
* @param keysize the keysize. This is an algorithm-specific metric,
* specified in number of bits.
* @param random the source of randomness for this key generator
*
* @exception InvalidParameterException if the keysize is wrong or not
* supported.
*/
public final void init(int keysize, SecureRandom random) {
if (serviceIterator == null) {
spi.engineInit(keysize, random);
return;
}
RuntimeException failure = null;
KeyGeneratorSpi mySpi = spi;
do {
try {
mySpi.engineInit(keysize, random);
initType = I_SIZE;
initKeySize = keysize;
initParams = null;
initRandom = random;
return;
} catch (RuntimeException e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi, false);
}
} while (mySpi != null);
throw failure;
}
/**
* Generates a secret key.
*
* @return the new key
*/
public final SecretKey generateKey() {
if (serviceIterator == null) {
return spi.engineGenerateKey();
}
RuntimeException failure = null;
KeyGeneratorSpi mySpi = spi;
do {
try {
return mySpi.engineGenerateKey();
} catch (RuntimeException e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi, true);
}
} while (mySpi != null);
throw failure;
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 1997, 2017, 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 javax.crypto;
import java.security.*;
import java.security.spec.*;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>KeyGenerator</code> class.
* All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a key generator for a particular algorithm.
*
* <p>In case the client does not explicitly initialize the KeyGenerator
* (via a call to an {@code init} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.
* Additionally, the default value for a provider may change in a future
* version. Therefore, it is recommended to explicitly initialize the
* KeyGenerator instead of relying on provider-specific defaults.
*
* @author Jan Luehe
*
* @see SecretKey
* @since 1.4
*/
public abstract class KeyGeneratorSpi {
/**
* Initializes the key generator.
*
* @param random the source of randomness for this generator
*/
protected abstract void engineInit(SecureRandom random);
/**
* Initializes the key generator with the specified parameter
* set and a user-provided source of randomness.
*
* @param params the key generation parameters
* @param random the source of randomness for this key generator
*
* @exception InvalidAlgorithmParameterException if <code>params</code> is
* inappropriate for this key generator
*/
protected abstract void engineInit(AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidAlgorithmParameterException;
/**
* Initializes this key generator for a certain keysize, using the given
* source of randomness.
*
* @param keysize the keysize. This is an algorithm-specific metric,
* specified in number of bits.
* @param random the source of randomness for this key generator
*
* @exception InvalidParameterException if the keysize is wrong or not
* supported.
*/
protected abstract void engineInit(int keysize, SecureRandom random);
/**
* Generates a secret key.
*
* @return the new key
*/
protected abstract SecretKey engineGenerateKey();
}

View file

@ -0,0 +1,692 @@
/*
* Copyright (c) 1998, 2017, 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 javax.crypto;
import java.util.*;
import java.security.*;
import java.security.Provider.Service;
import java.security.spec.AlgorithmParameterSpec;
import java.nio.ByteBuffer;
import sun.security.util.Debug;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* This class provides the functionality of a "Message Authentication Code"
* (MAC) algorithm.
*
* <p> A MAC provides a way to check
* the integrity of information transmitted over or stored in an unreliable
* medium, based on a secret key. Typically, message
* authentication codes are used between two parties that share a secret
* key in order to validate information transmitted between these
* parties.
*
* <p> A MAC mechanism that is based on cryptographic hash functions is
* referred to as HMAC. HMAC can be used with any cryptographic hash function,
* e.g., SHA256 or SHA384, in combination with a secret shared key. HMAC is
* specified in RFC 2104.
*
* <p> Every implementation of the Java platform is required to support
* the following standard {@code Mac} algorithms:
* <ul>
* <li>{@code HmacMD5}</li>
* <li>{@code HmacSHA1}</li>
* <li>{@code HmacSHA256}</li>
* </ul>
* These algorithms are described in the
* <a href="{@docRoot}/../specs/security/standard-names.html#mac-algorithms">
* Mac section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class Mac implements Cloneable {
private static final Debug debug =
Debug.getInstance("jca", "Mac");
private static final Debug pdebug =
Debug.getInstance("provider", "Provider");
private static final boolean skipDebug =
Debug.isOn("engine=") && !Debug.isOn("mac");
// The provider
private Provider provider;
// The provider implementation (delegate)
private MacSpi spi;
// The name of the MAC algorithm.
private final String algorithm;
// Has this object been initialized?
private boolean initialized = false;
// next service to try in provider selection
// null once provider is selected
private Service firstService;
// remaining services to try in provider selection
// null once provider is selected
private Iterator<Service> serviceIterator;
private final Object lock;
/**
* Creates a MAC object.
*
* @param macSpi the delegate
* @param provider the provider
* @param algorithm the algorithm
*/
protected Mac(MacSpi macSpi, Provider provider, String algorithm) {
this.spi = macSpi;
this.provider = provider;
this.algorithm = algorithm;
serviceIterator = null;
lock = null;
}
private Mac(Service s, Iterator<Service> t, String algorithm) {
firstService = s;
serviceIterator = t;
this.algorithm = algorithm;
lock = new Object();
}
/**
* Returns the algorithm name of this {@code Mac} object.
*
* <p>This is the same name that was specified in one of the
* {@code getInstance} calls that created this
* {@code Mac} object.
*
* @return the algorithm name of this {@code Mac} object.
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns a {@code Mac} object that implements the
* specified MAC algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new Mac object encapsulating the
* MacSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard name of the requested MAC algorithm.
* See the Mac section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#mac-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new {@code Mac} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code MacSpi} implementation for the specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final Mac getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
List<Service> services = GetInstance.getServices("Mac", algorithm);
// make sure there is at least one service from a signed provider
Iterator<Service> t = services.iterator();
while (t.hasNext()) {
Service s = t.next();
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
return new Mac(s, t, algorithm);
}
throw new NoSuchAlgorithmException
("Algorithm " + algorithm + " not available");
}
/**
* Returns a {@code Mac} object that implements the
* specified MAC algorithm.
*
* <p> A new Mac object encapsulating the
* MacSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested MAC algorithm.
* See the Mac section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#mac-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new {@code Mac} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code MacSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final Mac getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("Mac", MacSpi.class, algorithm, provider);
return new Mac((MacSpi)instance.impl, instance.provider, algorithm);
}
/**
* Returns a {@code Mac} object that implements the
* specified MAC algorithm.
*
* <p> A new Mac object encapsulating the
* MacSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested MAC algorithm.
* See the Mac section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#mac-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return the new {@code Mac} object
*
* @throws IllegalArgumentException if the {@code provider} is
* {@code null}
*
* @throws NoSuchAlgorithmException if a {@code MacSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final Mac getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance
("Mac", MacSpi.class, algorithm, provider);
return new Mac((MacSpi)instance.impl, instance.provider, algorithm);
}
// max number of debug warnings to print from chooseFirstProvider()
private static int warnCount = 10;
/**
* Choose the Spi from the first provider available. Used if
* delayed provider selection is not possible because init()
* is not the first method called.
*/
void chooseFirstProvider() {
if ((spi != null) || (serviceIterator == null)) {
return;
}
synchronized (lock) {
if (spi != null) {
return;
}
if (debug != null) {
int w = --warnCount;
if (w >= 0) {
debug.println("Mac.init() not first method "
+ "called, disabling delayed provider selection");
if (w == 0) {
debug.println("Further warnings of this type will "
+ "be suppressed");
}
new Exception("Call trace").printStackTrace();
}
}
Exception lastException = null;
while ((firstService != null) || serviceIterator.hasNext()) {
Service s;
if (firstService != null) {
s = firstService;
firstService = null;
} else {
s = serviceIterator.next();
}
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
try {
Object obj = s.newInstance(null);
if (obj instanceof MacSpi == false) {
continue;
}
spi = (MacSpi)obj;
provider = s.getProvider();
// not needed any more
firstService = null;
serviceIterator = null;
return;
} catch (NoSuchAlgorithmException e) {
lastException = e;
}
}
ProviderException e = new ProviderException
("Could not construct MacSpi instance");
if (lastException != null) {
e.initCause(lastException);
}
throw e;
}
}
private void chooseProvider(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException {
synchronized (lock) {
if (spi != null) {
spi.engineInit(key, params);
return;
}
Exception lastException = null;
while ((firstService != null) || serviceIterator.hasNext()) {
Service s;
if (firstService != null) {
s = firstService;
firstService = null;
} else {
s = serviceIterator.next();
}
// if provider says it does not support this key, ignore it
if (s.supportsParameter(key) == false) {
continue;
}
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
try {
MacSpi spi = (MacSpi)s.newInstance(null);
spi.engineInit(key, params);
provider = s.getProvider();
this.spi = spi;
firstService = null;
serviceIterator = null;
return;
} catch (Exception e) {
// NoSuchAlgorithmException from newInstance()
// InvalidKeyException from init()
// RuntimeException (ProviderException) from init()
if (lastException == null) {
lastException = e;
}
}
}
// no working provider found, fail
if (lastException instanceof InvalidKeyException) {
throw (InvalidKeyException)lastException;
}
if (lastException instanceof InvalidAlgorithmParameterException) {
throw (InvalidAlgorithmParameterException)lastException;
}
if (lastException instanceof RuntimeException) {
throw (RuntimeException)lastException;
}
String kName = (key != null) ? key.getClass().getName() : "(null)";
throw new InvalidKeyException
("No installed provider supports this key: "
+ kName, lastException);
}
}
/**
* Returns the provider of this {@code Mac} object.
*
* @return the provider of this {@code Mac} object.
*/
public final Provider getProvider() {
chooseFirstProvider();
return this.provider;
}
/**
* Returns the length of the MAC in bytes.
*
* @return the MAC length in bytes.
*/
public final int getMacLength() {
chooseFirstProvider();
return spi.engineGetMacLength();
}
private String getProviderName() {
return (provider == null) ? "(no provider)" : provider.getName();
}
/**
* Initializes this {@code Mac} object with the given key.
*
* @param key the key.
*
* @exception InvalidKeyException if the given key is inappropriate for
* initializing this MAC.
*/
public final void init(Key key) throws InvalidKeyException {
try {
if (spi != null) {
spi.engineInit(key, null);
} else {
chooseProvider(key, null);
}
} catch (InvalidAlgorithmParameterException e) {
throw new InvalidKeyException("init() failed", e);
}
initialized = true;
if (!skipDebug && pdebug != null) {
pdebug.println("Mac." + algorithm + " algorithm from: " +
getProviderName());
}
}
/**
* Initializes this {@code Mac} object with the given key and
* algorithm parameters.
*
* @param key the key.
* @param params the algorithm parameters.
*
* @exception InvalidKeyException if the given key is inappropriate for
* initializing this MAC.
* @exception InvalidAlgorithmParameterException if the given algorithm
* parameters are inappropriate for this MAC.
*/
public final void init(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException {
if (spi != null) {
spi.engineInit(key, params);
} else {
chooseProvider(key, params);
}
initialized = true;
if (!skipDebug && pdebug != null) {
pdebug.println("Mac." + algorithm + " algorithm from: " +
getProviderName());
}
}
/**
* Processes the given byte.
*
* @param input the input byte to be processed.
*
* @exception IllegalStateException if this {@code Mac} has not been
* initialized.
*/
public final void update(byte input) throws IllegalStateException {
chooseFirstProvider();
if (initialized == false) {
throw new IllegalStateException("MAC not initialized");
}
spi.engineUpdate(input);
}
/**
* Processes the given array of bytes.
*
* @param input the array of bytes to be processed.
*
* @exception IllegalStateException if this {@code Mac} has not been
* initialized.
*/
public final void update(byte[] input) throws IllegalStateException {
chooseFirstProvider();
if (initialized == false) {
throw new IllegalStateException("MAC not initialized");
}
if (input != null) {
spi.engineUpdate(input, 0, input.length);
}
}
/**
* Processes the first {@code len} bytes in {@code input},
* starting at {@code offset} inclusive.
*
* @param input the input buffer.
* @param offset the offset in {@code input} where the input starts.
* @param len the number of bytes to process.
*
* @exception IllegalStateException if this {@code Mac} has not been
* initialized.
*/
public final void update(byte[] input, int offset, int len)
throws IllegalStateException {
chooseFirstProvider();
if (initialized == false) {
throw new IllegalStateException("MAC not initialized");
}
if (input != null) {
if ((offset < 0) || (len > (input.length - offset)) || (len < 0))
throw new IllegalArgumentException("Bad arguments");
spi.engineUpdate(input, offset, len);
}
}
/**
* Processes {@code input.remaining()} bytes in the ByteBuffer
* {@code input}, starting at {@code input.position()}.
* Upon return, the buffer's position will be equal to its limit;
* its limit will not have changed.
*
* @param input the ByteBuffer
*
* @exception IllegalStateException if this {@code Mac} has not been
* initialized.
* @since 1.5
*/
public final void update(ByteBuffer input) {
chooseFirstProvider();
if (initialized == false) {
throw new IllegalStateException("MAC not initialized");
}
if (input == null) {
throw new IllegalArgumentException("Buffer must not be null");
}
spi.engineUpdate(input);
}
/**
* Finishes the MAC operation.
*
* <p>A call to this method resets this {@code Mac} object to the
* state it was in when previously initialized via a call to
* {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
* That is, the object is reset and available to generate another MAC from
* the same key, if desired, via new calls to {@code update} and
* {@code doFinal}.
* (In order to reuse this {@code Mac} object with a different key,
* it must be reinitialized via a call to {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
*
* @return the MAC result.
*
* @exception IllegalStateException if this {@code Mac} has not been
* initialized.
*/
public final byte[] doFinal() throws IllegalStateException {
chooseFirstProvider();
if (initialized == false) {
throw new IllegalStateException("MAC not initialized");
}
byte[] mac = spi.engineDoFinal();
spi.engineReset();
return mac;
}
/**
* Finishes the MAC operation.
*
* <p>A call to this method resets this {@code Mac} object to the
* state it was in when previously initialized via a call to
* {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
* That is, the object is reset and available to generate another MAC from
* the same key, if desired, via new calls to {@code update} and
* {@code doFinal}.
* (In order to reuse this {@code Mac} object with a different key,
* it must be reinitialized via a call to {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
*
* <p>The MAC result is stored in {@code output}, starting at
* {@code outOffset} inclusive.
*
* @param output the buffer where the MAC result is stored
* @param outOffset the offset in {@code output} where the MAC is
* stored
*
* @exception ShortBufferException if the given output buffer is too small
* to hold the result
* @exception IllegalStateException if this {@code Mac} has not been
* initialized.
*/
public final void doFinal(byte[] output, int outOffset)
throws ShortBufferException, IllegalStateException
{
chooseFirstProvider();
if (initialized == false) {
throw new IllegalStateException("MAC not initialized");
}
int macLen = getMacLength();
if (output == null || output.length-outOffset < macLen) {
throw new ShortBufferException
("Cannot store MAC in output buffer");
}
byte[] mac = doFinal();
System.arraycopy(mac, 0, output, outOffset, macLen);
return;
}
/**
* Processes the given array of bytes and finishes the MAC operation.
*
* <p>A call to this method resets this {@code Mac} object to the
* state it was in when previously initialized via a call to
* {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
* That is, the object is reset and available to generate another MAC from
* the same key, if desired, via new calls to {@code update} and
* {@code doFinal}.
* (In order to reuse this {@code Mac} object with a different key,
* it must be reinitialized via a call to {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
*
* @param input data in bytes
* @return the MAC result.
*
* @exception IllegalStateException if this {@code Mac} has not been
* initialized.
*/
public final byte[] doFinal(byte[] input) throws IllegalStateException
{
chooseFirstProvider();
if (initialized == false) {
throw new IllegalStateException("MAC not initialized");
}
update(input);
return doFinal();
}
/**
* Resets this {@code Mac} object.
*
* <p>A call to this method resets this {@code Mac} object to the
* state it was in when previously initialized via a call to
* {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
* That is, the object is reset and available to generate another MAC from
* the same key, if desired, via new calls to {@code update} and
* {@code doFinal}.
* (In order to reuse this {@code Mac} object with a different key,
* it must be reinitialized via a call to {@code init(Key)} or
* {@code init(Key, AlgorithmParameterSpec)}.
*/
public final void reset() {
chooseFirstProvider();
spi.engineReset();
}
/**
* Returns a clone if the provider implementation is cloneable.
*
* @return a clone if the provider implementation is cloneable.
*
* @exception CloneNotSupportedException if this is called on a
* delegate that does not support {@code Cloneable}.
*/
public final Object clone() throws CloneNotSupportedException {
chooseFirstProvider();
Mac that = (Mac)super.clone();
that.spi = (MacSpi)this.spi.clone();
return that;
}
}

View file

@ -0,0 +1,153 @@
/*
* Copyright (c) 1998, 2007, 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 javax.crypto;
import java.security.*;
import java.security.spec.*;
import java.nio.ByteBuffer;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>Mac</code> class.
* All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a particular MAC algorithm.
*
* <p> Implementations are free to implement the Cloneable interface.
*
* @author Jan Luehe
*
* @since 1.4
*/
public abstract class MacSpi {
/**
* Returns the length of the MAC in bytes.
*
* @return the MAC length in bytes.
*/
protected abstract int engineGetMacLength();
/**
* Initializes the MAC with the given (secret) key and algorithm
* parameters.
*
* @param key the (secret) key.
* @param params the algorithm parameters.
*
* @exception InvalidKeyException if the given key is inappropriate for
* initializing this MAC.
* @exception InvalidAlgorithmParameterException if the given algorithm
* parameters are inappropriate for this MAC.
*/
protected abstract void engineInit(Key key,
AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException ;
/**
* Processes the given byte.
*
* @param input the input byte to be processed.
*/
protected abstract void engineUpdate(byte input);
/**
* Processes the first <code>len</code> bytes in <code>input</code>,
* starting at <code>offset</code> inclusive.
*
* @param input the input buffer.
* @param offset the offset in <code>input</code> where the input starts.
* @param len the number of bytes to process.
*/
protected abstract void engineUpdate(byte[] input, int offset, int len);
/**
* Processes <code>input.remaining()</code> bytes in the ByteBuffer
* <code>input</code>, starting at <code>input.position()</code>.
* Upon return, the buffer's position will be equal to its limit;
* its limit will not have changed.
*
* <p>Subclasses should consider overriding this method if they can
* process ByteBuffers more efficiently than byte arrays.
*
* @param input the ByteBuffer
* @since 1.5
*/
protected void engineUpdate(ByteBuffer input) {
if (input.hasRemaining() == false) {
return;
}
if (input.hasArray()) {
byte[] b = input.array();
int ofs = input.arrayOffset();
int pos = input.position();
int lim = input.limit();
engineUpdate(b, ofs + pos, lim - pos);
input.position(lim);
} else {
int len = input.remaining();
byte[] b = new byte[CipherSpi.getTempArraySize(len)];
while (len > 0) {
int chunk = Math.min(len, b.length);
input.get(b, 0, chunk);
engineUpdate(b, 0, chunk);
len -= chunk;
}
}
}
/**
* Completes the MAC computation and resets the MAC for further use,
* maintaining the secret key that the MAC was initialized with.
*
* @return the MAC result.
*/
protected abstract byte[] engineDoFinal();
/**
* Resets the MAC for further use, maintaining the secret key that the
* MAC was initialized with.
*/
protected abstract void engineReset();
/**
* Returns a clone if the implementation is cloneable.
*
* @return a clone if the implementation is cloneable.
*
* @exception CloneNotSupportedException if this is called
* on an implementation that does not support <code>Cloneable</code>.
*/
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
} else {
throw new CloneNotSupportedException();
}
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto;
import java.security.GeneralSecurityException;
/**
* This exception is thrown when a particular padding mechanism is
* requested but is not available in the environment.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class NoSuchPaddingException extends GeneralSecurityException {
private static final long serialVersionUID = -4572885201200175466L;
/**
* Constructs a NoSuchPaddingException with no detail
* message. A detail message is a String that describes this
* particular exception.
*/
public NoSuchPaddingException() {
super();
}
/**
* Constructs a NoSuchPaddingException with the specified
* detail message.
*
* @param msg the detail message.
*/
public NoSuchPaddingException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 1997, 2013, 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 javax.crypto;
/**
* The NullCipher class is a class that provides an
* "identity cipher" -- one that does not transform the plain text. As
* a consequence, the ciphertext is identical to the plaintext. All
* initialization methods do nothing, while the blocksize is set to 1
* byte.
*
* @author Li Gong
* @since 1.4
*/
public class NullCipher extends Cipher {
/**
* Creates a NullCipher object.
*/
public NullCipher() {
super(new NullCipherSpi(), null);
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 1997, 2013, 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 javax.crypto;
import java.security.*;
import java.security.spec.*;
/**
* This class provides a delegate for the identity cipher - one that does not
* transform the plain text.
*
* @author Li Gong
* @see NullCipher
*
* @since 1.4
*/
final class NullCipherSpi extends CipherSpi {
/*
* Do not let anybody instantiate this directly (protected).
*/
protected NullCipherSpi() {}
public void engineSetMode(String mode) {}
public void engineSetPadding(String padding) {}
protected int engineGetBlockSize() {
return 1;
}
protected int engineGetOutputSize(int inputLen) {
return inputLen;
}
protected byte[] engineGetIV() {
byte[] x = new byte[8];
return x;
}
protected AlgorithmParameters engineGetParameters() {
return null;
}
protected void engineInit(int mode, Key key, SecureRandom random) {}
protected void engineInit(int mode, Key key,
AlgorithmParameterSpec params,
SecureRandom random) {}
protected void engineInit(int mode, Key key,
AlgorithmParameters params,
SecureRandom random) {}
protected byte[] engineUpdate(byte[] input, int inputOffset,
int inputLen) {
if (input == null) return null;
byte[] x = new byte[inputLen];
System.arraycopy(input, inputOffset, x, 0, inputLen);
return x;
}
protected int engineUpdate(byte[] input, int inputOffset,
int inputLen, byte[] output,
int outputOffset) {
if (input == null) return 0;
System.arraycopy(input, inputOffset, output, outputOffset, inputLen);
return inputLen;
}
protected byte[] engineDoFinal(byte[] input, int inputOffset,
int inputLen)
{
return engineUpdate(input, inputOffset, inputLen);
}
protected int engineDoFinal(byte[] input, int inputOffset,
int inputLen, byte[] output,
int outputOffset)
{
return engineUpdate(input, inputOffset, inputLen,
output, outputOffset);
}
protected int engineGetKeySize(Key key)
{
return 0;
}
}

View file

@ -0,0 +1,177 @@
/*
* Copyright (c) 2007, 2014, 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 javax.crypto;
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.jar.*;
/**
* This class verifies Provider/Policy resources found at a URL
* (currently only JAR files and any supporting JAR files), and
* determines whether they may be used in this implementation.
*
* The JCE in OpenJDK has an open cryptographic interface, meaning it
* does not restrict which providers can be used. Compliance with
* United States export controls and with local law governing the
* import/export of products incorporating the JCE in the OpenJDK is
* the responsibility of the licensee.
*
* @since 1.7
*/
final class ProviderVerifier {
// The URL for the JAR file we want to verify.
private URL jarURL;
private Provider provider;
private boolean savePerms;
private CryptoPermissions appPerms = null;
/**
* Creates a ProviderVerifier object to verify the given URL.
*
* @param jarURL the JAR file to be verified.
* @param savePerms if true, save the permissions allowed by the
* exemption mechanism
*/
ProviderVerifier(URL jarURL, boolean savePerms) {
this(jarURL, null, savePerms);
}
/**
* Creates a ProviderVerifier object to verify the given URL.
*
* @param jarURL the JAR file to be verified
* @param provider the corresponding provider.
* @param savePerms if true, save the permissions allowed by the
* exemption mechanism
*/
ProviderVerifier(URL jarURL, Provider provider, boolean savePerms) {
this.jarURL = jarURL;
this.provider = provider;
this.savePerms = savePerms;
}
/**
* Verify the JAR file is signed by an entity which has a certificate
* issued by a trusted CA.
*
* In OpenJDK, we just need to examine the "cryptoperms" file to see
* if any permissions were bundled together with this jar file.
*/
void verify() throws IOException {
// Short-circuit. If we weren't asked to save any, we're done.
if (!savePerms) {
return;
}
// If the protocol of jarURL isn't "jar", we should
// construct a JAR URL so we can open a JarURLConnection
// for verifying this provider.
final URL url = jarURL.getProtocol().equalsIgnoreCase("jar")?
jarURL : new URL("jar:" + jarURL.toString() + "!/");
JarFile jf = null;
try {
// Get a link to the Jarfile to search.
try {
jf = AccessController.doPrivileged(
new PrivilegedExceptionAction<JarFile>() {
public JarFile run() throws Exception {
JarURLConnection conn =
(JarURLConnection) url.openConnection();
// You could do some caching here as
// an optimization.
conn.setUseCaches(false);
return conn.getJarFile();
}
});
} catch (java.security.PrivilegedActionException pae) {
throw new SecurityException("Cannot load " + url.toString(),
pae.getCause());
}
if (jf != null) {
JarEntry je = jf.getJarEntry("cryptoPerms");
if (je == null) {
throw new JarException(
"Can not find cryptoPerms");
}
try {
appPerms = new CryptoPermissions();
appPerms.load(jf.getInputStream(je));
} catch (Exception ex) {
JarException jex =
new JarException("Cannot load/parse" +
jarURL.toString());
jex.initCause(ex);
throw jex;
}
}
} finally {
// Only call close() when caching is not enabled.
// Otherwise, exceptions will be thrown for all
// subsequent accesses of this cached jar.
if (jf != null) {
jf.close();
}
}
}
/**
* Verify that the provided certs include the
* framework signing certificate.
*
* @param certs the list of certs to be checked.
* @throws Exception if the list of certs did not contain
* the framework signing certificate
*/
static void verifyPolicySigned(java.security.cert.Certificate[] certs)
throws Exception {
}
/**
* Returns true if the given provider is JDK trusted crypto provider
* if the implementation supports fast-path verification.
*/
static boolean isTrustedCryptoProvider(Provider provider) {
return false;
}
/**
* Returns the permissions which are bundled with the JAR file,
* aka the "cryptoperms" file.
*
* NOTE: if this ProviderVerifier instance is constructed with "savePerms"
* equal to false, then this method would always return null.
*/
CryptoPermissions getPermissions() {
return appPerms;
}
}

View file

@ -0,0 +1,487 @@
/*
* Copyright (c) 1997, 2017, 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 javax.crypto;
import java.io.*;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
/**
* This class enables a programmer to create an object and protect its
* confidentiality with a cryptographic algorithm.
*
* <p> Given any Serializable object, one can create a SealedObject
* that encapsulates the original object, in serialized
* format (i.e., a "deep copy"), and seals (encrypts) its serialized contents,
* using a cryptographic algorithm such as AES, to protect its
* confidentiality. The encrypted content can later be decrypted (with
* the corresponding algorithm using the correct decryption key) and
* de-serialized, yielding the original object.
*
* <p> Note that the Cipher object must be fully initialized with the
* correct algorithm, key, padding scheme, etc., before being applied
* to a SealedObject.
*
* <p> The original object that was sealed can be recovered in two different
* ways:
*
* <ul>
*
* <li>by using the {@link #getObject(javax.crypto.Cipher) getObject}
* method that takes a <code>Cipher</code> object.
*
* <p> This method requires a fully initialized <code>Cipher</code> object,
* initialized with the
* exact same algorithm, key, padding scheme, etc., that were used to seal the
* object.
*
* <p> This approach has the advantage that the party who unseals the
* sealed object does not require knowledge of the decryption key. For example,
* after one party has initialized the cipher object with the required
* decryption key, it could hand over the cipher object to
* another party who then unseals the sealed object.
*
* <li>by using one of the
* {@link #getObject(java.security.Key) getObject} methods
* that take a <code>Key</code> object.
*
* <p> In this approach, the <code>getObject</code> method creates a cipher
* object for the appropriate decryption algorithm and initializes it with the
* given decryption key and the algorithm parameters (if any) that were stored
* in the sealed object.
*
* <p> This approach has the advantage that the party who
* unseals the object does not need to keep track of the parameters (e.g., an
* IV) that were used to seal the object.
*
* </ul>
*
* @author Li Gong
* @author Jan Luehe
* @see Cipher
* @since 1.4
*/
public class SealedObject implements Serializable {
static final long serialVersionUID = 4482838265551344752L;
/**
* The serialized object contents in encrypted format.
*
* @serial
*/
private byte[] encryptedContent = null;
/**
* The algorithm that was used to seal this object.
*
* @serial
*/
private String sealAlg = null;
/**
* The algorithm of the parameters used.
*
* @serial
*/
private String paramsAlg = null;
/**
* The cryptographic parameters used by the sealing Cipher,
* encoded in the default format.
* <p>
* That is, <code>cipher.getParameters().getEncoded()</code>.
*
* @serial
*/
protected byte[] encodedParams = null;
/**
* Constructs a SealedObject from any Serializable object.
*
* <p>The given object is serialized, and its serialized contents are
* encrypted using the given Cipher, which must be fully initialized.
*
* <p>Any algorithm parameters that may be used in the encryption
* operation are stored inside of the new <code>SealedObject</code>.
*
* @param object the object to be sealed; can be null.
* @param c the cipher used to seal the object.
*
* @exception NullPointerException if the given cipher is null.
* @exception IOException if an error occurs during serialization
* @exception IllegalBlockSizeException if the given cipher is a block
* cipher, no padding has been requested, and the total input length
* (i.e., the length of the serialized object contents) is not a multiple
* of the cipher's block size
*/
public SealedObject(Serializable object, Cipher c) throws IOException,
IllegalBlockSizeException
{
/*
* Serialize the object
*/
// creating a stream pipe-line, from a to b
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutput a = new ObjectOutputStream(b);
byte[] content;
try {
// write and flush the object content to byte array
a.writeObject(object);
a.flush();
content = b.toByteArray();
} finally {
a.close();
}
/*
* Seal the object
*/
try {
this.encryptedContent = c.doFinal(content);
}
catch (BadPaddingException ex) {
// if sealing is encryption only
// Should never happen??
}
// Save the parameters
if (c.getParameters() != null) {
this.encodedParams = c.getParameters().getEncoded();
this.paramsAlg = c.getParameters().getAlgorithm();
}
// Save the encryption algorithm
this.sealAlg = c.getAlgorithm();
}
/**
* Constructs a SealedObject object from the passed-in SealedObject.
*
* @param so a SealedObject object
* @exception NullPointerException if the given sealed object is null.
*/
protected SealedObject(SealedObject so) {
this.encryptedContent = so.encryptedContent.clone();
this.sealAlg = so.sealAlg;
this.paramsAlg = so.paramsAlg;
if (so.encodedParams != null) {
this.encodedParams = so.encodedParams.clone();
} else {
this.encodedParams = null;
}
}
/**
* Returns the algorithm that was used to seal this object.
*
* @return the algorithm that was used to seal this object.
*/
public final String getAlgorithm() {
return this.sealAlg;
}
/**
* Retrieves the original (encapsulated) object.
*
* <p>This method creates a cipher for the algorithm that had been used in
* the sealing operation.
* If the default provider package provides an implementation of that
* algorithm, an instance of Cipher containing that implementation is used.
* If the algorithm is not available in the default package, other
* packages are searched.
* The Cipher object is initialized for decryption, using the given
* <code>key</code> and the parameters (if any) that had been used in the
* sealing operation.
*
* <p>The encapsulated object is unsealed and de-serialized, before it is
* returned.
*
* @param key the key used to unseal the object.
*
* @return the original object.
*
* @exception IOException if an error occurs during de-serialiazation.
* @exception ClassNotFoundException if an error occurs during
* de-serialiazation.
* @exception NoSuchAlgorithmException if the algorithm to unseal the
* object is not available.
* @exception InvalidKeyException if the given key cannot be used to unseal
* the object (e.g., it has the wrong algorithm).
* @exception NullPointerException if <code>key</code> is null.
*/
public final Object getObject(Key key)
throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
InvalidKeyException
{
if (key == null) {
throw new NullPointerException("key is null");
}
try {
return unseal(key, null);
} catch (NoSuchProviderException nspe) {
// we've already caught NoSuchProviderException's and converted
// them into NoSuchAlgorithmException's with details about
// the failing algorithm
throw new NoSuchAlgorithmException("algorithm not found");
} catch (IllegalBlockSizeException ibse) {
throw new InvalidKeyException(ibse.getMessage());
} catch (BadPaddingException bpe) {
throw new InvalidKeyException(bpe.getMessage());
}
}
/**
* Retrieves the original (encapsulated) object.
*
* <p>The encapsulated object is unsealed (using the given Cipher,
* assuming that the Cipher is already properly initialized) and
* de-serialized, before it is returned.
*
* @param c the cipher used to unseal the object
*
* @return the original object.
*
* @exception NullPointerException if the given cipher is null.
* @exception IOException if an error occurs during de-serialiazation
* @exception ClassNotFoundException if an error occurs during
* de-serialiazation
* @exception IllegalBlockSizeException if the given cipher is a block
* cipher, no padding has been requested, and the total input length is
* not a multiple of the cipher's block size
* @exception BadPaddingException if the given cipher has been
* initialized for decryption, and padding has been specified, but
* the input data does not have proper expected padding bytes
*/
public final Object getObject(Cipher c)
throws IOException, ClassNotFoundException, IllegalBlockSizeException,
BadPaddingException
{
/*
* Unseal the object
*/
byte[] content = c.doFinal(this.encryptedContent);
/*
* De-serialize it
*/
// creating a stream pipe-line, from b to a
ByteArrayInputStream b = new ByteArrayInputStream(content);
ObjectInput a = new extObjectInputStream(b);
try {
Object obj = a.readObject();
return obj;
} finally {
a.close();
}
}
/**
* Retrieves the original (encapsulated) object.
*
* <p>This method creates a cipher for the algorithm that had been used in
* the sealing operation, using an implementation of that algorithm from
* the given <code>provider</code>.
* The Cipher object is initialized for decryption, using the given
* <code>key</code> and the parameters (if any) that had been used in the
* sealing operation.
*
* <p>The encapsulated object is unsealed and de-serialized, before it is
* returned.
*
* @param key the key used to unseal the object.
* @param provider the name of the provider of the algorithm to unseal
* the object.
*
* @return the original object.
*
* @exception IllegalArgumentException if the given provider is null
* or empty.
* @exception IOException if an error occurs during de-serialiazation.
* @exception ClassNotFoundException if an error occurs during
* de-serialiazation.
* @exception NoSuchAlgorithmException if the algorithm to unseal the
* object is not available.
* @exception NoSuchProviderException if the given provider is not
* configured.
* @exception InvalidKeyException if the given key cannot be used to unseal
* the object (e.g., it has the wrong algorithm).
* @exception NullPointerException if <code>key</code> is null.
*/
public final Object getObject(Key key, String provider)
throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException
{
if (key == null) {
throw new NullPointerException("key is null");
}
if (provider == null || provider.length() == 0) {
throw new IllegalArgumentException("missing provider");
}
try {
return unseal(key, provider);
} catch (IllegalBlockSizeException | BadPaddingException ex) {
throw new InvalidKeyException(ex.getMessage());
}
}
private Object unseal(Key key, String provider)
throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException
{
/*
* Create the parameter object.
*/
AlgorithmParameters params = null;
if (this.encodedParams != null) {
try {
if (provider != null)
params = AlgorithmParameters.getInstance(this.paramsAlg,
provider);
else
params = AlgorithmParameters.getInstance(this.paramsAlg);
} catch (NoSuchProviderException nspe) {
if (provider == null) {
throw new NoSuchAlgorithmException(this.paramsAlg
+ " not found");
} else {
throw new NoSuchProviderException(nspe.getMessage());
}
}
params.init(this.encodedParams);
}
/*
* Create and initialize the cipher.
*/
Cipher c;
try {
if (provider != null)
c = Cipher.getInstance(this.sealAlg, provider);
else
c = Cipher.getInstance(this.sealAlg);
} catch (NoSuchPaddingException nspe) {
throw new NoSuchAlgorithmException("Padding that was used in "
+ "sealing operation not "
+ "available");
} catch (NoSuchProviderException nspe) {
if (provider == null) {
throw new NoSuchAlgorithmException(this.sealAlg+" not found");
} else {
throw new NoSuchProviderException(nspe.getMessage());
}
}
try {
if (params != null)
c.init(Cipher.DECRYPT_MODE, key, params);
else
c.init(Cipher.DECRYPT_MODE, key);
} catch (InvalidAlgorithmParameterException iape) {
// this should never happen, because we use the exact same
// parameters that were used in the sealing operation
throw new RuntimeException(iape.getMessage());
}
/*
* Unseal the object
*/
byte[] content = c.doFinal(this.encryptedContent);
/*
* De-serialize it
*/
// creating a stream pipe-line, from b to a
ByteArrayInputStream b = new ByteArrayInputStream(content);
ObjectInput a = new extObjectInputStream(b);
try {
Object obj = a.readObject();
return obj;
} finally {
a.close();
}
}
/**
* Restores the state of the SealedObject from a stream.
* @param s the object input stream.
* @exception NullPointerException if s is null.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException
{
s.defaultReadObject();
if (encryptedContent != null)
encryptedContent = encryptedContent.clone();
if (encodedParams != null)
encodedParams = encodedParams.clone();
}
}
final class extObjectInputStream extends ObjectInputStream {
extObjectInputStream(InputStream in)
throws IOException, StreamCorruptedException {
super(in);
}
protected Class<?> resolveClass(ObjectStreamClass v)
throws IOException, ClassNotFoundException
{
try {
/*
* Calling the super.resolveClass() first
* will let us pick up bug fixes in the super
* class (e.g., 4171142).
*/
return super.resolveClass(v);
} catch (ClassNotFoundException cnfe) {
/*
* This is a workaround for bug 4224921.
*/
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
if (loader == null) {
throw new ClassNotFoundException(v.getName());
}
}
return Class.forName(v.getName(), false, loader);
}
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 1997, 2013, 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 javax.crypto;
/**
* A secret (symmetric) key.
* The purpose of this interface is to group (and provide type safety
* for) all secret key interfaces.
* <p>
* Provider implementations of this interface must overwrite the
* {@code equals} and {@code hashCode} methods inherited from
* {@link java.lang.Object}, so that secret keys are compared based on
* their underlying key material and not based on reference.
* Implementations should override the default {@code destroy} and
* {@code isDestroyed} methods from the
* {@link javax.security.auth.Destroyable} interface to enable
* sensitive key information to be destroyed, cleared, or in the case
* where such information is immutable, unreferenced.
* Finally, since {@code SecretKey} is {@code Serializable}, implementations
* should also override
* {@link java.io.ObjectOutputStream#writeObject(java.lang.Object)}
* to prevent keys that have been destroyed from being serialized.
*
* <p>Keys that implement this interface return the string {@code RAW}
* as their encoding format (see {@code getFormat}), and return the
* raw key bytes as the result of a {@code getEncoded} method call. (The
* {@code getFormat} and {@code getEncoded} methods are inherited
* from the {@link java.security.Key} parent interface.)
*
* @author Jan Luehe
*
* @see SecretKeyFactory
* @see Cipher
* @since 1.4
*/
public interface SecretKey extends
java.security.Key, javax.security.auth.Destroyable {
/**
* The class fingerprint that is set to indicate serialization
* compatibility since J2SE 1.4.
*/
static final long serialVersionUID = -4795878709595146952L;
}

View file

@ -0,0 +1,437 @@
/*
* Copyright (c) 1997, 2017, 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 javax.crypto;
import java.util.*;
import java.security.*;
import java.security.Provider.Service;
import java.security.spec.*;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* This class represents a factory for secret keys.
*
* <P> Key factories are used to convert <I>keys</I> (opaque
* cryptographic keys of type {@code Key}) into <I>key specifications</I>
* (transparent representations of the underlying key material), and vice
* versa.
* Secret key factories operate only on secret (symmetric) keys.
*
* <P> Key factories are bi-directional, i.e., they allow to build an opaque
* key object from a given key specification (key material), or to retrieve
* the underlying key material of a key object in a suitable format.
*
* <P> Application developers should refer to their provider's documentation
* to find out which key specifications are supported by the
* {@link #generateSecret(java.security.spec.KeySpec) generateSecret} and
* {@link #getKeySpec(javax.crypto.SecretKey, java.lang.Class) getKeySpec}
* methods.
* For example, the DES secret-key factory supplied by the "SunJCE" provider
* supports {@code DESKeySpec} as a transparent representation of DES
* keys, and that provider's secret-key factory for Triple DES keys supports
* {@code DESedeKeySpec} as a transparent representation of Triple DES
* keys.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code SecretKeyFactory} algorithms:
* <ul>
* <li>{@code DES}</li>
* <li>{@code DESede}</li>
* </ul>
* These algorithms are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#secretkeyfactory-algorithms">
* SecretKeyFactory section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Jan Luehe
*
* @see SecretKey
* @see javax.crypto.spec.DESKeySpec
* @see javax.crypto.spec.DESedeKeySpec
* @see javax.crypto.spec.PBEKeySpec
* @since 1.4
*/
public class SecretKeyFactory {
// The provider
private Provider provider;
// The algorithm associated with this factory
private final String algorithm;
// The provider implementation (delegate)
private volatile SecretKeyFactorySpi spi;
// lock for mutex during provider selection
private final Object lock = new Object();
// remaining services to try in provider selection
// null once provider is selected
private Iterator<Service> serviceIterator;
/**
* Creates a SecretKeyFactory object.
*
* @param keyFacSpi the delegate
* @param provider the provider
* @param algorithm the secret-key algorithm
*/
protected SecretKeyFactory(SecretKeyFactorySpi keyFacSpi,
Provider provider, String algorithm) {
this.spi = keyFacSpi;
this.provider = provider;
this.algorithm = algorithm;
}
private SecretKeyFactory(String algorithm) throws NoSuchAlgorithmException {
this.algorithm = algorithm;
List<Service> list =
GetInstance.getServices("SecretKeyFactory", algorithm);
serviceIterator = list.iterator();
// fetch and instantiate initial spi
if (nextSpi(null) == null) {
throw new NoSuchAlgorithmException
(algorithm + " SecretKeyFactory not available");
}
}
/**
* Returns a {@code SecretKeyFactory} object that converts
* secret keys of the specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new SecretKeyFactory object encapsulating the
* SecretKeyFactorySpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
* See the SecretKeyFactory section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#secretkeyfactory-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new {@code SecretKeyFactory} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code SecretKeyFactorySpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final SecretKeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
return new SecretKeyFactory(algorithm);
}
/**
* Returns a {@code SecretKeyFactory} object that converts
* secret keys of the specified algorithm.
*
* <p> A new SecretKeyFactory object encapsulating the
* SecretKeyFactorySpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
* See the SecretKeyFactory section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#secretkeyfactory-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new {@code SecretKeyFactory} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code SecretKeyFactorySpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final SecretKeyFactory getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("SecretKeyFactory",
SecretKeyFactorySpi.class, algorithm, provider);
return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a {@code SecretKeyFactory} object that converts
* secret keys of the specified algorithm.
*
* <p> A new SecretKeyFactory object encapsulating the
* SecretKeyFactorySpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested secret-key
* algorithm.
* See the SecretKeyFactory section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#secretkeyfactory-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return the new {@code SecretKeyFactory} object
*
* @throws IllegalArgumentException if the {@code provider}
* is {@code null}
*
* @throws NoSuchAlgorithmException if a {@code SecretKeyFactorySpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final SecretKeyFactory getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = JceSecurity.getInstance("SecretKeyFactory",
SecretKeyFactorySpi.class, algorithm, provider);
return new SecretKeyFactory((SecretKeyFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the provider of this {@code SecretKeyFactory} object.
*
* @return the provider of this {@code SecretKeyFactory} object
*/
public final Provider getProvider() {
synchronized (lock) {
// disable further failover after this call
serviceIterator = null;
return provider;
}
}
/**
* Returns the algorithm name of this {@code SecretKeyFactory} object.
*
* <p>This is the same name that was specified in one of the
* {@code getInstance} calls that created this
* {@code SecretKeyFactory} object.
*
* @return the algorithm name of this {@code SecretKeyFactory}
* object.
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Update the active spi of this class and return the next
* implementation for failover. If no more implemenations are
* available, this method returns null. However, the active spi of
* this class is never set to null.
*/
private SecretKeyFactorySpi nextSpi(SecretKeyFactorySpi oldSpi) {
synchronized (lock) {
// somebody else did a failover concurrently
// try that spi now
if ((oldSpi != null) && (oldSpi != spi)) {
return spi;
}
if (serviceIterator == null) {
return null;
}
while (serviceIterator.hasNext()) {
Service s = serviceIterator.next();
if (JceSecurity.canUseProvider(s.getProvider()) == false) {
continue;
}
try {
Object obj = s.newInstance(null);
if (obj instanceof SecretKeyFactorySpi == false) {
continue;
}
SecretKeyFactorySpi spi = (SecretKeyFactorySpi)obj;
provider = s.getProvider();
this.spi = spi;
return spi;
} catch (NoSuchAlgorithmException e) {
// ignore
}
}
serviceIterator = null;
return null;
}
}
/**
* Generates a {@code SecretKey} object from the provided key
* specification (key material).
*
* @param keySpec the specification (key material) of the secret key
*
* @return the secret key
*
* @exception InvalidKeySpecException if the given key specification
* is inappropriate for this secret-key factory to produce a secret key.
*/
public final SecretKey generateSecret(KeySpec keySpec)
throws InvalidKeySpecException {
if (serviceIterator == null) {
return spi.engineGenerateSecret(keySpec);
}
Exception failure = null;
SecretKeyFactorySpi mySpi = spi;
do {
try {
return mySpi.engineGenerateSecret(keySpec);
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi);
}
} while (mySpi != null);
if (failure instanceof InvalidKeySpecException) {
throw (InvalidKeySpecException)failure;
}
throw new InvalidKeySpecException
("Could not generate secret key", failure);
}
/**
* Returns a specification (key material) of the given key object
* in the requested format.
*
* @param key the key
* @param keySpec the requested format in which the key material shall be
* returned
*
* @return the underlying key specification (key material) in the
* requested format
*
* @exception InvalidKeySpecException if the requested key specification is
* inappropriate for the given key (e.g., the algorithms associated with
* {@code key} and {@code keySpec} do not match, or
* {@code key} references a key on a cryptographic hardware device
* whereas {@code keySpec} is the specification of a software-based
* key), or the given key cannot be dealt with
* (e.g., the given key has an algorithm or format not supported by this
* secret-key factory).
*/
public final KeySpec getKeySpec(SecretKey key, Class<?> keySpec)
throws InvalidKeySpecException {
if (serviceIterator == null) {
return spi.engineGetKeySpec(key, keySpec);
}
Exception failure = null;
SecretKeyFactorySpi mySpi = spi;
do {
try {
return mySpi.engineGetKeySpec(key, keySpec);
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi);
}
} while (mySpi != null);
if (failure instanceof InvalidKeySpecException) {
throw (InvalidKeySpecException)failure;
}
throw new InvalidKeySpecException
("Could not get key spec", failure);
}
/**
* Translates a key object, whose provider may be unknown or potentially
* untrusted, into a corresponding key object of this secret-key factory.
*
* @param key the key whose provider is unknown or untrusted
*
* @return the translated key
*
* @exception InvalidKeyException if the given key cannot be processed
* by this secret-key factory.
*/
public final SecretKey translateKey(SecretKey key)
throws InvalidKeyException {
if (serviceIterator == null) {
return spi.engineTranslateKey(key);
}
Exception failure = null;
SecretKeyFactorySpi mySpi = spi;
do {
try {
return mySpi.engineTranslateKey(key);
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi);
}
} while (mySpi != null);
if (failure instanceof InvalidKeyException) {
throw (InvalidKeyException)failure;
}
throw new InvalidKeyException
("Could not translate key", failure);
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 1997, 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 javax.crypto;
import java.security.*;
import java.security.spec.*;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>SecretKeyFactory</code> class.
* All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a secret-key factory for a particular algorithm.
*
* <P> A provider should document all the key specifications supported by its
* secret key factory.
* For example, the DES secret-key factory supplied by the "SunJCE" provider
* supports <code>DESKeySpec</code> as a transparent representation of DES
* keys, and that provider's secret-key factory for Triple DES keys supports
* <code>DESedeKeySpec</code> as a transparent representation of Triple DES
* keys.
*
* @author Jan Luehe
*
* @see SecretKey
* @see javax.crypto.spec.DESKeySpec
* @see javax.crypto.spec.DESedeKeySpec
* @since 1.4
*/
public abstract class SecretKeyFactorySpi {
/**
* Generates a <code>SecretKey</code> object from the
* provided key specification (key material).
*
* @param keySpec the specification (key material) of the secret key
*
* @return the secret key
*
* @exception InvalidKeySpecException if the given key specification
* is inappropriate for this secret-key factory to produce a secret key.
*/
protected abstract SecretKey engineGenerateSecret(KeySpec keySpec)
throws InvalidKeySpecException;
/**
* Returns a specification (key material) of the given key
* object in the requested format.
*
* @param key the key
*
* @param keySpec the requested format in which the key material shall be
* returned
*
* @return the underlying key specification (key material) in the
* requested format
*
* @exception InvalidKeySpecException if the requested key specification is
* inappropriate for the given key (e.g., the algorithms associated with
* <code>key</code> and <code>keySpec</code> do not match, or
* <code>key</code> references a key on a cryptographic hardware device
* whereas <code>keySpec</code> is the specification of a software-based
* key), or the given key cannot be dealt with
* (e.g., the given key has an algorithm or format not supported by this
* secret-key factory).
*/
protected abstract KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec)
throws InvalidKeySpecException;
/**
* Translates a key object, whose provider may be unknown or
* potentially untrusted, into a corresponding key object of this
* secret-key factory.
*
* @param key the key whose provider is unknown or untrusted
*
* @return the translated key
*
* @exception InvalidKeyException if the given key cannot be processed
* by this secret-key factory.
*/
protected abstract SecretKey engineTranslateKey(SecretKey key)
throws InvalidKeyException;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto;
import java.security.GeneralSecurityException;
/**
* This exception is thrown when an output buffer provided by the user
* is too short to hold the operation result.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class ShortBufferException extends GeneralSecurityException {
private static final long serialVersionUID = 8427718640832943747L;
/**
* Constructs a ShortBufferException with no detail
* message. A detail message is a String that describes this
* particular exception.
*/
public ShortBufferException() {
super();
}
/**
* Constructs a ShortBufferException with the specified
* detail message.
*
* @param msg the detail message.
*/
public ShortBufferException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto.interfaces;
import javax.crypto.spec.DHParameterSpec;
/**
* The interface to a Diffie-Hellman key.
*
* @author Jan Luehe
*
* @see javax.crypto.spec.DHParameterSpec
* @see DHPublicKey
* @see DHPrivateKey
* @since 1.4
*/
public interface DHKey {
/**
* Returns the key parameters.
*
* @return the key parameters
*/
DHParameterSpec getParams();
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto.interfaces;
import java.math.BigInteger;
/**
* The interface to a Diffie-Hellman private key.
*
* @author Jan Luehe
*
* @see DHKey
* @see DHPublicKey
* @since 1.4
*/
public interface DHPrivateKey extends DHKey, java.security.PrivateKey {
/**
* The class fingerprint that is set to indicate serialization
* compatibility since J2SE 1.4.
*/
static final long serialVersionUID = 2211791113380396553L;
/**
* Returns the private value, <code>x</code>.
*
* @return the private value, <code>x</code>
*/
BigInteger getX();
}

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto.interfaces;
import java.math.BigInteger;
/**
* The interface to a Diffie-Hellman public key.
*
* @author Jan Luehe
*
* @see DHKey
* @see DHPrivateKey
* @since 1.4
*/
public interface DHPublicKey extends DHKey, java.security.PublicKey {
/**
* The class fingerprint that is set to indicate serialization
* compatibility since J2SE 1.4.
*/
static final long serialVersionUID = -6628103563352519193L;
/**
* Returns the public value, <code>y</code>.
*
* @return the public value, <code>y</code>
*/
BigInteger getY();
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2001, 2007, 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 javax.crypto.interfaces;
import java.math.BigInteger;
/**
* The interface to a PBE key.
*
* @author Valerie Peng
*
* @see javax.crypto.spec.PBEKeySpec
* @see javax.crypto.SecretKey
* @since 1.4
*/
public interface PBEKey extends javax.crypto.SecretKey {
/**
* The class fingerprint that is set to indicate serialization
* compatibility since J2SE 1.4.
*/
static final long serialVersionUID = -1430015993304333921L;
/**
* Returns the password.
*
* <p> Note: this method should return a copy of the password. It is
* the caller's responsibility to zero out the password information after
* it is no longer needed.
*
* @return the password.
*/
char[] getPassword();
/**
* Returns the salt or null if not specified.
*
* <p> Note: this method should return a copy of the salt. It is
* the caller's responsibility to zero out the salt information after
* it is no longer needed.
*
* @return the salt.
*/
byte[] getSalt();
/**
* Returns the iteration count or 0 if not specified.
*
* @return the iteration count.
*/
int getIterationCount();
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 1999, 2017, 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.
*/
/**
* Provides interfaces for Diffie-Hellman keys as defined in RSA
* Laboratories' PKCS #3.
*
* <P>Note that these interfaces are intended only for key
* implementations whose key material is accessible and
* available. These interfaces are not intended for key implementations
* whose key material resides in inaccessible, protected storage (such
* as in a hardware device).
*
* <P>For more developer information on how to use these interfaces,
* including information on how to design <code>Key</code> classes for
* hardware devices, please refer to the cryptographic provider
* developer guide:
*
* <ul>
* <li> {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
* </ul>
*
* <h2>Package Specification</h2>
*
* <ul>
* <li>PKCS #3: Diffie-Hellman Key-Agreement Standard, Version 1.4,
* November 1993.</li>
* </ul>
*
* <h2>Related Documentation</h2>
*
* For further documentation, please see:
* <ul>
* <li>
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}</li>
* </ul>
*
* @since 1.4
*/
package javax.crypto.interfaces;

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 1999, 2017, 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.
*/
/**
* Provides the classes and interfaces for cryptographic
* operations. The cryptographic operations defined in this package
* include encryption, key generation and key agreement, and Message
* Authentication Code (MAC) generation.
*
* <p>Support for encryption includes symmetric, asymmetric, block,
* and stream ciphers. This package also supports secure streams and
* sealed objects.
*
* <p>Many of the classes provided in this package are provider-based.
* The class itself defines a programming interface to which
* applications may write. The implementations themselves may then be
* written by independent third-party vendors and plugged in
* seamlessly as needed. Therefore application developers may take
* advantage of any number of provider-based implementations without
* having to add or rewrite code.
*
* <ul>
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
* <b>Java Security Standard Algorithm Names Specification
* </b></a></li>
* </ul>
*
* <h2>Related Documentation</h2>
*
* For further documentation, please see:
* <ul>
* <li>
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide}</li>
* <li>
* {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
* </ul>
*
* @since 1.4
*/
package javax.crypto;

View file

@ -0,0 +1,240 @@
/*
* Copyright (c) 1997, 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 javax.crypto.spec;
import java.security.InvalidKeyException;
/**
* This class specifies a DES key.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class DESKeySpec implements java.security.spec.KeySpec {
/**
* The constant which defines the length of a DES key in bytes.
*/
public static final int DES_KEY_LEN = 8;
private byte[] key;
/*
* Weak/semi-weak keys copied from FIPS 74.
*
* "...The first 6 keys have duals different than themselves, hence
* each is both a key and a dual giving 12 keys with duals. The last
* four keys equal their duals, and are called self-dual keys..."
*
* 1. E001E001F101F101 01E001E001F101F1
* 2. FE1FFE1FFEOEFEOE 1FFE1FFEOEFEOEFE
* 3. E01FE01FF10EF10E 1FE01FEOOEF10EF1
* 4. 01FE01FE01FE01FE FE01FE01FE01FE01
* 5. 011F011F010E010E 1F011F010E010E01
* 6. E0FEE0FEF1FEF1FE FEE0FEE0FEF1FEF1
* 7. 0101010101010101 0101010101010101
* 8. FEFEFEFEFEFEFEFE FEFEFEFEFEFEFEFE
* 9. E0E0E0E0F1F1F1F1 E0E0E0E0F1F1F1F1
* 10. 1F1F1F1F0E0E0E0E 1F1F1F1F0E0E0E0E
*/
private static final byte[][] WEAK_KEYS = {
{ (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01,
(byte)0x01, (byte)0x01, (byte)0x01 },
{ (byte)0xFE, (byte)0xFE, (byte)0xFE, (byte)0xFE, (byte)0xFE,
(byte)0xFE, (byte)0xFE, (byte)0xFE },
{ (byte)0x1F, (byte)0x1F, (byte)0x1F, (byte)0x1F, (byte)0x0E,
(byte)0x0E, (byte)0x0E, (byte)0x0E },
{ (byte)0xE0, (byte)0xE0, (byte)0xE0, (byte)0xE0, (byte)0xF1,
(byte)0xF1, (byte)0xF1, (byte)0xF1 },
{ (byte)0x01, (byte)0xFE, (byte)0x01, (byte)0xFE, (byte)0x01,
(byte)0xFE, (byte)0x01, (byte)0xFE },
{ (byte)0x1F, (byte)0xE0, (byte)0x1F, (byte)0xE0, (byte)0x0E,
(byte)0xF1, (byte)0x0E, (byte)0xF1 },
{ (byte)0x01, (byte)0xE0, (byte)0x01, (byte)0xE0, (byte)0x01,
(byte)0xF1, (byte)0x01, (byte)0xF1 },
{ (byte)0x1F, (byte)0xFE, (byte)0x1F, (byte)0xFE, (byte)0x0E,
(byte)0xFE, (byte)0x0E, (byte)0xFE },
{ (byte)0x01, (byte)0x1F, (byte)0x01, (byte)0x1F, (byte)0x01,
(byte)0x0E, (byte)0x01, (byte)0x0E },
{ (byte)0xE0, (byte)0xFE, (byte)0xE0, (byte)0xFE, (byte)0xF1,
(byte)0xFE, (byte)0xF1, (byte)0xFE },
{ (byte)0xFE, (byte)0x01, (byte)0xFE, (byte)0x01, (byte)0xFE,
(byte)0x01, (byte)0xFE, (byte)0x01 },
{ (byte)0xE0, (byte)0x1F, (byte)0xE0, (byte)0x1F, (byte)0xF1,
(byte)0x0E, (byte)0xF1, (byte)0x0E },
{ (byte)0xE0, (byte)0x01, (byte)0xE0, (byte)0x01, (byte)0xF1,
(byte)0x01, (byte)0xF1, (byte)0x01 },
{ (byte)0xFE, (byte)0x1F, (byte)0xFE, (byte)0x1F, (byte)0xFE,
(byte)0x0E, (byte)0xFE, (byte)0x0E },
{ (byte)0x1F, (byte)0x01, (byte)0x1F, (byte)0x01, (byte)0x0E,
(byte)0x01, (byte)0x0E, (byte)0x01 },
{ (byte)0xFE, (byte)0xE0, (byte)0xFE, (byte)0xE0, (byte)0xFE,
(byte)0xF1, (byte)0xFE, (byte)0xF1 }
};
/**
* Creates a DESKeySpec object using the first 8 bytes in
* <code>key</code> as the key material for the DES key.
*
* <p> The bytes that constitute the DES key are those between
* <code>key[0]</code> and <code>key[7]</code> inclusive.
*
* @param key the buffer with the DES key material. The first 8 bytes
* of the buffer are copied to protect against subsequent modification.
*
* @exception NullPointerException if the given key material is
* <code>null</code>
* @exception InvalidKeyException if the given key material is shorter
* than 8 bytes.
*/
public DESKeySpec(byte[] key) throws InvalidKeyException {
this(key, 0);
}
/**
* Creates a DESKeySpec object using the first 8 bytes in
* <code>key</code>, beginning at <code>offset</code> inclusive,
* as the key material for the DES key.
*
* <p> The bytes that constitute the DES key are those between
* <code>key[offset]</code> and <code>key[offset+7]</code> inclusive.
*
* @param key the buffer with the DES key material. The first 8 bytes
* of the buffer beginning at <code>offset</code> inclusive are copied
* to protect against subsequent modification.
* @param offset the offset in <code>key</code>, where the DES key
* material starts.
*
* @exception NullPointerException if the given key material is
* <code>null</code>
* @exception InvalidKeyException if the given key material, starting at
* <code>offset</code> inclusive, is shorter than 8 bytes.
*/
public DESKeySpec(byte[] key, int offset) throws InvalidKeyException {
if (key.length - offset < DES_KEY_LEN) {
throw new InvalidKeyException("Wrong key size");
}
this.key = new byte[DES_KEY_LEN];
System.arraycopy(key, offset, this.key, 0, DES_KEY_LEN);
}
/**
* Returns the DES key material.
*
* @return the DES key material. Returns a new array
* each time this method is called.
*/
public byte[] getKey() {
return this.key.clone();
}
/**
* Checks if the given DES key material, starting at <code>offset</code>
* inclusive, is parity-adjusted.
*
* @param key the buffer with the DES key material.
* @param offset the offset in <code>key</code>, where the DES key
* material starts.
*
* @return true if the given DES key material is parity-adjusted, false
* otherwise.
*
* @exception InvalidKeyException if the given key material is
* <code>null</code>, or starting at <code>offset</code> inclusive, is
* shorter than 8 bytes.
*/
public static boolean isParityAdjusted(byte[] key, int offset)
throws InvalidKeyException {
if (key == null) {
throw new InvalidKeyException("null key");
}
if (key.length - offset < DES_KEY_LEN) {
throw new InvalidKeyException("Wrong key size");
}
for (int i = 0; i < DES_KEY_LEN; i++) {
int k = Integer.bitCount(key[offset++] & 0xff);
if ((k & 1) == 0) {
return false;
}
}
return true;
}
/**
* Checks if the given DES key material is weak or semi-weak.
*
* @param key the buffer with the DES key material.
* @param offset the offset in <code>key</code>, where the DES key
* material starts.
*
* @return true if the given DES key material is weak or semi-weak, false
* otherwise.
*
* @exception InvalidKeyException if the given key material is
* <code>null</code>, or starting at <code>offset</code> inclusive, is
* shorter than 8 bytes.
*/
public static boolean isWeak(byte[] key, int offset)
throws InvalidKeyException {
if (key == null) {
throw new InvalidKeyException("null key");
}
if (key.length - offset < DES_KEY_LEN) {
throw new InvalidKeyException("Wrong key size");
}
for (int i = 0; i < WEAK_KEYS.length; i++) {
boolean found = true;
for (int j = 0; j < DES_KEY_LEN && found == true; j++) {
if (WEAK_KEYS[i][j] != key[j+offset]) {
found = false;
}
}
if (found == true) {
return found;
}
}
return false;
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 1997, 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 javax.crypto.spec;
import java.security.InvalidKeyException;
/**
* This class specifies a DES-EDE ("triple-DES") key.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class DESedeKeySpec implements java.security.spec.KeySpec {
/**
* The constant which defines the length of a DESede key in bytes.
*/
public static final int DES_EDE_KEY_LEN = 24;
private byte[] key;
/**
* Creates a DESedeKeySpec object using the first 24 bytes in
* <code>key</code> as the key material for the DES-EDE key.
*
* <p> The bytes that constitute the DES-EDE key are those between
* <code>key[0]</code> and <code>key[23]</code> inclusive
*
* @param key the buffer with the DES-EDE key material. The first
* 24 bytes of the buffer are copied to protect against subsequent
* modification.
*
* @exception NullPointerException if <code>key</code> is null.
* @exception InvalidKeyException if the given key material is shorter
* than 24 bytes.
*/
public DESedeKeySpec(byte[] key) throws InvalidKeyException {
this(key, 0);
}
/**
* Creates a DESedeKeySpec object using the first 24 bytes in
* <code>key</code>, beginning at <code>offset</code> inclusive,
* as the key material for the DES-EDE key.
*
* <p> The bytes that constitute the DES-EDE key are those between
* <code>key[offset]</code> and <code>key[offset+23]</code> inclusive.
*
* @param key the buffer with the DES-EDE key material. The first
* 24 bytes of the buffer beginning at <code>offset</code> inclusive
* are copied to protect against subsequent modification.
* @param offset the offset in <code>key</code>, where the DES-EDE key
* material starts.
*
* @exception NullPointerException if <code>key</code> is null.
* @exception InvalidKeyException if the given key material, starting at
* <code>offset</code> inclusive, is shorter than 24 bytes
*/
public DESedeKeySpec(byte[] key, int offset) throws InvalidKeyException {
if (key.length - offset < 24) {
throw new InvalidKeyException("Wrong key size");
}
this.key = new byte[24];
System.arraycopy(key, offset, this.key, 0, 24);
}
/**
* Returns the DES-EDE key.
*
* @return the DES-EDE key. Returns a new array
* each time this method is called.
*/
public byte[] getKey() {
return this.key.clone();
}
/**
* Checks if the given DES-EDE key, starting at <code>offset</code>
* inclusive, is parity-adjusted.
*
* @param key a byte array which holds the key value
* @param offset the offset into the byte array
* @return true if the given DES-EDE key is parity-adjusted, false
* otherwise
*
* @exception NullPointerException if <code>key</code> is null.
* @exception InvalidKeyException if the given key material, starting at
* <code>offset</code> inclusive, is shorter than 24 bytes
*/
public static boolean isParityAdjusted(byte[] key, int offset)
throws InvalidKeyException {
if (key.length - offset < 24) {
throw new InvalidKeyException("Wrong key size");
}
if (DESKeySpec.isParityAdjusted(key, offset) == false
|| DESKeySpec.isParityAdjusted(key, offset + 8) == false
|| DESKeySpec.isParityAdjusted(key, offset + 16) == false) {
return false;
}
return true;
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto.spec;
import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class specifies the set of parameters used for generating
* Diffie-Hellman (system) parameters for use in Diffie-Hellman key
* agreement. This is typically done by a central
* authority.
*
* <p> The central authority, after computing the parameters, must send this
* information to the parties looking to agree on a secret key.
*
* @author Jan Luehe
*
* @see DHParameterSpec
* @since 1.4
*/
public class DHGenParameterSpec implements AlgorithmParameterSpec {
// The size in bits of the prime modulus
private int primeSize;
// The size in bits of the random exponent (private value)
private int exponentSize;
/**
* Constructs a parameter set for the generation of Diffie-Hellman
* (system) parameters. The constructed parameter set can be used to
* initialize an
* {@link java.security.AlgorithmParameterGenerator AlgorithmParameterGenerator}
* object for the generation of Diffie-Hellman parameters.
*
* @param primeSize the size (in bits) of the prime modulus.
* @param exponentSize the size (in bits) of the random exponent.
*/
public DHGenParameterSpec(int primeSize, int exponentSize) {
this.primeSize = primeSize;
this.exponentSize = exponentSize;
}
/**
* Returns the size in bits of the prime modulus.
*
* @return the size in bits of the prime modulus
*/
public int getPrimeSize() {
return this.primeSize;
}
/**
* Returns the size in bits of the random exponent (private value).
*
* @return the size in bits of the random exponent (private value)
*/
public int getExponentSize() {
return this.exponentSize;
}
}

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto.spec;
import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class specifies the set of parameters used with the Diffie-Hellman
* algorithm, as specified in PKCS #3: <i>Diffie-Hellman Key-Agreement
* Standard</i>.
*
* <p>A central authority generates parameters and gives them to the two
* entities seeking to generate a secret key. The parameters are a prime
* <code>p</code>, a base <code>g</code>, and optionally the length
* in bits of the private value, <code>l</code>.
*
* <p>It is possible that more than one instance of parameters may be
* generated by a given central authority, and that there may be more than
* one central authority. Indeed, each individual may be its own central
* authority, with different entities having different parameters.
*
* <p>Note that this class does not perform any validation on specified
* parameters. Thus, the specified values are returned directly even
* if they are null.
*
* @author Jan Luehe
*
* @see javax.crypto.KeyAgreement
* @since 1.4
*/
public class DHParameterSpec implements AlgorithmParameterSpec {
// The prime modulus
private BigInteger p;
// The base generator
private BigInteger g;
// The size in bits of the random exponent (private value) (optional)
private int l;
/**
* Constructs a parameter set for Diffie-Hellman, using a prime modulus
* <code>p</code> and a base generator <code>g</code>.
*
* @param p the prime modulus
* @param g the base generator
*/
public DHParameterSpec(BigInteger p, BigInteger g) {
this.p = p;
this.g = g;
this.l = 0;
}
/**
* Constructs a parameter set for Diffie-Hellman, using a prime modulus
* <code>p</code>, a base generator <code>g</code>,
* and the size in bits, <code>l</code>, of the random exponent
* (private value).
*
* @param p the prime modulus
* @param g the base generator
* @param l the size in bits of the random exponent (private value)
*/
public DHParameterSpec(BigInteger p, BigInteger g, int l) {
this.p = p;
this.g = g;
this.l = l;
}
/**
* Returns the prime modulus <code>p</code>.
*
* @return the prime modulus <code>p</code>
*/
public BigInteger getP() {
return this.p;
}
/**
* Returns the base generator <code>g</code>.
*
* @return the base generator <code>g</code>
*/
public BigInteger getG() {
return this.g;
}
/**
* Returns the size in bits, <code>l</code>, of the random exponent
* (private value).
*
* @return the size in bits, <code>l</code>, of the random exponent
* (private value), or 0 if this size has not been set
*/
public int getL() {
return this.l;
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto.spec;
import java.math.BigInteger;
/**
* This class specifies a Diffie-Hellman private key with its associated
* parameters.
*
* <p>Note that this class does not perform any validation on specified
* parameters. Thus, the specified values are returned directly even
* if they are null.
*
* @author Jan Luehe
*
* @see DHPublicKeySpec
* @since 1.4
*/
public class DHPrivateKeySpec implements java.security.spec.KeySpec {
// The private value
private BigInteger x;
// The prime modulus
private BigInteger p;
// The base generator
private BigInteger g;
/**
* Constructor that takes a private value <code>x</code>, a prime
* modulus <code>p</code>, and a base generator <code>g</code>.
* @param x private value x
* @param p prime modulus p
* @param g base generator g
*/
public DHPrivateKeySpec(BigInteger x, BigInteger p, BigInteger g) {
this.x = x;
this.p = p;
this.g = g;
}
/**
* Returns the private value <code>x</code>.
*
* @return the private value <code>x</code>
*/
public BigInteger getX() {
return this.x;
}
/**
* Returns the prime modulus <code>p</code>.
*
* @return the prime modulus <code>p</code>
*/
public BigInteger getP() {
return this.p;
}
/**
* Returns the base generator <code>g</code>.
*
* @return the base generator <code>g</code>
*/
public BigInteger getG() {
return this.g;
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 1997, 2007, 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 javax.crypto.spec;
import java.math.BigInteger;
/**
* This class specifies a Diffie-Hellman public key with its associated
* parameters.
*
* <p>Note that this class does not perform any validation on specified
* parameters. Thus, the specified values are returned directly even
* if they are null.
*
* @author Jan Luehe
*
* @see DHPrivateKeySpec
* @since 1.4
*/
public class DHPublicKeySpec implements java.security.spec.KeySpec {
// The public value
private BigInteger y;
// The prime modulus
private BigInteger p;
// The base generator
private BigInteger g;
/**
* Constructor that takes a public value <code>y</code>, a prime
* modulus <code>p</code>, and a base generator <code>g</code>.
* @param y public value y
* @param p prime modulus p
* @param g base generator g
*/
public DHPublicKeySpec(BigInteger y, BigInteger p, BigInteger g) {
this.y = y;
this.p = p;
this.g = g;
}
/**
* Returns the public value <code>y</code>.
*
* @return the public value <code>y</code>
*/
public BigInteger getY() {
return this.y;
}
/**
* Returns the prime modulus <code>p</code>.
*
* @return the prime modulus <code>p</code>
*/
public BigInteger getP() {
return this.p;
}
/**
* Returns the base generator <code>g</code>.
*
* @return the base generator <code>g</code>
*/
public BigInteger getG() {
return this.g;
}
}

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2011, 2013, 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 javax.crypto.spec;
import java.security.spec.AlgorithmParameterSpec;
/**
* Specifies the set of parameters required by a {@link
* javax.crypto.Cipher} using the Galois/Counter Mode (GCM) mode.
* <p>
* Simple block cipher modes (such as CBC) generally require only an
* initialization vector (such as {@code IvParameterSpec}),
* but GCM needs these parameters:
* <ul>
* <li>{@code IV}: Initialization Vector (IV) </li>
* <li>{@code tLen}: length (in bits) of authentication tag T</li>
* </ul>
* <p>
* In addition to the parameters described here, other GCM inputs/output
* (Additional Authenticated Data (AAD), Keys, block ciphers,
* plain/ciphertext and authentication tags) are handled in the {@code
* Cipher} class.
* <p>
* Please see <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116
* </a> for more information on the Authenticated Encryption with
* Associated Data (AEAD) algorithm, and <a href=
* "http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf">
* NIST Special Publication 800-38D</a>, "NIST Recommendation for Block
* Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC."
* <p>
* The GCM specification states that {@code tLen} may only have the
* values {128, 120, 112, 104, 96}, or {64, 32} for certain
* applications. Other values can be specified for this class, but not
* all CSP implementations will support them.
*
* @see javax.crypto.Cipher
*
* @since 1.7
*/
public class GCMParameterSpec implements AlgorithmParameterSpec {
// Initialization Vector. Could use IvParameterSpec, but that
// would add extra copies.
private byte[] iv;
// Required Tag length (in bits).
private int tLen;
/**
* Constructs a GCMParameterSpec using the specified authentication
* tag bit-length and IV buffer.
*
* @param tLen the authentication tag length (in bits)
* @param src the IV source buffer. The contents of the buffer are
* copied to protect against subsequent modification.
*
* @throws IllegalArgumentException if {@code tLen} is negative,
* or {@code src} is null.
*/
public GCMParameterSpec(int tLen, byte[] src) {
if (src == null) {
throw new IllegalArgumentException("src array is null");
}
init(tLen, src, 0, src.length);
}
/**
* Constructs a GCMParameterSpec object using the specified
* authentication tag bit-length and a subset of the specified
* buffer as the IV.
*
* @param tLen the authentication tag length (in bits)
* @param src the IV source buffer. The contents of the
* buffer are copied to protect against subsequent modification.
* @param offset the offset in {@code src} where the IV starts
* @param len the number of IV bytes
*
* @throws IllegalArgumentException if {@code tLen} is negative,
* {@code src} is null, {@code len} or {@code offset} is negative,
* or the sum of {@code offset} and {@code len} is greater than the
* length of the {@code src} byte array.
*/
public GCMParameterSpec(int tLen, byte[] src, int offset, int len) {
init(tLen, src, offset, len);
}
/*
* Check input parameters.
*/
private void init(int tLen, byte[] src, int offset, int len) {
if (tLen < 0) {
throw new IllegalArgumentException(
"Length argument is negative");
}
this.tLen = tLen;
// Input sanity check
if ((src == null) ||(len < 0) || (offset < 0)
|| ((len + offset) > src.length)) {
throw new IllegalArgumentException("Invalid buffer arguments");
}
iv = new byte[len];
System.arraycopy(src, offset, iv, 0, len);
}
/**
* Returns the authentication tag length.
*
* @return the authentication tag length (in bits)
*/
public int getTLen() {
return tLen;
}
/**
* Returns the Initialization Vector (IV).
*
* @return the IV. Creates a new array each time this method
* is called.
*/
public byte[] getIV() {
return iv.clone();
}
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 1997, 2013, 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 javax.crypto.spec;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class specifies an <i>initialization vector</i> (IV).
* Examples which use IVs are ciphers in feedback mode,
* e.g., DES in CBC mode and RSA ciphers with OAEP encoding
* operation.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class IvParameterSpec implements AlgorithmParameterSpec {
private byte[] iv;
/**
* Creates an IvParameterSpec object using the bytes in <code>iv</code>
* as the IV.
*
* @param iv the buffer with the IV. The contents of the
* buffer are copied to protect against subsequent modification.
* @throws NullPointerException if <code>iv</code> is <code>null</code>
*/
public IvParameterSpec(byte[] iv) {
this(iv, 0, iv.length);
}
/**
* Creates an IvParameterSpec object using the first <code>len</code>
* bytes in <code>iv</code>, beginning at <code>offset</code>
* inclusive, as the IV.
*
* <p> The bytes that constitute the IV are those between
* <code>iv[offset]</code> and <code>iv[offset+len-1]</code> inclusive.
*
* @param iv the buffer with the IV. The first <code>len</code>
* bytes of the buffer beginning at <code>offset</code> inclusive
* are copied to protect against subsequent modification.
* @param offset the offset in <code>iv</code> where the IV
* starts.
* @param len the number of IV bytes.
* @throws IllegalArgumentException if <code>iv</code> is <code>null</code>
* or {@code (iv.length - offset < len)}
* @throws ArrayIndexOutOfBoundsException is thrown if <code>offset</code>
* or <code>len</code> index bytes outside the <code>iv</code>.
*/
public IvParameterSpec(byte[] iv, int offset, int len) {
if (iv == null) {
throw new IllegalArgumentException("IV missing");
}
if (iv.length - offset < len) {
throw new IllegalArgumentException
("IV buffer too short for given offset/length combination");
}
if (len < 0) {
throw new ArrayIndexOutOfBoundsException("len is negative");
}
this.iv = new byte[len];
System.arraycopy(iv, offset, this.iv, 0, len);
}
/**
* Returns the initialization vector (IV).
*
* @return the initialization vector (IV). Returns a new array
* each time this method is called.
*/
public byte[] getIV() {
return this.iv.clone();
}
}

View file

@ -0,0 +1,168 @@
/*
* Copyright (c) 2003, 2007, 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 javax.crypto.spec;
import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.MGF1ParameterSpec;
/**
* This class specifies the set of parameters used with OAEP Padding,
* as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a>
* standard.
*
* Its ASN.1 definition in PKCS#1 standard is described below:
* <pre>
* RSAES-OAEP-params ::= SEQUENCE {
* hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
* maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
* pSourceAlgorithm [2] PKCS1PSourceAlgorithms DEFAULT pSpecifiedEmpty
* }
* </pre>
* where
* <pre>
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-sha1 PARAMETERS NULL }|
* { OID id-sha256 PARAMETERS NULL }|
* { OID id-sha384 PARAMETERS NULL }|
* { OID id-sha512 PARAMETERS NULL },
* ... -- Allows for future expansion --
* }
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
* ... -- Allows for future expansion --
* }
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-pSpecified PARAMETERS OCTET STRING },
* ... -- Allows for future expansion --
* }
* </pre>
* <p>Note: the OAEPParameterSpec.DEFAULT uses the following:
* message digest -- "SHA-1"
* mask generation function (mgf) -- "MGF1"
* parameters for mgf -- MGF1ParameterSpec.SHA1
* source of encoding input -- PSource.PSpecified.DEFAULT
*
* @see java.security.spec.MGF1ParameterSpec
* @see PSource
*
* @author Valerie Peng
*
* @since 1.5
*/
public class OAEPParameterSpec implements AlgorithmParameterSpec {
private String mdName = "SHA-1";
private String mgfName = "MGF1";
private AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1;
private PSource pSrc = PSource.PSpecified.DEFAULT;
/**
* The OAEP parameter set with all default values.
*/
public static final OAEPParameterSpec DEFAULT = new OAEPParameterSpec();
/**
* Constructs a parameter set for OAEP padding as defined in
* the PKCS #1 standard using the default values.
*/
private OAEPParameterSpec() {
}
/**
* Constructs a parameter set for OAEP padding as defined in
* the PKCS #1 standard using the specified message digest
* algorithm <code>mdName</code>, mask generation function
* algorithm <code>mgfName</code>, parameters for the mask
* generation function <code>mgfSpec</code>, and source of
* the encoding input P <code>pSrc</code>.
*
* @param mdName the algorithm name for the message digest.
* @param mgfName the algorithm name for the mask generation
* function.
* @param mgfSpec the parameters for the mask generation function.
* If null is specified, null will be returned by getMGFParameters().
* @param pSrc the source of the encoding input P.
* @exception NullPointerException if <code>mdName</code>,
* <code>mgfName</code>, or <code>pSrc</code> is null.
*/
public OAEPParameterSpec(String mdName, String mgfName,
AlgorithmParameterSpec mgfSpec,
PSource pSrc) {
if (mdName == null) {
throw new NullPointerException("digest algorithm is null");
}
if (mgfName == null) {
throw new NullPointerException("mask generation function " +
"algorithm is null");
}
if (pSrc == null) {
throw new NullPointerException("source of the encoding input " +
"is null");
}
this.mdName = mdName;
this.mgfName = mgfName;
this.mgfSpec = mgfSpec;
this.pSrc = pSrc;
}
/**
* Returns the message digest algorithm name.
*
* @return the message digest algorithm name.
*/
public String getDigestAlgorithm() {
return mdName;
}
/**
* Returns the mask generation function algorithm name.
*
* @return the mask generation function algorithm name.
*/
public String getMGFAlgorithm() {
return mgfName;
}
/**
* Returns the parameters for the mask generation function.
*
* @return the parameters for the mask generation function.
*/
public AlgorithmParameterSpec getMGFParameters() {
return mgfSpec;
}
/**
* Returns the source of encoding input P.
*
* @return the source of encoding input P.
*/
public PSource getPSource() {
return pSrc;
}
}

View file

@ -0,0 +1,240 @@
/*
* Copyright (c) 1997, 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 javax.crypto.spec;
import java.security.spec.KeySpec;
/**
* A user-chosen password that can be used with password-based encryption
* (<i>PBE</i>).
*
* <p>The password can be viewed as some kind of raw key material, from which
* the encryption mechanism that uses it derives a cryptographic key.
*
* <p>Different PBE mechanisms may consume different bits of each password
* character. For example, the PBE mechanism defined in
* <a href="http://www.ietf.org/rfc/rfc2898.txt">
* PKCS #5</a> looks at only the low order 8 bits of each character, whereas
* PKCS #12 looks at all 16 bits of each character.
*
* <p>You convert the password characters to a PBE key by creating an
* instance of the appropriate secret-key factory. For example, a secret-key
* factory for PKCS #5 will construct a PBE key from only the low order 8 bits
* of each password character, whereas a secret-key factory for PKCS #12 will
* take all 16 bits of each character.
*
* <p>Also note that this class stores passwords as char arrays instead of
* <code>String</code> objects (which would seem more logical), because the
* String class is immutable and there is no way to overwrite its
* internal value when the password stored in it is no longer needed. Hence,
* this class requests the password as a char array, so it can be overwritten
* when done.
*
* @author Jan Luehe
* @author Valerie Peng
*
* @see javax.crypto.SecretKeyFactory
* @see PBEParameterSpec
* @since 1.4
*/
public class PBEKeySpec implements KeySpec {
private char[] password;
private byte[] salt = null;
private int iterationCount = 0;
private int keyLength = 0;
/**
* Constructor that takes a password. An empty char[] is used if
* null is specified.
*
* <p> Note: <code>password</code> is cloned before it is stored in
* the new <code>PBEKeySpec</code> object.
*
* @param password the password.
*/
public PBEKeySpec(char[] password) {
if ((password == null) || (password.length == 0)) {
this.password = new char[0];
} else {
this.password = password.clone();
}
}
/**
* Constructor that takes a password, salt, iteration count, and
* to-be-derived key length for generating PBEKey of variable-key-size
* PBE ciphers. An empty char[] is used if null is specified for
* <code>password</code>.
*
* <p> Note: the <code>password</code> and <code>salt</code>
* are cloned before they are stored in
* the new <code>PBEKeySpec</code> object.
*
* @param password the password.
* @param salt the salt.
* @param iterationCount the iteration count.
* @param keyLength the to-be-derived key length.
* @exception NullPointerException if <code>salt</code> is null.
* @exception IllegalArgumentException if <code>salt</code> is empty,
* i.e. 0-length, <code>iterationCount</code> or
* <code>keyLength</code> is not positive.
*/
public PBEKeySpec(char[] password, byte[] salt, int iterationCount,
int keyLength) {
if ((password == null) || (password.length == 0)) {
this.password = new char[0];
} else {
this.password = password.clone();
}
if (salt == null) {
throw new NullPointerException("the salt parameter " +
"must be non-null");
} else if (salt.length == 0) {
throw new IllegalArgumentException("the salt parameter " +
"must not be empty");
} else {
this.salt = salt.clone();
}
if (iterationCount<=0) {
throw new IllegalArgumentException("invalid iterationCount value");
}
if (keyLength<=0) {
throw new IllegalArgumentException("invalid keyLength value");
}
this.iterationCount = iterationCount;
this.keyLength = keyLength;
}
/**
* Constructor that takes a password, salt, iteration count for
* generating PBEKey of fixed-key-size PBE ciphers. An empty
* char[] is used if null is specified for <code>password</code>.
*
* <p> Note: the <code>password</code> and <code>salt</code>
* are cloned before they are stored in the new
* <code>PBEKeySpec</code> object.
*
* @param password the password.
* @param salt the salt.
* @param iterationCount the iteration count.
* @exception NullPointerException if <code>salt</code> is null.
* @exception IllegalArgumentException if <code>salt</code> is empty,
* i.e. 0-length, or <code>iterationCount</code> is not positive.
*/
public PBEKeySpec(char[] password, byte[] salt, int iterationCount) {
if ((password == null) || (password.length == 0)) {
this.password = new char[0];
} else {
this.password = password.clone();
}
if (salt == null) {
throw new NullPointerException("the salt parameter " +
"must be non-null");
} else if (salt.length == 0) {
throw new IllegalArgumentException("the salt parameter " +
"must not be empty");
} else {
this.salt = salt.clone();
}
if (iterationCount<=0) {
throw new IllegalArgumentException("invalid iterationCount value");
}
this.iterationCount = iterationCount;
}
/**
* Clears the internal copy of the password.
*
*/
public final void clearPassword() {
if (password != null) {
for (int i = 0; i < password.length; i++) {
password[i] = ' ';
}
password = null;
}
}
/**
* Returns a copy of the password.
*
* <p> Note: this method returns a copy of the password. It is
* the caller's responsibility to zero out the password information after
* it is no longer needed.
*
* @exception IllegalStateException if password has been cleared by
* calling <code>clearPassword</code> method.
* @return the password.
*/
public final char[] getPassword() {
if (password == null) {
throw new IllegalStateException("password has been cleared");
}
return password.clone();
}
/**
* Returns a copy of the salt or null if not specified.
*
* <p> Note: this method should return a copy of the salt. It is
* the caller's responsibility to zero out the salt information after
* it is no longer needed.
*
* @return the salt.
*/
public final byte[] getSalt() {
if (salt != null) {
return salt.clone();
} else {
return null;
}
}
/**
* Returns the iteration count or 0 if not specified.
*
* @return the iteration count.
*/
public final int getIterationCount() {
return iterationCount;
}
/**
* Returns the to-be-derived key length or 0 if not specified.
*
* <p> Note: this is used to indicate the preference on key length
* for variable-key-size ciphers. The actual key size depends on
* each provider's implementation.
*
* @return the to-be-derived key length.
*/
public final int getKeyLength() {
return keyLength;
}
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 1997, 2013, 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 javax.crypto.spec;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class specifies the set of parameters used with password-based
* encryption (PBE), as defined in the
* <a href="http://www.ietf.org/rfc/rfc2898.txt">PKCS #5</a>
* standard.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class PBEParameterSpec implements AlgorithmParameterSpec {
private byte[] salt;
private int iterationCount;
private AlgorithmParameterSpec paramSpec = null;
/**
* Constructs a parameter set for password-based encryption as defined in
* the PKCS #5 standard.
*
* @param salt the salt. The contents of <code>salt</code> are copied
* to protect against subsequent modification.
* @param iterationCount the iteration count.
* @exception NullPointerException if <code>salt</code> is null.
*/
public PBEParameterSpec(byte[] salt, int iterationCount) {
this.salt = salt.clone();
this.iterationCount = iterationCount;
}
/**
* Constructs a parameter set for password-based encryption as defined in
* the PKCS #5 standard.
*
* @param salt the salt. The contents of <code>salt</code> are copied
* to protect against subsequent modification.
* @param iterationCount the iteration count.
* @param paramSpec the cipher algorithm parameter specification, which
* may be null.
* @exception NullPointerException if <code>salt</code> is null.
*
* @since 1.8
*/
public PBEParameterSpec(byte[] salt, int iterationCount,
AlgorithmParameterSpec paramSpec) {
this.salt = salt.clone();
this.iterationCount = iterationCount;
this.paramSpec = paramSpec;
}
/**
* Returns the salt.
*
* @return the salt. Returns a new array
* each time this method is called.
*/
public byte[] getSalt() {
return this.salt.clone();
}
/**
* Returns the iteration count.
*
* @return the iteration count
*/
public int getIterationCount() {
return this.iterationCount;
}
/**
* Returns the cipher algorithm parameter specification.
*
* @return the parameter specification, or null if none was set.
*
* @since 1.8
*/
public AlgorithmParameterSpec getParameterSpec() {
return this.paramSpec;
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2003, 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 javax.crypto.spec;
/**
* This class specifies the source for encoding input P in OAEP Padding,
* as defined in the
* <a href="http://www.ietf.org/rfc/rfc3447.txt">PKCS #1</a>
* standard.
* <pre>
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
* { OID id-pSpecified PARAMETERS OCTET STRING },
* ... -- Allows for future expansion --
* }
* </pre>
* @author Valerie Peng
*
* @since 1.5
*/
public class PSource {
private String pSrcName;
/**
* Constructs a source of the encoding input P for OAEP
* padding as defined in the PKCS #1 standard using the
* specified PSource algorithm.
* @param pSrcName the algorithm for the source of the
* encoding input P.
* @exception NullPointerException if <code>pSrcName</code>
* is null.
*/
protected PSource(String pSrcName) {
if (pSrcName == null) {
throw new NullPointerException("pSource algorithm is null");
}
this.pSrcName = pSrcName;
}
/**
* Returns the PSource algorithm name.
*
* @return the PSource algorithm name.
*/
public String getAlgorithm() {
return pSrcName;
}
/**
* This class is used to explicitly specify the value for
* encoding input P in OAEP Padding.
*
* @since 1.5
*/
public static final class PSpecified extends PSource {
private byte[] p = new byte[0];
/**
* The encoding input P whose value equals byte[0].
*/
public static final PSpecified DEFAULT = new PSpecified(new byte[0]);
/**
* Constructs the source explicitly with the specified
* value <code>p</code> as the encoding input P.
* Note:
* @param p the value of the encoding input. The contents
* of the array are copied to protect against subsequent
* modification.
* @exception NullPointerException if <code>p</code> is null.
*/
public PSpecified(byte[] p) {
super("PSpecified");
this.p = p.clone();
}
/**
* Returns the value of encoding input P.
* @return the value of encoding input P. A new array is
* returned each time this method is called.
*/
public byte[] getValue() {
return (p.length==0? p: p.clone());
}
}
}

View file

@ -0,0 +1,160 @@
/*
* 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
* 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 javax.crypto.spec;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class specifies the parameters used with the
* <a href="http://www.ietf.org/rfc/rfc2268.txt"><i>RC2</i></a>
* algorithm.
*
* <p> The parameters consist of an effective key size and optionally
* an 8-byte initialization vector (IV) (only in feedback mode).
*
* <p> This class can be used to initialize a {@code Cipher} object that
* implements the <i>RC2</i> algorithm.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class RC2ParameterSpec implements AlgorithmParameterSpec {
private byte[] iv = null;
private int effectiveKeyBits;
/**
* Constructs a parameter set for RC2 from the given effective key size
* (in bits).
*
* @param effectiveKeyBits the effective key size in bits.
*/
public RC2ParameterSpec(int effectiveKeyBits) {
this.effectiveKeyBits = effectiveKeyBits;
}
/**
* Constructs a parameter set for RC2 from the given effective key size
* (in bits) and an 8-byte IV.
*
* <p> The bytes that constitute the IV are those between
* {@code iv[0]} and {@code iv[7]} inclusive.
*
* @param effectiveKeyBits the effective key size in bits.
* @param iv the buffer with the 8-byte IV. The first 8 bytes of
* the buffer are copied to protect against subsequent modification.
* @exception IllegalArgumentException if {@code iv} is null.
*/
public RC2ParameterSpec(int effectiveKeyBits, byte[] iv) {
this(effectiveKeyBits, iv, 0);
}
/**
* Constructs a parameter set for RC2 from the given effective key size
* (in bits) and IV.
*
* <p> The IV is taken from {@code iv}, starting at
* {@code offset} inclusive.
* The bytes that constitute the IV are those between
* {@code iv[offset]} and {@code iv[offset+7]} inclusive.
*
* @param effectiveKeyBits the effective key size in bits.
* @param iv the buffer with the IV. The first 8 bytes
* of the buffer beginning at {@code offset} inclusive
* are copied to protect against subsequent modification.
* @param offset the offset in {@code iv} where the 8-byte IV
* starts.
* @exception IllegalArgumentException if {@code iv} is null.
*/
public RC2ParameterSpec(int effectiveKeyBits, byte[] iv, int offset) {
this.effectiveKeyBits = effectiveKeyBits;
if (iv == null) throw new IllegalArgumentException("IV missing");
int blockSize = 8;
if (iv.length - offset < blockSize) {
throw new IllegalArgumentException("IV too short");
}
this.iv = new byte[blockSize];
System.arraycopy(iv, offset, this.iv, 0, blockSize);
}
/**
* Returns the effective key size in bits.
*
* @return the effective key size in bits.
*/
public int getEffectiveKeyBits() {
return this.effectiveKeyBits;
}
/**
* Returns the IV or null if this parameter set does not contain an IV.
*
* @return the IV or null if this parameter set does not contain an IV.
* Returns a new array each time this method is called.
*/
public byte[] getIV() {
return (iv == null? null:iv.clone());
}
/**
* Tests for equality between the specified object and this
* object. Two RC2ParameterSpec objects are considered equal if their
* effective key sizes and IVs are equal.
* (Two IV references are considered equal if both are {@code null}.)
*
* @param obj the object to test for equality with this object.
*
* @return true if the objects are considered equal, false if
* {@code obj} is null or otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof RC2ParameterSpec)) {
return false;
}
RC2ParameterSpec other = (RC2ParameterSpec) obj;
return ((effectiveKeyBits == other.effectiveKeyBits) &&
java.util.Arrays.equals(iv, other.iv));
}
/**
* Calculates a hash code value for the object.
* Objects that are equal will also have the same hashcode.
*/
public int hashCode() {
int retval = 0;
if (iv != null) {
for (int i = 1; i < iv.length; i++) {
retval += iv[i] * i;
}
}
return (retval += effectiveKeyBits);
}
}

View file

@ -0,0 +1,203 @@
/*
* Copyright (c) 1998, 2015, 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 javax.crypto.spec;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class specifies the parameters used with the
* <a href="http://tools.ietf.org/html/rfc2040"><i>RC5</i></a>
* algorithm.
*
* <p> The parameters consist of a version number, a rounds count, a word
* size, and optionally an initialization vector (IV) (only in feedback mode).
*
* <p> This class can be used to initialize a {@code Cipher} object that
* implements the <i>RC5</i> algorithm as supplied by
* <a href="http://www.rsa.com">RSA Security LLC</a>,
* or any parties authorized by RSA Security.
*
* @author Jan Luehe
*
* @since 1.4
*/
public class RC5ParameterSpec implements AlgorithmParameterSpec {
private byte[] iv = null;
private int version;
private int rounds;
private int wordSize; // the word size in bits
/**
* Constructs a parameter set for RC5 from the given version, number of
* rounds and word size (in bits).
*
* @param version the version.
* @param rounds the number of rounds.
* @param wordSize the word size in bits.
*/
public RC5ParameterSpec(int version, int rounds, int wordSize) {
this.version = version;
this.rounds = rounds;
this.wordSize = wordSize;
}
/**
* Constructs a parameter set for RC5 from the given version, number of
* rounds, word size (in bits), and IV.
*
* <p> Note that the size of the IV (block size) must be twice the word
* size. The bytes that constitute the IV are those between
* {@code iv[0]} and {@code iv[2*(wordSize/8)-1]} inclusive.
*
* @param version the version.
* @param rounds the number of rounds.
* @param wordSize the word size in bits.
* @param iv the buffer with the IV. The first {@code 2*(wordSize/8)}
* bytes of the buffer are copied to protect against subsequent
* modification.
* @exception IllegalArgumentException if {@code iv} is
* {@code null} or {@code (iv.length < 2 * (wordSize / 8))}
*/
public RC5ParameterSpec(int version, int rounds, int wordSize, byte[] iv) {
this(version, rounds, wordSize, iv, 0);
}
/**
* Constructs a parameter set for RC5 from the given version, number of
* rounds, word size (in bits), and IV.
*
* <p> The IV is taken from {@code iv}, starting at
* {@code offset} inclusive.
* Note that the size of the IV (block size), starting at
* {@code offset} inclusive, must be twice the word size.
* The bytes that constitute the IV are those between
* {@code iv[offset]} and {@code iv[offset+2*(wordSize/8)-1]}
* inclusive.
*
* @param version the version.
* @param rounds the number of rounds.
* @param wordSize the word size in bits.
* @param iv the buffer with the IV. The first {@code 2*(wordSize/8)}
* bytes of the buffer beginning at {@code offset}
* inclusive are copied to protect against subsequent modification.
* @param offset the offset in {@code iv} where the IV starts.
* @exception IllegalArgumentException if {@code iv} is
* {@code null} or
* {@code (iv.length - offset < 2 * (wordSize / 8))}
*/
public RC5ParameterSpec(int version, int rounds, int wordSize,
byte[] iv, int offset) {
this.version = version;
this.rounds = rounds;
this.wordSize = wordSize;
if (iv == null) throw new IllegalArgumentException("IV missing");
int blockSize = (wordSize / 8) * 2;
if (iv.length - offset < blockSize) {
throw new IllegalArgumentException("IV too short");
}
this.iv = new byte[blockSize];
System.arraycopy(iv, offset, this.iv, 0, blockSize);
}
/**
* Returns the version.
*
* @return the version.
*/
public int getVersion() {
return this.version;
}
/**
* Returns the number of rounds.
*
* @return the number of rounds.
*/
public int getRounds() {
return this.rounds;
}
/**
* Returns the word size in bits.
*
* @return the word size in bits.
*/
public int getWordSize() {
return this.wordSize;
}
/**
* Returns the IV or null if this parameter set does not contain an IV.
*
* @return the IV or null if this parameter set does not contain an IV.
* Returns a new array each time this method is called.
*/
public byte[] getIV() {
return (iv == null? null:iv.clone());
}
/**
* Tests for equality between the specified object and this
* object. Two RC5ParameterSpec objects are considered equal if their
* version numbers, number of rounds, word sizes, and IVs are equal.
* (Two IV references are considered equal if both are {@code null}.)
*
* @param obj the object to test for equality with this object.
*
* @return true if the objects are considered equal, false if
* {@code obj} is null or otherwise.
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof RC5ParameterSpec)) {
return false;
}
RC5ParameterSpec other = (RC5ParameterSpec) obj;
return ((version == other.version) &&
(rounds == other.rounds) &&
(wordSize == other.wordSize) &&
java.util.Arrays.equals(iv, other.iv));
}
/**
* Calculates a hash code value for the object.
* Objects that are equal will also have the same hashcode.
*/
public int hashCode() {
int retval = 0;
if (iv != null) {
for (int i = 1; i < iv.length; i++) {
retval += iv[i] * i;
}
}
retval += (version + rounds + wordSize);
return retval;
}
}

View file

@ -0,0 +1,232 @@
/*
* Copyright (c) 1998, 2017, 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 javax.crypto.spec;
import java.security.MessageDigest;
import java.security.spec.KeySpec;
import java.util.Locale;
import javax.crypto.SecretKey;
/**
* This class specifies a secret key in a provider-independent fashion.
*
* <p>It can be used to construct a <code>SecretKey</code> from a byte array,
* without having to go through a (provider-based)
* <code>SecretKeyFactory</code>.
*
* <p>This class is only useful for raw secret keys that can be represented as
* a byte array and have no key parameters associated with them, e.g., DES or
* Triple DES keys.
*
* @author Jan Luehe
*
* @see javax.crypto.SecretKey
* @see javax.crypto.SecretKeyFactory
* @since 1.4
*/
public class SecretKeySpec implements KeySpec, SecretKey {
private static final long serialVersionUID = 6577238317307289933L;
/**
* The secret key.
*
* @serial
*/
private byte[] key;
/**
* The name of the algorithm associated with this key.
*
* @serial
*/
private String algorithm;
/**
* Constructs a secret key from the given byte array.
*
* <p>This constructor does not check if the given bytes indeed specify a
* secret key of the specified algorithm. For example, if the algorithm is
* DES, this constructor does not check if <code>key</code> is 8 bytes
* long, and also does not check for weak or semi-weak keys.
* In order for those checks to be performed, an algorithm-specific
* <i>key specification</i> class (in this case:
* {@link DESKeySpec DESKeySpec})
* should be used.
*
* @param key the key material of the secret key. The contents of
* the array are copied to protect against subsequent modification.
* @param algorithm the name of the secret-key algorithm to be associated
* with the given key material.
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
* @exception IllegalArgumentException if <code>algorithm</code>
* is null or <code>key</code> is null or empty.
*/
public SecretKeySpec(byte[] key, String algorithm) {
if (key == null || algorithm == null) {
throw new IllegalArgumentException("Missing argument");
}
if (key.length == 0) {
throw new IllegalArgumentException("Empty key");
}
this.key = key.clone();
this.algorithm = algorithm;
}
/**
* Constructs a secret key from the given byte array, using the first
* <code>len</code> bytes of <code>key</code>, starting at
* <code>offset</code> inclusive.
*
* <p> The bytes that constitute the secret key are
* those between <code>key[offset]</code> and
* <code>key[offset+len-1]</code> inclusive.
*
* <p>This constructor does not check if the given bytes indeed specify a
* secret key of the specified algorithm. For example, if the algorithm is
* DES, this constructor does not check if <code>key</code> is 8 bytes
* long, and also does not check for weak or semi-weak keys.
* In order for those checks to be performed, an algorithm-specific key
* specification class (in this case:
* {@link DESKeySpec DESKeySpec})
* must be used.
*
* @param key the key material of the secret key. The first
* <code>len</code> bytes of the array beginning at
* <code>offset</code> inclusive are copied to protect
* against subsequent modification.
* @param offset the offset in <code>key</code> where the key material
* starts.
* @param len the length of the key material.
* @param algorithm the name of the secret-key algorithm to be associated
* with the given key material.
* See the <a href="{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
* @exception IllegalArgumentException if <code>algorithm</code>
* is null or <code>key</code> is null, empty, or too short,
* i.e. {@code key.length-offset<len}.
* @exception ArrayIndexOutOfBoundsException is thrown if
* <code>offset</code> or <code>len</code> index bytes outside the
* <code>key</code>.
*/
public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
if (key == null || algorithm == null) {
throw new IllegalArgumentException("Missing argument");
}
if (key.length == 0) {
throw new IllegalArgumentException("Empty key");
}
if (key.length-offset < len) {
throw new IllegalArgumentException
("Invalid offset/length combination");
}
if (len < 0) {
throw new ArrayIndexOutOfBoundsException("len is negative");
}
this.key = new byte[len];
System.arraycopy(key, offset, this.key, 0, len);
this.algorithm = algorithm;
}
/**
* Returns the name of the algorithm associated with this secret key.
*
* @return the secret key algorithm.
*/
public String getAlgorithm() {
return this.algorithm;
}
/**
* Returns the name of the encoding format for this secret key.
*
* @return the string "RAW".
*/
public String getFormat() {
return "RAW";
}
/**
* Returns the key material of this secret key.
*
* @return the key material. Returns a new array
* each time this method is called.
*/
public byte[] getEncoded() {
return this.key.clone();
}
/**
* Calculates a hash code value for the object.
* Objects that are equal will also have the same hashcode.
*/
public int hashCode() {
int retval = 0;
for (int i = 1; i < this.key.length; i++) {
retval += this.key[i] * i;
}
if (this.algorithm.equalsIgnoreCase("TripleDES"))
return (retval ^= "desede".hashCode());
else
return (retval ^=
this.algorithm.toLowerCase(Locale.ENGLISH).hashCode());
}
/**
* Tests for equality between the specified object and this
* object. Two SecretKeySpec objects are considered equal if
* they are both SecretKey instances which have the
* same case-insensitive algorithm name and key encoding.
*
* @param obj the object to test for equality with this object.
*
* @return true if the objects are considered equal, false if
* <code>obj</code> is null or otherwise.
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof SecretKey))
return false;
String thatAlg = ((SecretKey)obj).getAlgorithm();
if (!(thatAlg.equalsIgnoreCase(this.algorithm))) {
if ((!(thatAlg.equalsIgnoreCase("DESede"))
|| !(this.algorithm.equalsIgnoreCase("TripleDES")))
&& (!(thatAlg.equalsIgnoreCase("TripleDES"))
|| !(this.algorithm.equalsIgnoreCase("DESede"))))
return false;
}
byte[] thatKey = ((SecretKey)obj).getEncoded();
return MessageDigest.isEqual(this.key, thatKey);
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 1999, 2017, 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.
*/
/**
* Provides classes and interfaces for key specifications and
* algorithm parameter specifications.
*
* <p>A key specification is a transparent representation of the key
* material that constitutes a key. A key may be specified in an
* algorithm-specific way, or in an algorithm-independent encoding
* format (such as ASN.1). This package contains key specifications
* for Diffie-Hellman public and private keys, as well as key
* specifications for DES, Triple DES, and PBE secret keys.
*
* <p>An algorithm parameter specification is a transparent
* representation of the sets of parameters used with an
* algorithm. This package contains algorithm parameter specifications
* for parameters used with the Diffie-Hellman, DES, Triple DES, PBE,
* RC2 and RC5 algorithms.
*
*
* <ul>
* <li>PKCS #3: Diffie-Hellman Key-Agreement Standard, Version 1.4,
* November 1993.</li>
* <li>PKCS #5: Password-Based Encryption Standard, Version 1.5,
* November 1993.</li>
* <li>Federal Information Processing Standards Publication (FIPS PUB) 46-2:
* Data Encryption Standard (DES) </li>
* </ul>
*
* <h2>Related Documentation</h2>
*
* For documentation that includes information about algorithm
* parameter and key specifications, please see:
*
* <ul>
* <li>
* {@extLink security_guide_jca
* Java Cryptography Architecture (JCA) Reference Guide} </li>
* <li>
* {@extLink security_guide_impl_provider
* How to Implement a Provider in the Java Cryptography Architecture}</li>
* </ul>
*
* @since 1.4
*/
package javax.crypto.spec;

View file

@ -0,0 +1,233 @@
/*
* Copyright (c) 1997, 2007, 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 javax.net;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.SocketException;
/**
* This class creates server sockets. It may be subclassed by other
* factories, which create particular types of server sockets. This
* provides a general framework for the addition of public socket-level
* functionality. It is the server side analogue of a socket factory,
* and similarly provides a way to capture a variety of policies related
* to the sockets being constructed.
*
* <P> Like socket factories, server Socket factory instances have
* methods used to create sockets. There is also an environment
* specific default server socket factory; frameworks will often use
* their own customized factory.
*
* @since 1.4
* @see SocketFactory
*
* @author David Brownell
*/
public abstract class ServerSocketFactory
{
//
// NOTE: JDK 1.1 bug in class GC, this can get collected
// even though it's always accessible via getDefault().
//
private static ServerSocketFactory theFactory;
/**
* Creates a server socket factory.
*/
protected ServerSocketFactory() { /* NOTHING */ }
/**
* Returns a copy of the environment's default socket factory.
*
* @return the <code>ServerSocketFactory</code>
*/
public static ServerSocketFactory getDefault()
{
synchronized (ServerSocketFactory.class) {
if (theFactory == null) {
//
// Different implementations of this method could
// work rather differently. For example, driving
// this from a system property, or using a different
// implementation than JavaSoft's.
//
theFactory = new DefaultServerSocketFactory();
}
}
return theFactory;
}
/**
* Returns an unbound server socket. The socket is configured with
* the socket options (such as accept timeout) given to this factory.
*
* @return the unbound socket
* @throws IOException if the socket cannot be created
* @see java.net.ServerSocket#bind(java.net.SocketAddress)
* @see java.net.ServerSocket#bind(java.net.SocketAddress, int)
* @see java.net.ServerSocket#ServerSocket()
*/
public ServerSocket createServerSocket() throws IOException {
throw new SocketException("Unbound server sockets not implemented");
}
/**
* Returns a server socket bound to the specified port.
* The socket is configured with the socket options
* (such as accept timeout) given to this factory.
* <P>
* If there is a security manager, its <code>checkListen</code>
* method is called with the <code>port</code> argument as its
* argument to ensure the operation is allowed. This could result
* in a SecurityException.
*
* @param port the port to listen to
* @return the <code>ServerSocket</code>
* @throws IOException for networking errors
* @throws SecurityException if a security manager exists and its
* <code>checkListen</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkListen
* @see java.net.ServerSocket#ServerSocket(int)
*/
public abstract ServerSocket createServerSocket(int port)
throws IOException;
/**
* Returns a server socket bound to the specified port, and uses the
* specified connection backlog. The socket is configured with
* the socket options (such as accept timeout) given to this factory.
* <P>
* The <code>backlog</code> argument must be a positive
* value greater than 0. If the value passed if equal or less
* than 0, then the default value will be assumed.
* <P>
* If there is a security manager, its <code>checkListen</code>
* method is called with the <code>port</code> argument as its
* argument to ensure the operation is allowed. This could result
* in a SecurityException.
*
* @param port the port to listen to
* @param backlog how many connections are queued
* @return the <code>ServerSocket</code>
* @throws IOException for networking errors
* @throws SecurityException if a security manager exists and its
* <code>checkListen</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkListen
* @see java.net.ServerSocket#ServerSocket(int, int)
*/
public abstract ServerSocket
createServerSocket(int port, int backlog)
throws IOException;
/**
* Returns a server socket bound to the specified port,
* with a specified listen backlog and local IP.
* <P>
* The <code>ifAddress</code> argument can be used on a multi-homed
* host for a <code>ServerSocket</code> that will only accept connect
* requests to one of its addresses. If <code>ifAddress</code> is null,
* it will accept connections on all local addresses. The socket is
* configured with the socket options (such as accept timeout) given
* to this factory.
* <P>
* The <code>backlog</code> argument must be a positive
* value greater than 0. If the value passed if equal or less
* than 0, then the default value will be assumed.
* <P>
* If there is a security manager, its <code>checkListen</code>
* method is called with the <code>port</code> argument as its
* argument to ensure the operation is allowed. This could result
* in a SecurityException.
*
* @param port the port to listen to
* @param backlog how many connections are queued
* @param ifAddress the network interface address to use
* @return the <code>ServerSocket</code>
* @throws IOException for networking errors
* @throws SecurityException if a security manager exists and its
* <code>checkListen</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkListen
* @see java.net.ServerSocket#ServerSocket(int, int, java.net.InetAddress)
*/
public abstract ServerSocket
createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException;
}
//
// The default factory has NO intelligence. In fact it's not clear
// what sort of intelligence servers need; the onus is on clients,
// who have to know how to tunnel etc.
//
class DefaultServerSocketFactory extends ServerSocketFactory {
DefaultServerSocketFactory()
{
/* NOTHING */
}
public ServerSocket createServerSocket()
throws IOException
{
return new ServerSocket();
}
public ServerSocket createServerSocket(int port)
throws IOException
{
return new ServerSocket(port);
}
public ServerSocket createServerSocket(int port, int backlog)
throws IOException
{
return new ServerSocket(port, backlog);
}
public ServerSocket
createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException
{
return new ServerSocket(port, backlog, ifAddress);
}
}

View file

@ -0,0 +1,293 @@
/*
* Copyright (c) 1997, 2010, 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 javax.net;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
/**
* This class creates sockets. It may be subclassed by other factories,
* which create particular subclasses of sockets and thus provide a general
* framework for the addition of public socket-level functionality.
*
* <P> Socket factories are a simple way to capture a variety of policies
* related to the sockets being constructed, producing such sockets in
* a way which does not require special configuration of the code which
* asks for the sockets: <UL>
*
* <LI> Due to polymorphism of both factories and sockets, different
* kinds of sockets can be used by the same application code just
* by passing it different kinds of factories.
*
* <LI> Factories can themselves be customized with parameters used
* in socket construction. So for example, factories could be
* customized to return sockets with different networking timeouts
* or security parameters already configured.
*
* <LI> The sockets returned to the application can be subclasses
* of java.net.Socket, so that they can directly expose new APIs
* for features such as compression, security, record marking,
* statistics collection, or firewall tunneling.
*
* </UL>
*
* <P> Factory classes are specified by environment-specific configuration
* mechanisms. For example, the <em>getDefault</em> method could return
* a factory that was appropriate for a particular user or applet, and a
* framework could use a factory customized to its own purposes.
*
* @since 1.4
* @see ServerSocketFactory
*
* @author David Brownell
*/
public abstract class SocketFactory
{
//
// NOTE: JDK 1.1 bug in class GC, this can get collected
// even though it's always accessible via getDefault().
//
private static SocketFactory theFactory;
/**
* Creates a <code>SocketFactory</code>.
*/
protected SocketFactory() { /* NOTHING */ }
/**
* Returns a copy of the environment's default socket factory.
*
* @return the default <code>SocketFactory</code>
*/
public static SocketFactory getDefault()
{
synchronized (SocketFactory.class) {
if (theFactory == null) {
//
// Different implementations of this method SHOULD
// work rather differently. For example, driving
// this from a system property, or using a different
// implementation than JavaSoft's.
//
theFactory = new DefaultSocketFactory();
}
}
return theFactory;
}
/**
* Creates an unconnected socket.
*
* @return the unconnected socket
* @throws IOException if the socket cannot be created
* @see java.net.Socket#connect(java.net.SocketAddress)
* @see java.net.Socket#connect(java.net.SocketAddress, int)
* @see java.net.Socket#Socket()
*/
public Socket createSocket() throws IOException {
//
// bug 6771432:
// The Exception is used by HttpsClient to signal that
// unconnected sockets have not been implemented.
//
UnsupportedOperationException uop = new
UnsupportedOperationException();
SocketException se = new SocketException(
"Unconnected sockets not implemented");
se.initCause(uop);
throw se;
}
/**
* Creates a socket and connects it to the specified remote host
* at the specified remote port. This socket is configured using
* the socket options established for this factory.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param host the server host name with which to connect, or
* <code>null</code> for the loopback address.
* @param port the server port
* @return the <code>Socket</code>
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws UnknownHostException if the host is not known
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkConnect
* @see java.net.Socket#Socket(String, int)
*/
public abstract Socket createSocket(String host, int port)
throws IOException, UnknownHostException;
/**
* Creates a socket and connects it to the specified remote host
* on the specified remote port.
* The socket will also be bound to the local address and port supplied.
* This socket is configured using
* the socket options established for this factory.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param host the server host name with which to connect, or
* <code>null</code> for the loopback address.
* @param port the server port
* @param localHost the local address the socket is bound to
* @param localPort the local port the socket is bound to
* @return the <code>Socket</code>
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws UnknownHostException if the host is not known
* @throws IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
* @see SecurityManager#checkConnect
* @see java.net.Socket#Socket(String, int, java.net.InetAddress, int)
*/
public abstract Socket
createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException, UnknownHostException;
/**
* Creates a socket and connects it to the specified port number
* at the specified address. This socket is configured using
* the socket options established for this factory.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param host the server host
* @param port the server port
* @return the <code>Socket</code>
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @throws NullPointerException if <code>host</code> is null.
* @see SecurityManager#checkConnect
* @see java.net.Socket#Socket(java.net.InetAddress, int)
*/
public abstract Socket createSocket(InetAddress host, int port)
throws IOException;
/**
* Creates a socket and connect it to the specified remote address
* on the specified remote port. The socket will also be bound
* to the local address and port suplied. The socket is configured using
* the socket options established for this factory.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param address the server network address
* @param port the server port
* @param localAddress the client network address
* @param localPort the client port
* @return the <code>Socket</code>
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
* @throws NullPointerException if <code>address</code> is null.
* @see SecurityManager#checkConnect
* @see java.net.Socket#Socket(java.net.InetAddress, int,
* java.net.InetAddress, int)
*/
public abstract Socket
createSocket(InetAddress address, int port,
InetAddress localAddress, int localPort)
throws IOException;
}
//
// The default factory has NO intelligence about policies like tunneling
// out through firewalls (e.g. SOCKS V4 or V5) or in through them
// (e.g. using SSL), or that some ports are reserved for use with SSL.
//
// Note that at least JDK 1.1 has a low level "plainSocketImpl" that
// knows about SOCKS V4 tunneling, so this isn't a totally bogus default.
//
// ALSO: we may want to expose this class somewhere so other folk
// can reuse it, particularly if we start to add highly useful features
// such as ability to set connect timeouts.
//
class DefaultSocketFactory extends SocketFactory {
public Socket createSocket() {
return new Socket();
}
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException
{
return new Socket(host, port);
}
public Socket createSocket(InetAddress address, int port)
throws IOException
{
return new Socket(address, port);
}
public Socket createSocket(String host, int port,
InetAddress clientAddress, int clientPort)
throws IOException, UnknownHostException
{
return new Socket(host, port, clientAddress, clientPort);
}
public Socket createSocket(InetAddress address, int port,
InetAddress clientAddress, int clientPort)
throws IOException
{
return new Socket(address, port, clientAddress, clientPort);
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 1999, 2001, 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.
*/
/**
* Provides classes for networking applications. These classes include
* factories for creating sockets. Using socket factories you can
* encapsulate socket creation and configuration behavior.
*
* @since 1.4
*/
package javax.net;

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2003, 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 javax.net.ssl;
import java.security.cert.CertPathParameters;
/**
* A wrapper for CertPathParameters. This class is used to pass validation
* settings to CertPath based {@link TrustManager}s using the
* {@link TrustManagerFactory#init(ManagerFactoryParameters)
* TrustManagerFactory.init()} method.
*
* <p>Instances of this class are immutable.
*
* @see X509TrustManager
* @see TrustManagerFactory
* @see java.security.cert.CertPathParameters
*
* @since 1.5
* @author Andreas Sterbenz
*/
public class CertPathTrustManagerParameters implements ManagerFactoryParameters {
private final CertPathParameters parameters;
/**
* Construct new CertPathTrustManagerParameters from the specified
* parameters. The parameters are cloned to protect against subsequent
* modification.
*
* @param parameters the CertPathParameters to be used
*
* @throws NullPointerException if parameters is null
*/
public CertPathTrustManagerParameters(CertPathParameters parameters) {
this.parameters = (CertPathParameters)parameters.clone();
}
/**
* Return a clone of the CertPathParameters encapsulated by this class.
*
* @return a clone of the CertPathParameters encapsulated by this class.
*/
public CertPathParameters getParameters() {
return (CertPathParameters)parameters.clone();
}
}

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2010, 2017, 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 javax.net.ssl;
import java.util.List;
/**
* Extends the {@code SSLSession} interface to support additional
* session attributes.
*
* @since 1.7
*/
public abstract class ExtendedSSLSession implements SSLSession {
/**
* Obtains an array of supported signature algorithms that the local side
* is willing to use.
* <p>
* Note: this method is used to indicate to the peer which signature
* algorithms may be used for digital signatures in TLS/DTLS 1.2. It is
* not meaningful for TLS/DTLS versions prior to 1.2.
* <p>
* The signature algorithm name must be a standard Java Security
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
* <p>
* Note: the local supported signature algorithms should conform to
* the algorithm constraints specified by
* {@link SSLParameters#getAlgorithmConstraints getAlgorithmConstraints()}
* method in {@code SSLParameters}.
*
* @return An array of supported signature algorithms, in descending
* order of preference. The return value is an empty array if
* no signature algorithm is supported.
*
* @see SSLParameters#getAlgorithmConstraints
*/
public abstract String[] getLocalSupportedSignatureAlgorithms();
/**
* Obtains an array of supported signature algorithms that the peer is
* able to use.
* <p>
* Note: this method is used to indicate to the local side which signature
* algorithms may be used for digital signatures in TLS/DTLS 1.2. It is
* not meaningful for TLS/DTLS versions prior to 1.2.
* <p>
* The signature algorithm name must be a standard Java Security
* name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @return An array of supported signature algorithms, in descending
* order of preference. The return value is an empty array if
* the peer has not sent the supported signature algorithms.
*
* @see X509KeyManager
* @see X509ExtendedKeyManager
*/
public abstract String[] getPeerSupportedSignatureAlgorithms();
/**
* Obtains a {@link List} containing all {@link SNIServerName}s
* of the requested Server Name Indication (SNI) extension.
* <P>
* In server mode, unless the return {@link List} is empty,
* the server should use the requested server names to guide its
* selection of an appropriate authentication certificate, and/or
* other aspects of security policy.
* <P>
* In client mode, unless the return {@link List} is empty,
* the client should use the requested server names to guide its
* endpoint identification of the peer's identity, and/or
* other aspects of security policy.
*
* @return a non-null immutable list of {@link SNIServerName}s of the
* requested server name indications. The returned list may be
* empty if no server name indications were requested.
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation
*
* @see SNIServerName
* @see X509ExtendedTrustManager
* @see X509ExtendedKeyManager
*
* @since 1.8
*/
public List<SNIServerName> getRequestedServerNames() {
throw new UnsupportedOperationException();
}
/**
* Returns a {@link List} containing DER-encoded OCSP responses
* (using the ASN.1 type OCSPResponse defined in RFC 6960) for
* the client to verify status of the server's certificate during
* handshaking.
*
* <P>
* This method only applies to certificate-based server
* authentication. An {@link X509ExtendedTrustManager} will use the
* returned value for server certificate validation.
*
* @implSpec This method throws UnsupportedOperationException by default.
* Classes derived from ExtendedSSLSession must implement
* this method.
*
* @return a non-null unmodifiable list of byte arrays, each entry
* containing a DER-encoded OCSP response (using the
* ASN.1 type OCSPResponse defined in RFC 6960). The order
* of the responses must match the order of the certificates
* presented by the server in its Certificate message (See
* {@link SSLSession#getLocalCertificates()} for server mode,
* and {@link SSLSession#getPeerCertificates()} for client mode).
* It is possible that fewer response entries may be returned than
* the number of presented certificates. If an entry in the list
* is a zero-length byte array, it should be treated by the
* caller as if the OCSP entry for the corresponding certificate
* is missing. The returned list may be empty if no OCSP responses
* were presented during handshaking or if OCSP stapling is not
* supported by either endpoint for this handshake.
*
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation
*
* @see X509ExtendedTrustManager
*
* @since 9
*/
public List<byte[]> getStatusResponses() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,245 @@
/*
* Copyright (c) 1997, 2017, 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 javax.net.ssl;
import java.util.EventObject;
import java.security.cert.Certificate;
import java.security.Principal;
import java.security.cert.X509Certificate;
/**
* This event indicates that an SSL handshake completed on a given
* SSL connection. All of the core information about that handshake's
* result is captured through an "SSLSession" object. As a convenience,
* this event class provides direct access to some important session
* attributes.
*
* <P> The source of this event is the SSLSocket on which handshaking
* just completed.
*
* @see SSLSocket
* @see HandshakeCompletedListener
* @see SSLSession
*
* @since 1.4
* @author David Brownell
*/
public class HandshakeCompletedEvent extends EventObject
{
private static final long serialVersionUID = 7914963744257769778L;
private transient SSLSession session;
/**
* Constructs a new HandshakeCompletedEvent.
*
* @param sock the SSLSocket acting as the source of the event
* @param s the SSLSession this event is associated with
*/
public HandshakeCompletedEvent(SSLSocket sock, SSLSession s)
{
super(sock);
session = s;
}
/**
* Returns the session that triggered this event.
*
* @return the <code>SSLSession</code> for this handshake
*/
public SSLSession getSession()
{
return session;
}
/**
* Returns the cipher suite in use by the session which was produced
* by the handshake. (This is a convenience method for
* getting the ciphersuite from the SSLsession.)
*
* @return the name of the cipher suite negotiated during this session.
*/
public String getCipherSuite()
{
return session.getCipherSuite();
}
/**
* Returns the certificate(s) that were sent to the peer during
* handshaking.
* Note: This method is useful only when using certificate-based
* cipher suites.
*
* When multiple certificates are available for use in a
* handshake, the implementation chooses what it considers the
* "best" certificate chain available, and transmits that to
* the other side. This method allows the caller to know
* which certificate chain was actually used.
*
* @return an ordered array of certificates, with the local
* certificate first followed by any
* certificate authorities. If no certificates were sent,
* then null is returned.
* @see #getLocalPrincipal()
*/
public java.security.cert.Certificate [] getLocalCertificates()
{
return session.getLocalCertificates();
}
/**
* Returns the identity of the peer which was established as part
* of defining the session.
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* @return an ordered array of the peer certificates,
* with the peer's own certificate first followed by
* any certificate authorities.
* @exception SSLPeerUnverifiedException if the peer is not verified.
* @see #getPeerPrincipal()
*/
public java.security.cert.Certificate [] getPeerCertificates()
throws SSLPeerUnverifiedException
{
return session.getPeerCertificates();
}
/**
* Returns the identity of the peer which was identified as part
* of defining the session.
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* <p><em>Note: this method exists for compatibility with previous
* releases. New applications should use
* {@link #getPeerCertificates} instead.</em></p>
*
* @return an ordered array of peer X.509 certificates,
* with the peer's own certificate first followed by any
* certificate authorities. (The certificates are in
* the original JSSE
* {@link javax.security.cert.X509Certificate} format).
* @exception SSLPeerUnverifiedException if the peer is not verified.
* @see #getPeerPrincipal()
* @deprecated The {@link #getPeerCertificates()} method that returns an
* array of {@code java.security.cert.Certificate} should
* be used instead.
*/
@Deprecated(since="9")
public javax.security.cert.X509Certificate [] getPeerCertificateChain()
throws SSLPeerUnverifiedException
{
return session.getPeerCertificateChain();
}
/**
* Returns the identity of the peer which was established as part of
* defining the session.
*
* @return the peer's principal. Returns an X500Principal of the
* end-entity certiticate for X509-based cipher suites, and
* KerberosPrincipal for Kerberos cipher suites.
*
* @throws SSLPeerUnverifiedException if the peer's identity has not
* been verified
*
* @see #getPeerCertificates()
* @see #getLocalPrincipal()
*
* @since 1.5
*/
public Principal getPeerPrincipal()
throws SSLPeerUnverifiedException
{
Principal principal;
try {
principal = session.getPeerPrincipal();
} catch (AbstractMethodError e) {
// if the provider does not support it, fallback to peer certs.
// return the X500Principal of the end-entity cert.
Certificate[] certs = getPeerCertificates();
principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
}
return principal;
}
/**
* Returns the principal that was sent to the peer during handshaking.
*
* @return the principal sent to the peer. Returns an X500Principal
* of the end-entity certificate for X509-based cipher suites, and
* KerberosPrincipal for Kerberos cipher suites. If no principal was
* sent, then null is returned.
*
* @see #getLocalCertificates()
* @see #getPeerPrincipal()
*
* @since 1.5
*/
public Principal getLocalPrincipal()
{
Principal principal;
try {
principal = session.getLocalPrincipal();
} catch (AbstractMethodError e) {
principal = null;
// if the provider does not support it, fallback to local certs.
// return the X500Principal of the end-entity cert.
Certificate[] certs = getLocalCertificates();
if (certs != null) {
principal =
((X509Certificate)certs[0]).getSubjectX500Principal();
}
}
return principal;
}
/**
* Returns the socket which is the source of this event.
* (This is a convenience function, to let applications
* write code without type casts.)
*
* @return the socket on which the connection was made.
*/
public SSLSocket getSocket()
{
return (SSLSocket) getSource();
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 1997, 2001, 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 javax.net.ssl;
import java.util.EventListener;
/**
* This interface is implemented by any class which wants to receive
* notifications about the completion of an SSL protocol handshake
* on a given SSL connection.
*
* <P> When an SSL handshake completes, new security parameters will
* have been established. Those parameters always include the security
* keys used to protect messages. They may also include parameters
* associated with a new <em>session</em> such as authenticated
* peer identity and a new SSL cipher suite.
*
* @since 1.4
* @author David Brownell
*/
public interface HandshakeCompletedListener extends EventListener
{
/**
* This method is invoked on registered objects
* when a SSL handshake is completed.
*
* @param event the event identifying when the SSL Handshake
* completed on a given SSL connection
*/
void handshakeCompleted(HandshakeCompletedEvent event);
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2001, 2012, 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 javax.net.ssl;
/**
* This class is the base interface for hostname verification.
* <P>
* During handshaking, if the URL's hostname and
* the server's identification hostname mismatch, the
* verification mechanism can call back to implementers of this
* interface to determine if this connection should be allowed.
* <P>
* The policies can be certificate-based
* or may depend on other authentication schemes.
* <P>
* These callbacks are used when the default rules for URL hostname
* verification fail.
*
* @author Brad R. Wetmore
* @since 1.4
*/
public interface HostnameVerifier {
/**
* Verify that the host name is an acceptable match with
* the server's authentication scheme.
*
* @param hostname the host name
* @param session SSLSession used on the connection to host
* @return true if the host name is acceptable
*/
public boolean verify(String hostname, SSLSession session);
}

View file

@ -0,0 +1,381 @@
/*
* Copyright (c) 1999, 2016, 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 javax.net.ssl;
import java.net.URL;
import java.net.HttpURLConnection;
import java.security.Principal;
import java.security.cert.X509Certificate;
/**
* <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
* with support for https-specific features.
* <P>
* See <A HREF="http://www.w3.org/pub/WWW/Protocols/">
* http://www.w3.org/pub/WWW/Protocols/</A> and
* <A HREF="http://www.ietf.org/"> RFC 2818 </A>
* for more details on the
* https specification.
* <P>
* This class uses <code>HostnameVerifier</code> and
* <code>SSLSocketFactory</code>.
* There are default implementations defined for both classes.
* However, the implementations can be replaced on a per-class (static) or
* per-instance basis. All new <code>HttpsURLConnection</code>s instances
* will be assigned
* the "default" static values at instance creation, but they can be overriden
* by calling the appropriate per-instance set method(s) before
* <code>connect</code>ing.
*
* @since 1.4
*/
public abstract
class HttpsURLConnection extends HttpURLConnection
{
/**
* Creates an <code>HttpsURLConnection</code> using the
* URL specified.
*
* @param url the URL
*/
protected HttpsURLConnection(URL url) {
super(url);
}
/**
* Returns the cipher suite in use on this connection.
*
* @return the cipher suite
* @throws IllegalStateException if this method is called before
* the connection has been established.
*/
public abstract String getCipherSuite();
/**
* Returns the certificate(s) that were sent to the server during
* handshaking.
* <P>
* Note: This method is useful only when using certificate-based
* cipher suites.
* <P>
* When multiple certificates are available for use in a
* handshake, the implementation chooses what it considers the
* "best" certificate chain available, and transmits that to
* the other side. This method allows the caller to know
* which certificate chain was actually sent.
*
* @return an ordered array of certificates,
* with the client's own certificate first followed by any
* certificate authorities. If no certificates were sent,
* then null is returned.
* @throws IllegalStateException if this method is called before
* the connection has been established.
* @see #getLocalPrincipal()
*/
public abstract java.security.cert.Certificate [] getLocalCertificates();
/**
* Returns the server's certificate chain which was established
* as part of defining the session.
* <P>
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* @return an ordered array of server certificates,
* with the peer's own certificate first followed by
* any certificate authorities.
* @throws SSLPeerUnverifiedException if the peer is not verified.
* @throws IllegalStateException if this method is called before
* the connection has been established.
* @see #getPeerPrincipal()
*/
public abstract java.security.cert.Certificate [] getServerCertificates()
throws SSLPeerUnverifiedException;
/**
* Returns the server's principal which was established as part of
* defining the session.
* <P>
* Note: Subclasses should override this method. If not overridden, it
* will default to returning the X500Principal of the server's end-entity
* certificate for certificate-based ciphersuites, or throw an
* SSLPeerUnverifiedException for non-certificate based ciphersuites,
* such as Kerberos.
*
* @return the server's principal. Returns an X500Principal of the
* end-entity certiticate for X509-based cipher suites, and
* KerberosPrincipal for Kerberos cipher suites.
*
* @throws SSLPeerUnverifiedException if the peer was not verified
* @throws IllegalStateException if this method is called before
* the connection has been established.
*
* @see #getServerCertificates()
* @see #getLocalPrincipal()
*
* @since 1.5
*/
public Principal getPeerPrincipal()
throws SSLPeerUnverifiedException {
java.security.cert.Certificate[] certs = getServerCertificates();
return ((X509Certificate)certs[0]).getSubjectX500Principal();
}
/**
* Returns the principal that was sent to the server during handshaking.
* <P>
* Note: Subclasses should override this method. If not overridden, it
* will default to returning the X500Principal of the end-entity certificate
* that was sent to the server for certificate-based ciphersuites or,
* return null for non-certificate based ciphersuites, such as Kerberos.
*
* @return the principal sent to the server. Returns an X500Principal
* of the end-entity certificate for X509-based cipher suites, and
* KerberosPrincipal for Kerberos cipher suites. If no principal was
* sent, then null is returned.
*
* @throws IllegalStateException if this method is called before
* the connection has been established.
*
* @see #getLocalCertificates()
* @see #getPeerPrincipal()
*
* @since 1.5
*/
public Principal getLocalPrincipal() {
java.security.cert.Certificate[] certs = getLocalCertificates();
if (certs != null) {
return ((X509Certificate)certs[0]).getSubjectX500Principal();
} else {
return null;
}
}
/**
* <code>HostnameVerifier</code> provides a callback mechanism so that
* implementers of this interface can supply a policy for
* handling the case where the host to connect to and
* the server name from the certificate mismatch.
* <p>
* The default implementation will deny such connections.
*/
private static HostnameVerifier defaultHostnameVerifier =
new DefaultHostnameVerifier();
/*
* The initial default <code>HostnameVerifier</code>. Should be
* updated for another other type of <code>HostnameVerifier</code>
* that are created.
*/
private static class DefaultHostnameVerifier
implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return false;
}
}
/**
* The <code>hostnameVerifier</code> for this object.
*/
protected HostnameVerifier hostnameVerifier = defaultHostnameVerifier;
/**
* Sets the default <code>HostnameVerifier</code> inherited by a
* new instance of this class.
* <P>
* If this method is not called, the default
* <code>HostnameVerifier</code> assumes the connection should not
* be permitted.
*
* @param v the default host name verifier
* @throws IllegalArgumentException if the <code>HostnameVerifier</code>
* parameter is null.
* @throws SecurityException if a security manager exists and its
* <code>checkPermission</code> method does not allow
* <code>SSLPermission("setHostnameVerifier")</code>
* @see #getDefaultHostnameVerifier()
*/
public static void setDefaultHostnameVerifier(HostnameVerifier v) {
if (v == null) {
throw new IllegalArgumentException(
"no default HostnameVerifier specified");
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SSLPermission("setHostnameVerifier"));
}
defaultHostnameVerifier = v;
}
/**
* Gets the default <code>HostnameVerifier</code> that is inherited
* by new instances of this class.
*
* @return the default host name verifier
* @see #setDefaultHostnameVerifier(HostnameVerifier)
*/
public static HostnameVerifier getDefaultHostnameVerifier() {
return defaultHostnameVerifier;
}
/**
* Sets the <code>HostnameVerifier</code> for this instance.
* <P>
* New instances of this class inherit the default static hostname
* verifier set by {@link #setDefaultHostnameVerifier(HostnameVerifier)
* setDefaultHostnameVerifier}. Calls to this method replace
* this object's <code>HostnameVerifier</code>.
*
* @param v the host name verifier
* @throws IllegalArgumentException if the <code>HostnameVerifier</code>
* parameter is null.
* @see #getHostnameVerifier()
* @see #setDefaultHostnameVerifier(HostnameVerifier)
*/
public void setHostnameVerifier(HostnameVerifier v) {
if (v == null) {
throw new IllegalArgumentException(
"no HostnameVerifier specified");
}
hostnameVerifier = v;
}
/**
* Gets the <code>HostnameVerifier</code> in place on this instance.
*
* @return the host name verifier
* @see #setHostnameVerifier(HostnameVerifier)
* @see #setDefaultHostnameVerifier(HostnameVerifier)
*/
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}
private static SSLSocketFactory defaultSSLSocketFactory = null;
/**
* The <code>SSLSocketFactory</code> inherited when an instance
* of this class is created.
*/
private SSLSocketFactory sslSocketFactory = getDefaultSSLSocketFactory();
/**
* Sets the default <code>SSLSocketFactory</code> inherited by new
* instances of this class.
* <P>
* The socket factories are used when creating sockets for secure
* https URL connections.
*
* @param sf the default SSL socket factory
* @throws IllegalArgumentException if the SSLSocketFactory
* parameter is null.
* @throws SecurityException if a security manager exists and its
* <code>checkSetFactory</code> method does not allow
* a socket factory to be specified.
* @see #getDefaultSSLSocketFactory()
*/
public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
if (sf == null) {
throw new IllegalArgumentException(
"no default SSLSocketFactory specified");
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkSetFactory();
}
defaultSSLSocketFactory = sf;
}
/**
* Gets the default static <code>SSLSocketFactory</code> that is
* inherited by new instances of this class.
* <P>
* The socket factories are used when creating sockets for secure
* https URL connections.
*
* @return the default <code>SSLSocketFactory</code>
* @see #setDefaultSSLSocketFactory(SSLSocketFactory)
*/
public static SSLSocketFactory getDefaultSSLSocketFactory() {
if (defaultSSLSocketFactory == null) {
defaultSSLSocketFactory =
(SSLSocketFactory)SSLSocketFactory.getDefault();
}
return defaultSSLSocketFactory;
}
/**
* Sets the <code>SSLSocketFactory</code> to be used when this instance
* creates sockets for secure https URL connections.
* <P>
* New instances of this class inherit the default static
* <code>SSLSocketFactory</code> set by
* {@link #setDefaultSSLSocketFactory(SSLSocketFactory)
* setDefaultSSLSocketFactory}. Calls to this method replace
* this object's <code>SSLSocketFactory</code>.
*
* @param sf the SSL socket factory
* @throws IllegalArgumentException if the <code>SSLSocketFactory</code>
* parameter is null.
* @throws SecurityException if a security manager exists and its
* <code>checkSetFactory</code> method does not allow
* a socket factory to be specified.
* @see #getSSLSocketFactory()
*/
public void setSSLSocketFactory(SSLSocketFactory sf) {
if (sf == null) {
throw new IllegalArgumentException(
"no SSLSocketFactory specified");
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkSetFactory();
}
sslSocketFactory = sf;
}
/**
* Gets the SSL socket factory to be used when creating sockets
* for secure https URL connections.
*
* @return the <code>SSLSocketFactory</code>
* @see #setSSLSocketFactory(SSLSocketFactory)
*/
public SSLSocketFactory getSSLSocketFactory() {
return sslSocketFactory;
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 1999, 2003, 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 javax.net.ssl;
/**
* This is the base interface for JSSE key managers.
* <P>
* <code>KeyManager</code>s are responsible for managing the
* key material which is used to authenticate the local SSLSocket
* to its peer. If no key material is available, the socket will
* be unable to present authentication credentials.
* <P>
* <code>KeyManager</code>s are created by either
* using a <code>KeyManagerFactory</code>,
* or by implementing one of the <code>KeyManager</code> subclasses.
*
* @since 1.4
* @see KeyManagerFactory
*/
public interface KeyManager {
}

View file

@ -0,0 +1,306 @@
/*
* Copyright (c) 1999, 2017, 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 javax.net.ssl;
import java.security.Security;
import java.security.*;
import java.util.Objects;
import sun.security.jca.GetInstance;
/**
* This class acts as a factory for key managers based on a
* source of key material. Each key manager manages a specific
* type of key material for use by secure sockets. The key
* material is based on a KeyStore and/or provider specific sources.
*
* @since 1.4
* @see KeyManager
*/
public class KeyManagerFactory {
// The provider
private Provider provider;
// The provider implementation (delegate)
private KeyManagerFactorySpi factorySpi;
// The name of the key management algorithm.
private String algorithm;
/**
* Obtains the default KeyManagerFactory algorithm name.
*
* <p>The default algorithm can be changed at runtime by setting
* the value of the {@code ssl.KeyManagerFactory.algorithm}
* security property to the desired algorithm name.
*
* @see java.security.Security security properties
* @return the default algorithm name as specified by the
* {@code ssl.KeyManagerFactory.algorithm} security property, or an
* implementation-specific default if no such property exists.
*/
public static final String getDefaultAlgorithm() {
String type;
type = AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public String run() {
return Security.getProperty(
"ssl.KeyManagerFactory.algorithm");
}
});
if (type == null) {
type = "SunX509";
}
return type;
}
/**
* Creates a KeyManagerFactory object.
*
* @param factorySpi the delegate
* @param provider the provider
* @param algorithm the algorithm
*/
protected KeyManagerFactory(KeyManagerFactorySpi factorySpi,
Provider provider, String algorithm) {
this.factorySpi = factorySpi;
this.provider = provider;
this.algorithm = algorithm;
}
/**
* Returns the algorithm name of this <code>KeyManagerFactory</code> object.
*
* <p>This is the same name that was specified in one of the
* <code>getInstance</code> calls that created this
* <code>KeyManagerFactory</code> object.
*
* @return the algorithm name of this <code>KeyManagerFactory</code> object.
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns a <code>KeyManagerFactory</code> object that acts as a
* factory for key managers.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new KeyManagerFactory object encapsulating the
* KeyManagerFactorySpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard name of the requested algorithm.
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @return the new {@code KeyManagerFactory} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code KeyManagerFactorySpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyManagerFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("KeyManagerFactory", KeyManagerFactorySpi.class,
algorithm);
return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a <code>KeyManagerFactory</code> object that acts as a
* factory for key managers.
*
* <p> A new KeyManagerFactory object encapsulating the
* KeyManagerFactorySpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
* @param algorithm the standard name of the requested algorithm.
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new {@code KeyManagerFactory} object
*
* @throws IllegalArgumentException if the provider name is {@code null}
* or empty
*
* @throws NoSuchAlgorithmException if a {@code KeyManagerFactorySpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyManagerFactory getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("KeyManagerFactory", KeyManagerFactorySpi.class,
algorithm, provider);
return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a <code>KeyManagerFactory</code> object that acts as a
* factory for key managers.
*
* <p> A new KeyManagerFactory object encapsulating the
* KeyManagerFactorySpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested algorithm.
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider an instance of the provider.
*
* @return the new {@code KeyManagerFactory} object
*
* @throws IllegalArgumentException if provider is {@code null}
*
* @throws NoSuchAlgorithmException if a {@code @KeyManagerFactorySpi}
* implementation for the specified algorithm is not available
* from the specified Provider object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final KeyManagerFactory getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("KeyManagerFactory", KeyManagerFactorySpi.class,
algorithm, provider);
return new KeyManagerFactory((KeyManagerFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the provider of this <code>KeyManagerFactory</code> object.
*
* @return the provider of this <code>KeyManagerFactory</code> object
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Initializes this factory with a source of key material.
* <P>
* The provider typically uses a KeyStore for obtaining
* key material for use during secure socket negotiations.
* The KeyStore is generally password-protected.
* <P>
* For more flexible initialization, please see
* {@link #init(ManagerFactoryParameters)}.
*
* @param ks the key store or null
* @param password the password for recovering keys in the KeyStore
* @throws KeyStoreException if this operation fails
* @throws NoSuchAlgorithmException if the specified algorithm is not
* available from the specified provider.
* @throws UnrecoverableKeyException if the key cannot be recovered
* (e.g. the given password is wrong).
*/
public final void init(KeyStore ks, char[] password) throws
KeyStoreException, NoSuchAlgorithmException,
UnrecoverableKeyException {
factorySpi.engineInit(ks, password);
}
/**
* Initializes this factory with a source of provider-specific
* key material.
* <P>
* In some cases, initialization parameters other than a keystore
* and password may be needed by a provider. Users of that
* particular provider are expected to pass an implementation of
* the appropriate <CODE>ManagerFactoryParameters</CODE> as
* defined by the provider. The provider can then call the
* specified methods in the <CODE>ManagerFactoryParameters</CODE>
* implementation to obtain the needed information.
*
* @param spec an implementation of a provider-specific parameter
* specification
* @throws InvalidAlgorithmParameterException if an error is encountered
*/
public final void init(ManagerFactoryParameters spec) throws
InvalidAlgorithmParameterException {
factorySpi.engineInit(spec);
}
/**
* Returns one key manager for each type of key material.
*
* @return the key managers
* @throws IllegalStateException if the KeyManagerFactory is not initialized
*/
public final KeyManager[] getKeyManagers() {
return factorySpi.engineGetKeyManagers();
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 1999, 2001, 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 javax.net.ssl;
import java.security.*;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>KeyManagerFactory</code> class.
*
* <p> All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a particular key manager factory.
*
* @since 1.4
* @see KeyManagerFactory
* @see KeyManager
*/
public abstract class KeyManagerFactorySpi {
/**
* Initializes this factory with a source of key material.
*
* @param ks the key store or null
* @param password the password for recovering keys
* @throws KeyStoreException if this operation fails
* @throws NoSuchAlgorithmException if the specified algorithm is not
* available from the specified provider.
* @throws UnrecoverableKeyException if the key cannot be recovered
* @see KeyManagerFactory#init(KeyStore, char[])
*/
protected abstract void engineInit(KeyStore ks, char[] password) throws
KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException;
/**
* Initializes this factory with a source of key material.
* <P>
* In some cases, initialization parameters other than a keystore
* and password may be needed by a provider. Users of that
* particular provider are expected to pass an implementation of
* the appropriate <CODE>ManagerFactoryParameters</CODE> as
* defined by the provider. The provider can then call the
* specified methods in the ManagerFactoryParameters
* implementation to obtain the needed information.
*
* @param spec an implementation of a provider-specific parameter
* specification
* @throws InvalidAlgorithmParameterException if there is problem
* with the parameters
* @see KeyManagerFactory#init(ManagerFactoryParameters spec)
*/
protected abstract void engineInit(ManagerFactoryParameters spec)
throws InvalidAlgorithmParameterException;
/**
* Returns one key manager for each type of key material.
*
* @return the key managers
* @throws IllegalStateException
* if the KeyManagerFactorySpi is not initialized
*/
protected abstract KeyManager[] engineGetKeyManagers();
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2003, 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 javax.net.ssl;
import java.util.*;
import java.security.KeyStore.*;
/**
* A parameters object for X509KeyManagers that encapsulates a List
* of KeyStore.Builders.
*
* @see java.security.KeyStore.Builder
* @see X509KeyManager
*
* @author Andreas Sterbenz
* @since 1.5
*/
public class KeyStoreBuilderParameters implements ManagerFactoryParameters {
private final List<Builder> parameters;
/**
* Construct new KeyStoreBuilderParameters from the specified
* {@linkplain java.security.KeyStore.Builder}.
*
* @param builder the Builder object
* @exception NullPointerException if builder is null
*/
public KeyStoreBuilderParameters(Builder builder) {
parameters = Collections.singletonList(Objects.requireNonNull(builder));
}
/**
* Construct new KeyStoreBuilderParameters from a List
* of {@linkplain java.security.KeyStore.Builder}s. Note that the list
* is cloned to protect against subsequent modification.
*
* @param parameters the List of Builder objects
* @exception NullPointerException if parameters is null
* @exception IllegalArgumentException if parameters is an empty list
*/
public KeyStoreBuilderParameters(List<Builder> parameters) {
if (parameters.isEmpty()) {
throw new IllegalArgumentException();
}
this.parameters = Collections.unmodifiableList(
new ArrayList<Builder>(parameters));
}
/**
* Return the unmodifiable List of the
* {@linkplain java.security.KeyStore.Builder}s
* encapsulated by this object.
*
* @return the unmodifiable List of the
* {@linkplain java.security.KeyStore.Builder}s
* encapsulated by this object.
*/
public List<Builder> getParameters() {
return parameters;
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2001, 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 javax.net.ssl;
/**
* This class is the base interface for providing
* algorithm-specific information to a KeyManagerFactory or
* TrustManagerFactory.
* <P>
* In some cases, initialization parameters other than keystores
* may be needed by a provider. Users of that particular provider
* are expected to pass an implementation of the appropriate
* sub-interface of this class as defined by the
* provider. The provider can then call the specified methods in
* the <CODE>ManagerFactoryParameters</CODE> implementation to obtain the
* needed information.
*
* @author Brad R. Wetmore
* @since 1.4
*/
public interface ManagerFactoryParameters {
}

View file

@ -0,0 +1,396 @@
/*
* Copyright (c) 2012, 2013, 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 javax.net.ssl;
import java.net.IDN;
import java.nio.ByteBuffer;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharacterCodingException;
import java.util.Locale;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* Instances of this class represent a server name of type
* {@link StandardConstants#SNI_HOST_NAME host_name} in a Server Name
* Indication (SNI) extension.
* <P>
* As described in section 3, "Server Name Indication", of
* <A HREF="http://www.ietf.org/rfc/rfc6066.txt">TLS Extensions (RFC 6066)</A>,
* "HostName" contains the fully qualified DNS hostname of the server, as
* understood by the client. The encoded server name value of a hostname is
* represented as a byte string using ASCII encoding without a trailing dot.
* This allows the support of Internationalized Domain Names (IDN) through
* the use of A-labels (the ASCII-Compatible Encoding (ACE) form of a valid
* string of Internationalized Domain Names for Applications (IDNA)) defined
* in <A HREF="http://www.ietf.org/rfc/rfc5890.txt">RFC 5890</A>.
* <P>
* Note that {@code SNIHostName} objects are immutable.
*
* @see SNIServerName
* @see StandardConstants#SNI_HOST_NAME
*
* @since 1.8
*/
public final class SNIHostName extends SNIServerName {
// the decoded string value of the server name
private final String hostname;
/**
* Creates an {@code SNIHostName} using the specified hostname.
* <P>
* Note that per <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
* the encoded server name value of a hostname is
* {@link StandardCharsets#US_ASCII}-compliant. In this method,
* {@code hostname} can be a user-friendly Internationalized Domain Name
* (IDN). {@link IDN#toASCII(String, int)} is used to enforce the
* restrictions on ASCII characters in hostnames (see
* <A HREF="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</A>,
* <A HREF="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</A>,
* <A HREF="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</A>) and
* translate the {@code hostname} into ASCII Compatible Encoding (ACE), as:
* <pre>
* IDN.toASCII(hostname, IDN.USE_STD3_ASCII_RULES);
* </pre>
* <P>
* The {@code hostname} argument is illegal if it:
* <ul>
* <li> {@code hostname} is empty,</li>
* <li> {@code hostname} ends with a trailing dot,</li>
* <li> {@code hostname} is not a valid Internationalized
* Domain Name (IDN) compliant with the RFC 3490 specification.</li>
* </ul>
* @param hostname
* the hostname of this server name
*
* @throws NullPointerException if {@code hostname} is {@code null}
* @throws IllegalArgumentException if {@code hostname} is illegal
*/
public SNIHostName(String hostname) {
// IllegalArgumentException will be thrown if {@code hostname} is
// not a valid IDN.
super(StandardConstants.SNI_HOST_NAME,
(hostname = IDN.toASCII(
Objects.requireNonNull(hostname,
"Server name value of host_name cannot be null"),
IDN.USE_STD3_ASCII_RULES))
.getBytes(StandardCharsets.US_ASCII));
this.hostname = hostname;
// check the validity of the string hostname
checkHostName();
}
/**
* Creates an {@code SNIHostName} using the specified encoded value.
* <P>
* This method is normally used to parse the encoded name value in a
* requested SNI extension.
* <P>
* Per <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
* the encoded name value of a hostname is
* {@link StandardCharsets#US_ASCII}-compliant. However, in the previous
* version of the SNI extension (
* <A HREF="http://www.ietf.org/rfc/rfc4366.txt">RFC 4366</A>),
* the encoded hostname is represented as a byte string using UTF-8
* encoding. For the purpose of version tolerance, this method allows
* that the charset of {@code encoded} argument can be
* {@link StandardCharsets#UTF_8}, as well as
* {@link StandardCharsets#US_ASCII}. {@link IDN#toASCII(String)} is used
* to translate the {@code encoded} argument into ASCII Compatible
* Encoding (ACE) hostname.
* <P>
* It is strongly recommended that this constructor is only used to parse
* the encoded name value in a requested SNI extension. Otherwise, to
* comply with <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>,
* please always use {@link StandardCharsets#US_ASCII}-compliant charset
* and enforce the restrictions on ASCII characters in hostnames (see
* <A HREF="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</A>,
* <A HREF="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</A>,
* <A HREF="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</A>)
* for {@code encoded} argument, or use
* {@link SNIHostName#SNIHostName(String)} instead.
* <P>
* The {@code encoded} argument is illegal if it:
* <ul>
* <li> {@code encoded} is empty,</li>
* <li> {@code encoded} ends with a trailing dot,</li>
* <li> {@code encoded} is not encoded in
* {@link StandardCharsets#US_ASCII} or
* {@link StandardCharsets#UTF_8}-compliant charset,</li>
* <li> {@code encoded} is not a valid Internationalized
* Domain Name (IDN) compliant with the RFC 3490 specification.</li>
* </ul>
*
* <P>
* Note that the {@code encoded} byte array is cloned
* to protect against subsequent modification.
*
* @param encoded
* the encoded hostname of this server name
*
* @throws NullPointerException if {@code encoded} is {@code null}
* @throws IllegalArgumentException if {@code encoded} is illegal
*/
public SNIHostName(byte[] encoded) {
// NullPointerException will be thrown if {@code encoded} is null
super(StandardConstants.SNI_HOST_NAME, encoded);
// Compliance: RFC 4366 requires that the hostname is represented
// as a byte string using UTF_8 encoding [UTF8]
try {
// Please don't use {@link String} constructors because they
// do not report coding errors.
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
this.hostname = IDN.toASCII(
decoder.decode(ByteBuffer.wrap(encoded)).toString());
} catch (RuntimeException | CharacterCodingException e) {
throw new IllegalArgumentException(
"The encoded server name value is invalid", e);
}
// check the validity of the string hostname
checkHostName();
}
/**
* Returns the {@link StandardCharsets#US_ASCII}-compliant hostname of
* this {@code SNIHostName} object.
* <P>
* Note that, per
* <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>, the
* returned hostname may be an internationalized domain name that
* contains A-labels. See
* <A HREF="http://www.ietf.org/rfc/rfc5890.txt">RFC 5890</A>
* for more information about the detailed A-label specification.
*
* @return the {@link StandardCharsets#US_ASCII}-compliant hostname
* of this {@code SNIHostName} object
*/
public String getAsciiName() {
return hostname;
}
/**
* Compares this server name to the specified object.
* <P>
* Per <A HREF="http://www.ietf.org/rfc/rfc6066.txt">RFC 6066</A>, DNS
* hostnames are case-insensitive. Two server hostnames are equal if,
* and only if, they have the same name type, and the hostnames are
* equal in a case-independent comparison.
*
* @param other
* the other server name object to compare with.
* @return true if, and only if, the {@code other} is considered
* equal to this instance
*/
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other instanceof SNIHostName) {
return hostname.equalsIgnoreCase(((SNIHostName)other).hostname);
}
return false;
}
/**
* Returns a hash code value for this {@code SNIHostName}.
* <P>
* The hash code value is generated using the case-insensitive hostname
* of this {@code SNIHostName}.
*
* @return a hash code value for this {@code SNIHostName}.
*/
@Override
public int hashCode() {
int result = 17; // 17/31: prime number to decrease collisions
result = 31 * result + hostname.toUpperCase(Locale.ENGLISH).hashCode();
return result;
}
/**
* Returns a string representation of the object, including the DNS
* hostname in this {@code SNIHostName} object.
* <P>
* The exact details of the representation are unspecified and subject
* to change, but the following may be regarded as typical:
* <pre>
* "type=host_name (0), value={@literal <hostname>}"
* </pre>
* The "{@literal <hostname>}" is an ASCII representation of the hostname,
* which may contains A-labels. For example, a returned value of an pseudo
* hostname may look like:
* <pre>
* "type=host_name (0), value=www.example.com"
* </pre>
* or
* <pre>
* "type=host_name (0), value=xn--fsqu00a.xn--0zwm56d"
* </pre>
* <P>
* Please NOTE that the exact details of the representation are unspecified
* and subject to change.
*
* @return a string representation of the object.
*/
@Override
public String toString() {
return "type=host_name (0), value=" + hostname;
}
/**
* Creates an {@link SNIMatcher} object for {@code SNIHostName}s.
* <P>
* This method can be used by a server to verify the acceptable
* {@code SNIHostName}s. For example,
* <pre>
* SNIMatcher matcher =
* SNIHostName.createSNIMatcher("www\\.example\\.com");
* </pre>
* will accept the hostname "www.example.com".
* <pre>
* SNIMatcher matcher =
* SNIHostName.createSNIMatcher("www\\.example\\.(com|org)");
* </pre>
* will accept hostnames "www.example.com" and "www.example.org".
*
* @param regex
* the <a href="{@docRoot}/java/util/regex/Pattern.html#sum">
* regular expression pattern</a>
* representing the hostname(s) to match
* @return a {@code SNIMatcher} object for {@code SNIHostName}s
* @throws NullPointerException if {@code regex} is
* {@code null}
* @throws java.util.regex.PatternSyntaxException if the regular expression's
* syntax is invalid
*/
public static SNIMatcher createSNIMatcher(String regex) {
if (regex == null) {
throw new NullPointerException(
"The regular expression cannot be null");
}
return new SNIHostNameMatcher(regex);
}
// check the validity of the string hostname
private void checkHostName() {
if (hostname.isEmpty()) {
throw new IllegalArgumentException(
"Server name value of host_name cannot be empty");
}
if (hostname.endsWith(".")) {
throw new IllegalArgumentException(
"Server name value of host_name cannot have the trailing dot");
}
}
private static final class SNIHostNameMatcher extends SNIMatcher {
// the compiled representation of a regular expression.
private final Pattern pattern;
/**
* Creates an SNIHostNameMatcher object.
*
* @param regex
* the <a href="{@docRoot}/java/util/regex/Pattern.html#sum">
* regular expression pattern</a>
* representing the hostname(s) to match
* @throws NullPointerException if {@code regex} is
* {@code null}
* @throws PatternSyntaxException if the regular expression's syntax
* is invalid
*/
SNIHostNameMatcher(String regex) {
super(StandardConstants.SNI_HOST_NAME);
pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
}
/**
* Attempts to match the given {@link SNIServerName}.
*
* @param serverName
* the {@link SNIServerName} instance on which this matcher
* performs match operations
*
* @return {@code true} if, and only if, the matcher matches the
* given {@code serverName}
*
* @throws NullPointerException if {@code serverName} is {@code null}
* @throws IllegalArgumentException if {@code serverName} is
* not of {@code StandardConstants#SNI_HOST_NAME} type
*
* @see SNIServerName
*/
@Override
public boolean matches(SNIServerName serverName) {
if (serverName == null) {
throw new NullPointerException(
"The SNIServerName argument cannot be null");
}
SNIHostName hostname;
if (!(serverName instanceof SNIHostName)) {
if (serverName.getType() != StandardConstants.SNI_HOST_NAME) {
throw new IllegalArgumentException(
"The server name type is not host_name");
}
try {
hostname = new SNIHostName(serverName.getEncoded());
} catch (NullPointerException | IllegalArgumentException e) {
return false;
}
} else {
hostname = (SNIHostName)serverName;
}
// Let's first try the ascii name matching
String asciiName = hostname.getAsciiName();
if (pattern.matcher(asciiName).matches()) {
return true;
}
// May be an internationalized domain name, check the Unicode
// representations.
return pattern.matcher(IDN.toUnicode(asciiName)).matches();
}
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2012, 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 javax.net.ssl;
/**
* Instances of this class represent a matcher that performs match
* operations on an {@link SNIServerName} instance.
* <P>
* Servers can use Server Name Indication (SNI) information to decide if
* specific {@link SSLSocket} or {@link SSLEngine} instances should accept
* a connection. For example, when multiple "virtual" or "name-based"
* servers are hosted on a single underlying network address, the server
* application can use SNI information to determine whether this server is
* the exact server that the client wants to access. Instances of this
* class can be used by a server to verify the acceptable server names of
* a particular type, such as host names.
* <P>
* {@code SNIMatcher} objects are immutable. Subclasses should not provide
* methods that can change the state of an instance once it has been created.
*
* @see SNIServerName
* @see SNIHostName
* @see SSLParameters#getSNIMatchers()
* @see SSLParameters#setSNIMatchers(Collection)
*
* @since 1.8
*/
public abstract class SNIMatcher {
// the type of the server name that this matcher performs on
private final int type;
/**
* Creates an {@code SNIMatcher} using the specified server name type.
*
* @param type
* the type of the server name that this matcher performs on
*
* @throws IllegalArgumentException if {@code type} is not in the range
* of 0 to 255, inclusive.
*/
protected SNIMatcher(int type) {
if (type < 0) {
throw new IllegalArgumentException(
"Server name type cannot be less than zero");
} else if (type > 255) {
throw new IllegalArgumentException(
"Server name type cannot be greater than 255");
}
this.type = type;
}
/**
* Returns the server name type of this {@code SNIMatcher} object.
*
* @return the server name type of this {@code SNIMatcher} object.
*
* @see SNIServerName
*/
public final int getType() {
return type;
}
/**
* Attempts to match the given {@link SNIServerName}.
*
* @param serverName
* the {@link SNIServerName} instance on which this matcher
* performs match operations
*
* @return {@code true} if, and only if, the matcher matches the
* given {@code serverName}
*
* @throws NullPointerException if {@code serverName} is {@code null}
* @throws IllegalArgumentException if {@code serverName} is
* not of the given server name type of this matcher
*
* @see SNIServerName
*/
public abstract boolean matches(SNIServerName serverName);
}

View file

@ -0,0 +1,213 @@
/*
* Copyright (c) 2012, 2015, 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 javax.net.ssl;
import java.util.Arrays;
/**
* Instances of this class represent a server name in a Server Name
* Indication (SNI) extension.
* <P>
* The SNI extension is a feature that extends the SSL/TLS/DTLS protocols to
* indicate what server name the client is attempting to connect to during
* handshaking. See section 3, "Server Name Indication", of <A
* HREF="http://www.ietf.org/rfc/rfc6066.txt">TLS Extensions (RFC 6066)</A>.
* <P>
* {@code SNIServerName} objects are immutable. Subclasses should not provide
* methods that can change the state of an instance once it has been created.
*
* @see SSLParameters#getServerNames()
* @see SSLParameters#setServerNames(List)
*
* @since 1.8
*/
public abstract class SNIServerName {
// the type of the server name
private final int type;
// the encoded value of the server name
private final byte[] encoded;
// the hex digitals
private static final char[] HEXES = "0123456789ABCDEF".toCharArray();
/**
* Creates an {@code SNIServerName} using the specified name type and
* encoded value.
* <P>
* Note that the {@code encoded} byte array is cloned to protect against
* subsequent modification.
*
* @param type
* the type of the server name
* @param encoded
* the encoded value of the server name
*
* @throws IllegalArgumentException if {@code type} is not in the range
* of 0 to 255, inclusive.
* @throws NullPointerException if {@code encoded} is null
*/
protected SNIServerName(int type, byte[] encoded) {
if (type < 0) {
throw new IllegalArgumentException(
"Server name type cannot be less than zero");
} else if (type > 255) {
throw new IllegalArgumentException(
"Server name type cannot be greater than 255");
}
this.type = type;
if (encoded == null) {
throw new NullPointerException(
"Server name encoded value cannot be null");
}
this.encoded = encoded.clone();
}
/**
* Returns the name type of this server name.
*
* @return the name type of this server name
*/
public final int getType() {
return type;
}
/**
* Returns a copy of the encoded server name value of this server name.
*
* @return a copy of the encoded server name value of this server name
*/
public final byte[] getEncoded() {
return encoded.clone();
}
/**
* Indicates whether some other object is "equal to" this server name.
*
* @return true if, and only if, {@code other} is of the same class
* of this object, and has the same name type and
* encoded value as this server name.
*/
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (this.getClass() != other.getClass()) {
return false;
}
SNIServerName that = (SNIServerName)other;
return (this.type == that.type) &&
Arrays.equals(this.encoded, that.encoded);
}
/**
* Returns a hash code value for this server name.
* <P>
* The hash code value is generated using the name type and encoded
* value of this server name.
*
* @return a hash code value for this server name.
*/
@Override
public int hashCode() {
int result = 17; // 17/31: prime number to decrease collisions
result = 31 * result + type;
result = 31 * result + Arrays.hashCode(encoded);
return result;
}
/**
* Returns a string representation of this server name, including the server
* name type and the encoded server name value in this
* {@code SNIServerName} object.
* <P>
* The exact details of the representation are unspecified and subject
* to change, but the following may be regarded as typical:
* <pre>
* "type={@literal <name type>}, value={@literal <name value>}"
* </pre>
* <P>
* In this class, the format of "{@literal <name type>}" is
* "[LITERAL] (INTEGER)", where the optional "LITERAL" is the literal
* name, and INTEGER is the integer value of the name type. The format
* of "{@literal <name value>}" is "XX:...:XX", where "XX" is the
* hexadecimal digit representation of a byte value. For example, a
* returned value of an pseudo server name may look like:
* <pre>
* "type=(31), value=77:77:77:2E:65:78:61:6D:70:6C:65:2E:63:6E"
* </pre>
* or
* <pre>
* "type=host_name (0), value=77:77:77:2E:65:78:61:6D:70:6C:65:2E:63:6E"
* </pre>
*
* <P>
* Please NOTE that the exact details of the representation are unspecified
* and subject to change, and subclasses may override the method with
* their own formats.
*
* @return a string representation of this server name
*/
@Override
public String toString() {
if (type == StandardConstants.SNI_HOST_NAME) {
return "type=host_name (0), value=" + toHexString(encoded);
} else {
return "type=(" + type + "), value=" + toHexString(encoded);
}
}
// convert byte array to hex string
private static String toHexString(byte[] bytes) {
if (bytes.length == 0) {
return "(empty)";
}
StringBuilder sb = new StringBuilder(bytes.length * 3 - 1);
boolean isInitial = true;
for (byte b : bytes) {
if (isInitial) {
isInitial = false;
} else {
sb.append(':');
}
int k = b & 0xFF;
sb.append(HEXES[k >>> 4]);
sb.append(HEXES[k & 0xF]);
}
return sb.toString();
}
}

View file

@ -0,0 +1,458 @@
/*
* Copyright (c) 1999, 2017, 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 javax.net.ssl;
import java.security.*;
import java.util.Objects;
import sun.security.jca.GetInstance;
/**
* Instances of this class represent a secure socket protocol
* implementation which acts as a factory for secure socket
* factories or {@code SSLEngine}s. This class is initialized
* with an optional set of key and trust managers and source of
* secure random bytes.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code SSLContext} protocols:
* <ul>
* <li>{@code TLSv1}</li>
* <li>{@code TLSv1.1}</li>
* <li>{@code TLSv1.2}</li>
* </ul>
* These protocols are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms">
* SSLContext section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @since 1.4
*/
public class SSLContext {
private final Provider provider;
private final SSLContextSpi contextSpi;
private final String protocol;
/**
* Creates an SSLContext object.
*
* @param contextSpi the delegate
* @param provider the provider
* @param protocol the protocol
*/
protected SSLContext(SSLContextSpi contextSpi, Provider provider,
String protocol) {
this.contextSpi = contextSpi;
this.provider = provider;
this.protocol = protocol;
}
private static SSLContext defaultContext;
/**
* Returns the default SSL context.
*
* <p>If a default context was set using the {@link #setDefault
* SSLContext.setDefault()} method, it is returned. Otherwise, the first
* call of this method triggers the call
* {@code SSLContext.getInstance("Default")}.
* If successful, that object is made the default SSL context and returned.
*
* <p>The default context is immediately
* usable and does not require {@linkplain #init initialization}.
*
* @return the default SSL context
* @throws NoSuchAlgorithmException if the
* {@link SSLContext#getInstance SSLContext.getInstance()} call fails
* @since 1.6
*/
public static synchronized SSLContext getDefault()
throws NoSuchAlgorithmException {
if (defaultContext == null) {
defaultContext = SSLContext.getInstance("Default");
}
return defaultContext;
}
/**
* Sets the default SSL context. It will be returned by subsequent calls
* to {@link #getDefault}. The default context must be immediately usable
* and not require {@linkplain #init initialization}.
*
* @param context the SSLContext
* @throws NullPointerException if context is null
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method does not allow
* {@code SSLPermission("setDefaultSSLContext")}
* @since 1.6
*/
public static synchronized void setDefault(SSLContext context) {
if (context == null) {
throw new NullPointerException();
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SSLPermission("setDefaultSSLContext"));
}
defaultContext = context;
}
/**
* Returns a {@code SSLContext} object that implements the
* specified secure socket protocol.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new SSLContext object encapsulating the
* SSLContextSpi implementation from the first
* Provider that supports the specified protocol is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param protocol the standard name of the requested protocol.
* See the SSLContext section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard protocol names.
*
* @return the new {@code SSLContext} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code SSLContextSpi} implementation for the
* specified protocol
*
* @throws NullPointerException if {@code protocol} is {@code null}
*
* @see java.security.Provider
*/
public static SSLContext getInstance(String protocol)
throws NoSuchAlgorithmException {
Objects.requireNonNull(protocol, "null protocol name");
GetInstance.Instance instance = GetInstance.getInstance
("SSLContext", SSLContextSpi.class, protocol);
return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
protocol);
}
/**
* Returns a {@code SSLContext} object that implements the
* specified secure socket protocol.
*
* <p> A new SSLContext object encapsulating the
* SSLContextSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param protocol the standard name of the requested protocol.
* See the SSLContext section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard protocol names.
*
* @param provider the name of the provider.
*
* @return the new {@code SSLContext} object
*
* @throws IllegalArgumentException if the provider name is
* {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code SSLContextSpi}
* implementation for the specified protocol is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code protocol} is {@code null}
*
* @see java.security.Provider
*/
public static SSLContext getInstance(String protocol, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
Objects.requireNonNull(protocol, "null protocol name");
GetInstance.Instance instance = GetInstance.getInstance
("SSLContext", SSLContextSpi.class, protocol, provider);
return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
protocol);
}
/**
* Returns a {@code SSLContext} object that implements the
* specified secure socket protocol.
*
* <p> A new SSLContext object encapsulating the
* SSLContextSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param protocol the standard name of the requested protocol.
* See the SSLContext section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#sslcontext-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard protocol names.
*
* @param provider an instance of the provider.
*
* @return the new {@code SSLContext} object
*
* @throws IllegalArgumentException if the provider is {@code null}
*
* @throws NoSuchAlgorithmException if a {@code SSLContextSpi}
* implementation for the specified protocol is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code protocol} is {@code null}
*
* @see java.security.Provider
*/
public static SSLContext getInstance(String protocol, Provider provider)
throws NoSuchAlgorithmException {
Objects.requireNonNull(protocol, "null protocol name");
GetInstance.Instance instance = GetInstance.getInstance
("SSLContext", SSLContextSpi.class, protocol, provider);
return new SSLContext((SSLContextSpi)instance.impl, instance.provider,
protocol);
}
/**
* Returns the protocol name of this {@code SSLContext} object.
*
* <p>This is the same name that was specified in one of the
* {@code getInstance} calls that created this
* {@code SSLContext} object.
*
* @return the protocol name of this {@code SSLContext} object.
*/
public final String getProtocol() {
return this.protocol;
}
/**
* Returns the provider of this {@code SSLContext} object.
*
* @return the provider of this {@code SSLContext} object
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Initializes this context. Either of the first two parameters
* may be null in which case the installed security providers will
* be searched for the highest priority implementation of the
* appropriate factory. Likewise, the secure random parameter may
* be null in which case the default implementation will be used.
* <P>
* Only the first instance of a particular key and/or trust manager
* implementation type in the array is used. (For example, only
* the first javax.net.ssl.X509KeyManager in the array will be used.)
*
* @param km the sources of authentication keys or null
* @param tm the sources of peer authentication trust decisions or null
* @param random the source of randomness for this generator or null
* @throws KeyManagementException if this operation fails
*/
public final void init(KeyManager[] km, TrustManager[] tm,
SecureRandom random)
throws KeyManagementException {
contextSpi.engineInit(km, tm, random);
}
/**
* Returns a {@code SocketFactory} object for this
* context.
*
* @return the {@code SocketFactory} object
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code init()} has not been called
*/
public final SSLSocketFactory getSocketFactory() {
return contextSpi.engineGetSocketFactory();
}
/**
* Returns a {@code ServerSocketFactory} object for
* this context.
*
* @return the {@code ServerSocketFactory} object
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code init()} has not been called
*/
public final SSLServerSocketFactory getServerSocketFactory() {
return contextSpi.engineGetServerSocketFactory();
}
/**
* Creates a new {@code SSLEngine} using this context.
* <P>
* Applications using this factory method are providing no hints
* for an internal session reuse strategy. If hints are desired,
* {@link #createSSLEngine(String, int)} should be used
* instead.
* <P>
* Some cipher suites (such as Kerberos) require remote hostname
* information, in which case this factory method should not be used.
*
* @return the {@code SSLEngine} object
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code init()} has not been called
* @since 1.5
*/
public final SSLEngine createSSLEngine() {
try {
return contextSpi.engineCreateSSLEngine();
} catch (AbstractMethodError e) {
UnsupportedOperationException unsup =
new UnsupportedOperationException(
"Provider: " + getProvider() +
" doesn't support this operation");
unsup.initCause(e);
throw unsup;
}
}
/**
* Creates a new {@code SSLEngine} using this context using
* advisory peer information.
* <P>
* Applications using this factory method are providing hints
* for an internal session reuse strategy.
* <P>
* Some cipher suites (such as Kerberos) require remote hostname
* information, in which case peerHost needs to be specified.
*
* @param peerHost the non-authoritative name of the host
* @param peerPort the non-authoritative port
* @return the new {@code SSLEngine} object
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code init()} has not been called
* @since 1.5
*/
public final SSLEngine createSSLEngine(String peerHost, int peerPort) {
try {
return contextSpi.engineCreateSSLEngine(peerHost, peerPort);
} catch (AbstractMethodError e) {
UnsupportedOperationException unsup =
new UnsupportedOperationException(
"Provider: " + getProvider() +
" does not support this operation");
unsup.initCause(e);
throw unsup;
}
}
/**
* Returns the server session context, which represents the set of
* SSL sessions available for use during the handshake phase of
* server-side SSL sockets.
* <P>
* This context may be unavailable in some environments, in which
* case this method returns null. For example, when the underlying
* SSL provider does not provide an implementation of SSLSessionContext
* interface, this method returns null. A non-null session context
* is returned otherwise.
*
* @return server session context bound to this SSL context
*/
public final SSLSessionContext getServerSessionContext() {
return contextSpi.engineGetServerSessionContext();
}
/**
* Returns the client session context, which represents the set of
* SSL sessions available for use during the handshake phase of
* client-side SSL sockets.
* <P>
* This context may be unavailable in some environments, in which
* case this method returns null. For example, when the underlying
* SSL provider does not provide an implementation of SSLSessionContext
* interface, this method returns null. A non-null session context
* is returned otherwise.
*
* @return client session context bound to this SSL context
*/
public final SSLSessionContext getClientSessionContext() {
return contextSpi.engineGetClientSessionContext();
}
/**
* Returns a copy of the SSLParameters indicating the default
* settings for this SSL context.
*
* <p>The parameters will always have the ciphersuites and protocols
* arrays set to non-null values.
*
* @return a copy of the SSLParameters object with the default settings
* @throws UnsupportedOperationException if the default SSL parameters
* could not be obtained.
* @since 1.6
*/
public final SSLParameters getDefaultSSLParameters() {
return contextSpi.engineGetDefaultSSLParameters();
}
/**
* Returns a copy of the SSLParameters indicating the supported
* settings for this SSL context.
*
* <p>The parameters will always have the ciphersuites and protocols
* arrays set to non-null values.
*
* @return a copy of the SSLParameters object with the supported
* settings
* @throws UnsupportedOperationException if the supported SSL parameters
* could not be obtained.
* @since 1.6
*/
public final SSLParameters getSupportedSSLParameters() {
return contextSpi.engineGetSupportedSSLParameters();
}
}

View file

@ -0,0 +1,203 @@
/*
* Copyright (c) 1999, 2015, 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 javax.net.ssl;
import java.security.*;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code SSLContext} class.
*
* <p> All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a particular SSL context.
*
* @since 1.4
* @see SSLContext
*/
public abstract class SSLContextSpi {
/**
* Initializes this context.
*
* @param km the sources of authentication keys
* @param tm the sources of peer authentication trust decisions
* @param sr the source of randomness
* @throws KeyManagementException if this operation fails
* @see SSLContext#init(KeyManager [], TrustManager [], SecureRandom)
*/
protected abstract void engineInit(KeyManager[] km, TrustManager[] tm,
SecureRandom sr) throws KeyManagementException;
/**
* Returns a {@code SocketFactory} object for this
* context.
*
* @return the {@code SocketFactory} object
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code engineInit()}
* has not been called
* @see javax.net.ssl.SSLContext#getSocketFactory()
*/
protected abstract SSLSocketFactory engineGetSocketFactory();
/**
* Returns a {@code ServerSocketFactory} object for
* this context.
*
* @return the {@code ServerSocketFactory} object
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code engineInit()}
* has not been called
* @see javax.net.ssl.SSLContext#getServerSocketFactory()
*/
protected abstract SSLServerSocketFactory engineGetServerSocketFactory();
/**
* Creates a new {@code SSLEngine} using this context.
* <P>
* Applications using this factory method are providing no hints
* for an internal session reuse strategy. If hints are desired,
* {@link #engineCreateSSLEngine(String, int)} should be used
* instead.
* <P>
* Some cipher suites (such as Kerberos) require remote hostname
* information, in which case this factory method should not be used.
*
* @return the {@code SSLEngine} Object
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code engineInit()}
* has not been called
*
* @see SSLContext#createSSLEngine()
*
* @since 1.5
*/
protected abstract SSLEngine engineCreateSSLEngine();
/**
* Creates a {@code SSLEngine} using this context.
* <P>
* Applications using this factory method are providing hints
* for an internal session reuse strategy.
* <P>
* Some cipher suites (such as Kerberos) require remote hostname
* information, in which case peerHost needs to be specified.
*
* @param host the non-authoritative name of the host
* @param port the non-authoritative port
* @return the {@code SSLEngine} Object
* @throws IllegalStateException if the SSLContextImpl requires
* initialization and the {@code engineInit()}
* has not been called
*
* @see SSLContext#createSSLEngine(String, int)
*
* @since 1.5
*/
protected abstract SSLEngine engineCreateSSLEngine(String host, int port);
/**
* Returns a server {@code SSLSessionContext} object for
* this context.
*
* @return the {@code SSLSessionContext} object
* @see javax.net.ssl.SSLContext#getServerSessionContext()
*/
protected abstract SSLSessionContext engineGetServerSessionContext();
/**
* Returns a client {@code SSLSessionContext} object for
* this context.
*
* @return the {@code SSLSessionContext} object
* @see javax.net.ssl.SSLContext#getClientSessionContext()
*/
protected abstract SSLSessionContext engineGetClientSessionContext();
private SSLSocket getDefaultSocket() {
try {
SSLSocketFactory factory = engineGetSocketFactory();
return (SSLSocket)factory.createSocket();
} catch (java.io.IOException e) {
throw new UnsupportedOperationException("Could not obtain parameters", e);
}
}
/**
* Returns a copy of the SSLParameters indicating the default
* settings for this SSL context.
*
* <p>The parameters will always have the ciphersuite and protocols
* arrays set to non-null values.
*
* <p>The default implementation obtains the parameters from an
* SSLSocket created by calling the
* {@linkplain javax.net.SocketFactory#createSocket
* SocketFactory.createSocket()} method of this context's SocketFactory.
*
* @return a copy of the SSLParameters object with the default settings
* @throws UnsupportedOperationException if the default SSL parameters
* could not be obtained.
*
* @since 1.6
*/
protected SSLParameters engineGetDefaultSSLParameters() {
SSLSocket socket = getDefaultSocket();
return socket.getSSLParameters();
}
/**
* Returns a copy of the SSLParameters indicating the maximum supported
* settings for this SSL context.
*
* <p>The parameters will always have the ciphersuite and protocols
* arrays set to non-null values.
*
* <p>The default implementation obtains the parameters from an
* SSLSocket created by calling the
* {@linkplain javax.net.SocketFactory#createSocket
* SocketFactory.createSocket()} method of this context's SocketFactory.
*
* @return a copy of the SSLParameters object with the maximum supported
* settings
* @throws UnsupportedOperationException if the supported SSL parameters
* could not be obtained.
*
* @since 1.6
*/
protected SSLParameters engineGetSupportedSSLParameters() {
SSLSocket socket = getDefaultSocket();
SSLParameters params = new SSLParameters();
params.setCipherSuites(socket.getSupportedCipherSuites());
params.setProtocols(socket.getSupportedProtocols());
return params;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,325 @@
/*
* Copyright (c) 2003, 2017, 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 javax.net.ssl;
/**
* An encapsulation of the result state produced by
* {@code SSLEngine} I/O calls.
*
* <p> A {@code SSLEngine} provides a means for establishing
* secure communication sessions between two peers. {@code SSLEngine}
* operations typically consume bytes from an input buffer and produce
* bytes in an output buffer. This class provides operational result
* values describing the state of the {@code SSLEngine}, including
* indications of what operations are needed to finish an
* ongoing handshake. Lastly, it reports the number of bytes consumed
* and produced as a result of this operation.
*
* @see SSLEngine
* @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
* @see SSLEngine#unwrap(ByteBuffer, ByteBuffer)
*
* @author Brad R. Wetmore
* @since 1.5
*/
public class SSLEngineResult {
/**
* An {@code SSLEngineResult} enum describing the overall result
* of the {@code SSLEngine} operation.
*
* The {@code Status} value does not reflect the
* state of a {@code SSLEngine} handshake currently
* in progress. The {@code SSLEngineResult's HandshakeStatus}
* should be consulted for that information.
*
* @author Brad R. Wetmore
* @since 1.5
*/
public static enum Status {
/**
* The {@code SSLEngine} was not able to unwrap the
* incoming data because there were not enough source bytes
* available to make a complete packet.
*
* <P>
* Repeat the call once more bytes are available.
*/
BUFFER_UNDERFLOW,
/**
* The {@code SSLEngine} was not able to process the
* operation because there are not enough bytes available in the
* destination buffer to hold the result.
* <P>
* Repeat the call once more bytes are available.
*
* @see SSLSession#getPacketBufferSize()
* @see SSLSession#getApplicationBufferSize()
*/
BUFFER_OVERFLOW,
/**
* The {@code SSLEngine} completed the operation, and
* is available to process similar calls.
*/
OK,
/**
* The operation just closed this side of the
* {@code SSLEngine}, or the operation
* could not be completed because it was already closed.
*/
CLOSED;
}
/**
* An {@code SSLEngineResult} enum describing the current
* handshaking state of this {@code SSLEngine}.
*
* @author Brad R. Wetmore
* @since 1.5
*/
public static enum HandshakeStatus {
/**
* The {@code SSLEngine} is not currently handshaking.
*/
NOT_HANDSHAKING,
/**
* The {@code SSLEngine} has just finished handshaking.
* <P>
* This value is only generated by a call to
* {@code SSLEngine.wrap()/unwrap()} when that call
* finishes a handshake. It is never generated by
* {@code SSLEngine.getHandshakeStatus()}.
*
* @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
* @see SSLEngine#unwrap(ByteBuffer, ByteBuffer)
* @see SSLEngine#getHandshakeStatus()
*/
FINISHED,
/**
* The {@code SSLEngine} needs the results of one (or more)
* delegated tasks before handshaking can continue.
*
* @see SSLEngine#getDelegatedTask()
*/
NEED_TASK,
/**
* The {@code SSLEngine} must send data to the remote side
* before handshaking can continue, so {@code SSLEngine.wrap()}
* should be called.
*
* @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
*/
NEED_WRAP,
/**
* The {@code SSLEngine} needs to receive data from the
* remote side before handshaking can continue.
*/
NEED_UNWRAP,
/**
* The {@code SSLEngine} needs to unwrap before handshaking can
* continue.
* <P>
* This value is used to indicate that not-yet-interpreted data
* has been previously received from the remote side, and does
* not need to be received again.
* <P>
* This handshake status only applies to DTLS.
*
* @since 9
*/
NEED_UNWRAP_AGAIN;
}
private final Status status;
private final HandshakeStatus handshakeStatus;
private final int bytesConsumed;
private final int bytesProduced;
private final long sequenceNumber;
/**
* Initializes a new instance of this class.
*
* @param status
* the return value of the operation.
*
* @param handshakeStatus
* the current handshaking status.
*
* @param bytesConsumed
* the number of bytes consumed from the source ByteBuffer
*
* @param bytesProduced
* the number of bytes placed into the destination ByteBuffer
*
* @throws IllegalArgumentException
* if the {@code status} or {@code handshakeStatus}
* arguments are null, or if {@code bytesConsumed} or
* {@code bytesProduced} is negative.
*/
public SSLEngineResult(Status status, HandshakeStatus handshakeStatus,
int bytesConsumed, int bytesProduced) {
this(status, handshakeStatus, bytesConsumed, bytesProduced, -1);
}
/**
* Initializes a new instance of this class.
*
* @param status
* the return value of the operation.
*
* @param handshakeStatus
* the current handshaking status.
*
* @param bytesConsumed
* the number of bytes consumed from the source ByteBuffer
*
* @param bytesProduced
* the number of bytes placed into the destination ByteBuffer
*
* @param sequenceNumber
* the sequence number (unsigned long) of the produced or
* consumed SSL/TLS/DTLS record, or {@code -1L} if no record
* produced or consumed
*
* @throws IllegalArgumentException
* if the {@code status} or {@code handshakeStatus}
* arguments are null, or if {@code bytesConsumed} or
* {@code bytesProduced} is negative
*
* @since 9
*/
public SSLEngineResult(Status status, HandshakeStatus handshakeStatus,
int bytesConsumed, int bytesProduced, long sequenceNumber) {
if ((status == null) || (handshakeStatus == null) ||
(bytesConsumed < 0) || (bytesProduced < 0)) {
throw new IllegalArgumentException("Invalid Parameter(s)");
}
this.status = status;
this.handshakeStatus = handshakeStatus;
this.bytesConsumed = bytesConsumed;
this.bytesProduced = bytesProduced;
this.sequenceNumber = sequenceNumber;
}
/**
* Gets the return value of this {@code SSLEngine} operation.
*
* @return the return value
*/
public final Status getStatus() {
return status;
}
/**
* Gets the handshake status of this {@code SSLEngine}
* operation.
*
* @return the handshake status
*/
public final HandshakeStatus getHandshakeStatus() {
return handshakeStatus;
}
/**
* Returns the number of bytes consumed from the input buffer.
*
* @return the number of bytes consumed.
*/
public final int bytesConsumed() {
return bytesConsumed;
}
/**
* Returns the number of bytes written to the output buffer.
*
* @return the number of bytes produced
*/
public final int bytesProduced() {
return bytesProduced;
}
/**
* Returns the sequence number of the produced or consumed SSL/TLS/DTLS
* record (optional operation).
*
* @apiNote Note that sequence number is an unsigned long and cannot
* exceed {@code -1L}. It is desired to use the unsigned
* long comparing mode for comparison of unsigned long values
* (see also {@link java.lang.Long#compareUnsigned(long, long)
* Long.compareUnsigned()}).
* <P>
* For DTLS protocols, the first 16 bits of the sequence
* number is a counter value (epoch) that is incremented on
* every cipher state change. The remaining 48 bits on the
* right side of the sequence number represents the sequence
* of the record, which is maintained separately for each epoch.
*
* @implNote It is recommended that providers should never allow the
* sequence number incremented to {@code -1L}. If the sequence
* number is close to wrapping, renegotiate should be requested,
* otherwise the connection should be closed immediately.
* This should be carried on automatically by the underlying
* implementation.
*
* @return the sequence number of the produced or consumed SSL/TLS/DTLS
* record; or {@code -1L} if no record is produced or consumed,
* or this operation is not supported by the underlying provider
*
* @see java.lang.Long#compareUnsigned(long, long)
*
* @since 9
*/
public final long sequenceNumber() {
return sequenceNumber;
}
/**
* Returns a String representation of this object.
*/
@Override
public String toString() {
return ("Status = " + status +
" HandshakeStatus = " + handshakeStatus +
"\nbytesConsumed = " + bytesConsumed +
" bytesProduced = " + bytesProduced +
(sequenceNumber == -1 ? "" :
" sequenceNumber = " + Long.toUnsignedString(sequenceNumber)));
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 1996, 2004, 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 javax.net.ssl;
import java.io.IOException;
/**
* Indicates some kind of error detected by an SSL subsystem.
* This class is the general class of exceptions produced
* by failed SSL-related operations.
*
* @since 1.4
* @author David Brownell
*/
public
class SSLException extends IOException
{
private static final long serialVersionUID = 4511006460650708967L;
/**
* Constructs an exception reporting an error found by
* an SSL subsystem.
*
* @param reason describes the problem.
*/
public SSLException(String reason)
{
super(reason);
}
/**
* Creates a {@code SSLException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.5
*/
public SSLException(String message, Throwable cause) {
super(message);
initCause(cause);
}
/**
* Creates a {@code SSLException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
* @since 1.5
*/
public SSLException(Throwable cause) {
super(cause == null ? null : cause.toString());
initCause(cause);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 1996, 2003, 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 javax.net.ssl;
/**
* Indicates that the client and server could not negotiate the
* desired level of security. The connection is no longer usable.
*
* @since 1.4
* @author David Brownell
*/
public
class SSLHandshakeException extends SSLException
{
private static final long serialVersionUID = -5045881315018326890L;
/**
* Constructs an exception reporting an error found by
* an SSL subsystem during handshaking.
*
* @param reason describes the problem.
*/
public SSLHandshakeException(String reason)
{
super(reason);
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 1996, 2003, 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 javax.net.ssl;
/**
* Reports a bad SSL key. Normally, this indicates misconfiguration
* of the server or client SSL certificate and private key.
*
* @since 1.4
* @author David Brownell
*/
public
class SSLKeyException extends SSLException
{
private static final long serialVersionUID = -8071664081941937874L;
/**
* Constructs an exception reporting a key management error
* found by an SSL subsystem.
*
* @param reason describes the problem.
*/
public SSLKeyException(String reason)
{
super(reason);
}
}

View file

@ -0,0 +1,678 @@
/*
* Copyright (c) 2005, 2017, 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 javax.net.ssl;
import java.security.AlgorithmConstraints;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
/**
* Encapsulates parameters for an SSL/TLS/DTLS connection. The parameters
* are the list of ciphersuites to be accepted in an SSL/TLS/DTLS handshake,
* the list of protocols to be allowed, the endpoint identification
* algorithm during SSL/TLS/DTLS handshaking, the Server Name Indication (SNI),
* the maximum network packet size, the algorithm constraints and whether
* SSL/TLS/DTLS servers should request or require client authentication, etc.
* <p>
* SSLParameters can be created via the constructors in this class.
* Objects can also be obtained using the {@code getSSLParameters()}
* methods in
* {@link SSLSocket#getSSLParameters SSLSocket} and
* {@link SSLServerSocket#getSSLParameters SSLServerSocket} and
* {@link SSLEngine#getSSLParameters SSLEngine} or the
* {@link SSLContext#getDefaultSSLParameters getDefaultSSLParameters()} and
* {@link SSLContext#getSupportedSSLParameters getSupportedSSLParameters()}
* methods in {@code SSLContext}.
* <p>
* SSLParameters can be applied to a connection via the methods
* {@link SSLSocket#setSSLParameters SSLSocket.setSSLParameters()} and
* {@link SSLServerSocket#setSSLParameters SSLServerSocket.setSSLParameters()}
* and {@link SSLEngine#setSSLParameters SSLEngine.setSSLParameters()}.
* <p>
* For example:
*
* <blockquote><pre>
* SSLParameters p = sslSocket.getSSLParameters();
* p.setProtocols(new String[] { "TLSv1.2" });
* p.setCipherSuites(
* new String[] { "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", ... });
* p.setApplicationProtocols(new String[] {"h2", "http/1.1"});
* sslSocket.setSSLParameters(p);
* </pre></blockquote>
*
* @see SSLSocket
* @see SSLEngine
* @see SSLContext
*
* @since 1.6
*/
public class SSLParameters {
private String[] cipherSuites;
private String[] protocols;
private boolean wantClientAuth;
private boolean needClientAuth;
private String identificationAlgorithm;
private AlgorithmConstraints algorithmConstraints;
private Map<Integer, SNIServerName> sniNames = null;
private Map<Integer, SNIMatcher> sniMatchers = null;
private boolean preferLocalCipherSuites;
private boolean enableRetransmissions = true;
private int maximumPacketSize = 0;
private String[] applicationProtocols = new String[0];
/**
* Constructs SSLParameters.
* <p>
* The values of cipherSuites, protocols, cryptographic algorithm
* constraints, endpoint identification algorithm, server names and
* server name matchers are set to {@code null}; useCipherSuitesOrder,
* wantClientAuth and needClientAuth are set to {@code false};
* enableRetransmissions is set to {@code true}; maximum network packet
* size is set to {@code 0}.
*/
public SSLParameters() {
// empty
}
/**
* Constructs SSLParameters from the specified array of ciphersuites.
* <p>
* Calling this constructor is equivalent to calling the no-args
* constructor followed by
* {@code setCipherSuites(cipherSuites);}. Note that the
* standard list of cipher suite names may be found in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list.
*
* @param cipherSuites the array of ciphersuites (or null)
*/
public SSLParameters(String[] cipherSuites) {
setCipherSuites(cipherSuites);
}
/**
* Constructs SSLParameters from the specified array of ciphersuites
* and protocols.
* <p>
* Calling this constructor is equivalent to calling the no-args
* constructor followed by
* {@code setCipherSuites(cipherSuites); setProtocols(protocols);}.
* Note that the standard list of cipher suite names may be found in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list.
*
* @param cipherSuites the array of ciphersuites (or null)
* @param protocols the array of protocols (or null)
*/
public SSLParameters(String[] cipherSuites, String[] protocols) {
setCipherSuites(cipherSuites);
setProtocols(protocols);
}
private static String[] clone(String[] s) {
return (s == null) ? null : s.clone();
}
/**
* Returns a copy of the array of ciphersuites or null if none
* have been set.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return a copy of the array of ciphersuites or null if none
* have been set.
*/
public String[] getCipherSuites() {
return clone(cipherSuites);
}
/**
* Sets the array of ciphersuites.
*
* @param cipherSuites the array of ciphersuites (or null). Note that the
* standard list of cipher suite names may be found in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list or might not
* use the recommended name for a certain cipher suite.
*/
public void setCipherSuites(String[] cipherSuites) {
this.cipherSuites = clone(cipherSuites);
}
/**
* Returns a copy of the array of protocols or null if none
* have been set.
*
* @return a copy of the array of protocols or null if none
* have been set.
*/
public String[] getProtocols() {
return clone(protocols);
}
/**
* Sets the array of protocols.
*
* @param protocols the array of protocols (or null)
*/
public void setProtocols(String[] protocols) {
this.protocols = clone(protocols);
}
/**
* Returns whether client authentication should be requested.
*
* @return whether client authentication should be requested.
*/
public boolean getWantClientAuth() {
return wantClientAuth;
}
/**
* Sets whether client authentication should be requested. Calling
* this method clears the {@code needClientAuth} flag.
*
* @param wantClientAuth whether client authentication should be requested
*/
public void setWantClientAuth(boolean wantClientAuth) {
this.wantClientAuth = wantClientAuth;
this.needClientAuth = false;
}
/**
* Returns whether client authentication should be required.
*
* @return whether client authentication should be required.
*/
public boolean getNeedClientAuth() {
return needClientAuth;
}
/**
* Sets whether client authentication should be required. Calling
* this method clears the {@code wantClientAuth} flag.
*
* @param needClientAuth whether client authentication should be required
*/
public void setNeedClientAuth(boolean needClientAuth) {
this.wantClientAuth = false;
this.needClientAuth = needClientAuth;
}
/**
* Returns the cryptographic algorithm constraints.
*
* @return the cryptographic algorithm constraints, or null if the
* constraints have not been set
*
* @see #setAlgorithmConstraints(AlgorithmConstraints)
*
* @since 1.7
*/
public AlgorithmConstraints getAlgorithmConstraints() {
return algorithmConstraints;
}
/**
* Sets the cryptographic algorithm constraints, which will be used
* in addition to any configured by the runtime environment.
* <p>
* If the {@code constraints} parameter is non-null, every
* cryptographic algorithm, key and algorithm parameters used in the
* SSL/TLS/DTLS handshake must be permitted by the constraints.
*
* @param constraints the algorithm constraints (or null)
*
* @since 1.7
*/
public void setAlgorithmConstraints(AlgorithmConstraints constraints) {
// the constraints object is immutable
this.algorithmConstraints = constraints;
}
/**
* Gets the endpoint identification algorithm.
*
* @return the endpoint identification algorithm, or null if none
* has been set.
*
* @see X509ExtendedTrustManager
* @see #setEndpointIdentificationAlgorithm(String)
*
* @since 1.7
*/
public String getEndpointIdentificationAlgorithm() {
return identificationAlgorithm;
}
/**
* Sets the endpoint identification algorithm.
* <p>
* If the {@code algorithm} parameter is non-null or non-empty, the
* endpoint identification/verification procedures must be handled during
* SSL/TLS/DTLS handshaking. This is to prevent man-in-the-middle attacks.
*
* @param algorithm The standard string name of the endpoint
* identification algorithm (or null).
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @see X509ExtendedTrustManager
*
* @since 1.7
*/
public void setEndpointIdentificationAlgorithm(String algorithm) {
this.identificationAlgorithm = algorithm;
}
/**
* Sets the desired {@link SNIServerName}s of the Server Name
* Indication (SNI) parameter.
* <P>
* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s
* operating in client mode.
* <P>
* Note that the {@code serverNames} list is cloned
* to protect against subsequent modification.
*
* @param serverNames
* the list of desired {@link SNIServerName}s (or null)
*
* @throws NullPointerException if the {@code serverNames}
* contains {@code null} element
* @throws IllegalArgumentException if the {@code serverNames}
* contains more than one name of the same name type
*
* @see SNIServerName
* @see #getServerNames()
*
* @since 1.8
*/
public final void setServerNames(List<SNIServerName> serverNames) {
if (serverNames != null) {
if (!serverNames.isEmpty()) {
sniNames = new LinkedHashMap<>(serverNames.size());
for (SNIServerName serverName : serverNames) {
if (sniNames.put(serverName.getType(),
serverName) != null) {
throw new IllegalArgumentException(
"Duplicated server name of type " +
serverName.getType());
}
}
} else {
sniNames = Collections.<Integer, SNIServerName>emptyMap();
}
} else {
sniNames = null;
}
}
/**
* Returns a {@link List} containing all {@link SNIServerName}s of the
* Server Name Indication (SNI) parameter, or null if none has been set.
* <P>
* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s
* operating in client mode.
* <P>
* For SSL/TLS/DTLS connections, the underlying SSL/TLS/DTLS provider
* may specify a default value for a certain server name type. In
* client mode, it is recommended that, by default, providers should
* include the server name indication whenever the server can be located
* by a supported server name type.
* <P>
* It is recommended that providers initialize default Server Name
* Indications when creating {@code SSLSocket}/{@code SSLEngine}s.
* In the following examples, the server name could be represented by an
* instance of {@link SNIHostName} which has been initialized with the
* hostname "www.example.com" and type
* {@link StandardConstants#SNI_HOST_NAME}.
*
* <pre>
* Socket socket =
* sslSocketFactory.createSocket("www.example.com", 443);
* </pre>
* or
* <pre>
* SSLEngine engine =
* sslContext.createSSLEngine("www.example.com", 443);
* </pre>
*
* @return null or an immutable list of non-null {@link SNIServerName}s
*
* @see List
* @see #setServerNames(List)
*
* @since 1.8
*/
public final List<SNIServerName> getServerNames() {
if (sniNames != null) {
if (!sniNames.isEmpty()) {
return Collections.<SNIServerName>unmodifiableList(
new ArrayList<>(sniNames.values()));
} else {
return Collections.<SNIServerName>emptyList();
}
}
return null;
}
/**
* Sets the {@link SNIMatcher}s of the Server Name Indication (SNI)
* parameter.
* <P>
* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s
* operating in server mode.
* <P>
* Note that the {@code matchers} collection is cloned to protect
* against subsequent modification.
*
* @param matchers
* the collection of {@link SNIMatcher}s (or null)
*
* @throws NullPointerException if the {@code matchers}
* contains {@code null} element
* @throws IllegalArgumentException if the {@code matchers}
* contains more than one name of the same name type
*
* @see Collection
* @see SNIMatcher
* @see #getSNIMatchers()
*
* @since 1.8
*/
public final void setSNIMatchers(Collection<SNIMatcher> matchers) {
if (matchers != null) {
if (!matchers.isEmpty()) {
sniMatchers = new HashMap<>(matchers.size());
for (SNIMatcher matcher : matchers) {
if (sniMatchers.put(matcher.getType(),
matcher) != null) {
throw new IllegalArgumentException(
"Duplicated server name of type " +
matcher.getType());
}
}
} else {
sniMatchers = Collections.<Integer, SNIMatcher>emptyMap();
}
} else {
sniMatchers = null;
}
}
/**
* Returns a {@link Collection} containing all {@link SNIMatcher}s of the
* Server Name Indication (SNI) parameter, or null if none has been set.
* <P>
* This method is only useful to {@link SSLSocket}s or {@link SSLEngine}s
* operating in server mode.
* <P>
* For better interoperability, providers generally will not define
* default matchers so that by default servers will ignore the SNI
* extension and continue the handshake.
*
* @return null or an immutable collection of non-null {@link SNIMatcher}s
*
* @see SNIMatcher
* @see #setSNIMatchers(Collection)
*
* @since 1.8
*/
public final Collection<SNIMatcher> getSNIMatchers() {
if (sniMatchers != null) {
if (!sniMatchers.isEmpty()) {
return Collections.<SNIMatcher>unmodifiableList(
new ArrayList<>(sniMatchers.values()));
} else {
return Collections.<SNIMatcher>emptyList();
}
}
return null;
}
/**
* Sets whether the local cipher suites preference should be honored.
*
* @param honorOrder whether local cipher suites order in
* {@code #getCipherSuites} should be honored during
* SSL/TLS/DTLS handshaking.
*
* @see #getUseCipherSuitesOrder()
*
* @since 1.8
*/
public final void setUseCipherSuitesOrder(boolean honorOrder) {
this.preferLocalCipherSuites = honorOrder;
}
/**
* Returns whether the local cipher suites preference should be honored.
*
* @return whether local cipher suites order in {@code #getCipherSuites}
* should be honored during SSL/TLS/DTLS handshaking.
*
* @see #setUseCipherSuitesOrder(boolean)
*
* @since 1.8
*/
public final boolean getUseCipherSuitesOrder() {
return preferLocalCipherSuites;
}
/**
* Sets whether DTLS handshake retransmissions should be enabled.
*
* This method only applies to DTLS.
*
* @param enableRetransmissions
* {@code true} indicates that DTLS handshake retransmissions
* should be enabled; {@code false} indicates that DTLS handshake
* retransmissions should be disabled
*
* @see #getEnableRetransmissions()
*
* @since 9
*/
public void setEnableRetransmissions(boolean enableRetransmissions) {
this.enableRetransmissions = enableRetransmissions;
}
/**
* Returns whether DTLS handshake retransmissions should be enabled.
*
* This method only applies to DTLS.
*
* @return true, if DTLS handshake retransmissions should be enabled
*
* @see #setEnableRetransmissions(boolean)
*
* @since 9
*/
public boolean getEnableRetransmissions() {
return enableRetransmissions;
}
/**
* Sets the maximum expected network packet size in bytes for
* SSL/TLS/DTLS records.
*
* @apiNote It is recommended that if possible, the maximum packet size
* should not be less than 256 bytes so that small handshake
* messages, such as HelloVerifyRequests, are not fragmented.
*
* @implNote If the maximum packet size is too small to hold a minimal
* record, an implementation may attempt to generate as minimal
* records as possible. However, this may cause a generated
* packet to be larger than the maximum packet size.
*
* @param maximumPacketSize
* the maximum expected network packet size in bytes, or
* {@code 0} to use the implicit size that is automatically
* specified by the underlying implementation.
* @throws IllegalArgumentException
* if {@code maximumPacketSize} is negative.
*
* @see #getMaximumPacketSize()
*
* @since 9
*/
public void setMaximumPacketSize(int maximumPacketSize) {
if (maximumPacketSize < 0) {
throw new IllegalArgumentException(
"The maximum packet size cannot be negative");
}
this.maximumPacketSize = maximumPacketSize;
}
/**
* Returns the maximum expected network packet size in bytes for
* SSL/TLS/DTLS records.
*
* @apiNote The implicit size may not be a fixed value, especially
* for a DTLS protocols implementation.
*
* @implNote For SSL/TLS/DTLS connections, the underlying provider
* should calculate and specify the implicit value of the
* maximum expected network packet size if it is not
* configured explicitly. For any connection populated
* object, this method should never return {@code 0} so
* that applications can retrieve the actual implicit size
* of the underlying implementation.
* <P>
* An implementation should attempt to comply with the maximum
* packet size configuration. However, if the maximum packet
* size is too small to hold a minimal record, an implementation
* may try to generate as minimal records as possible. This
* may cause a generated packet to be larger than the maximum
* packet size.
*
* @return the maximum expected network packet size, or {@code 0} if
* use the implicit size that is automatically specified by
* the underlying implementation and this object has not been
* populated by any connection.
*
* @see #setMaximumPacketSize(int)
*
* @since 9
*/
public int getMaximumPacketSize() {
return maximumPacketSize;
}
/**
* Returns a prioritized array of application-layer protocol names that
* can be negotiated over the SSL/TLS/DTLS protocols.
* <p>
* The array could be empty (zero-length), in which case protocol
* indications will not be used.
* <p>
* This method will return a new array each time it is invoked.
*
* @return a non-null, possibly zero-length array of application protocol
* {@code String}s. The array is ordered based on protocol
* preference, with {@code protocols[0]} being the most preferred.
* @see #setApplicationProtocols
* @since 9
*/
public String[] getApplicationProtocols() {
return applicationProtocols.clone();
}
/**
* Sets the prioritized array of application-layer protocol names that
* can be negotiated over the SSL/TLS/DTLS protocols.
* <p>
* If application-layer protocols are supported by the underlying
* SSL/TLS implementation, this method configures which values can
* be negotiated by protocols such as <a
* href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
* Application Layer Protocol Negotiation (ALPN).
* <p>
* If this end of the connection is expected to offer application protocol
* values, all protocols configured by this method will be sent to the
* peer.
* <p>
* If this end of the connection is expected to select the application
* protocol value, the {@code protocols} configured by this method are
* compared with those sent by the peer. The first matched value becomes
* the negotiated value. If none of the {@code protocols} were actually
* requested by the peer, the underlying protocol will determine what
* action to take. (For example, ALPN will send a
* {@code "no_application_protocol"} alert and terminate the connection.)
*
* @implSpec
* This method will make a copy of the {@code protocols} array.
*
* @param protocols an ordered array of application protocols,
* with {@code protocols[0]} being the most preferred.
* If the array is empty (zero-length), protocol
* indications will not be used.
* @throws IllegalArgumentException if protocols is null, or if
* any element in a non-empty array is null or an
* empty (zero-length) string
* @see #getApplicationProtocols
* @since 9
*/
public void setApplicationProtocols(String[] protocols) {
if (protocols == null) {
throw new IllegalArgumentException("protocols was null");
}
String[] tempProtocols = protocols.clone();
for (String p : tempProtocols) {
if (p == null || p.equals("")) {
throw new IllegalArgumentException(
"An element of protocols was null/empty");
}
}
applicationProtocols = tempProtocols;
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 1996, 2013, 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 javax.net.ssl;
/**
* Indicates that the peer's identity has not been verified.
* <P>
* When the peer was not able to
* identify itself (for example; no certificate, the particular
* cipher suite being used does not support authentication, or no
* peer authentication was established during SSL handshaking) this
* exception is thrown.
*
* @since 1.4
* @author David Brownell
*/
public
class SSLPeerUnverifiedException extends SSLException
{
private static final long serialVersionUID = -8919512675000600547L;
/**
* Constructs an exception reporting that the SSL peer's
* identity has not been verified.
*
* @param reason describes the problem.
*/
public SSLPeerUnverifiedException(String reason)
{
super(reason);
}
}

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2000, 2017, 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 javax.net.ssl;
import java.security.*;
/**
* This class is for various network permissions.
* An SSLPermission contains a name (also referred to as a "target name") but
* no actions list; you either have the named permission
* or you don't.
* <P>
* The target name is the name of the network permission (see below). The naming
* convention follows the hierarchical property naming convention.
* Also, an asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match. For example: "foo.*" and "*" signify a wildcard
* match, while "*foo" and "a*b" do not.
* <P>
* The following table lists all the possible SSLPermission target names,
* and for each provides a description of what the permission allows
* and a discussion of the risks of granting code the permission.
*
* <table class="striped">
* <caption style="display:none">permission name, what it allows, and associated risks</caption>
* <thead>
* <tr>
* <th scope="col">Permission Target Name</th>
* <th scope="col">What the Permission Allows</th>
* <th scope="col">Risks of Allowing this Permission</th>
* </tr>
* </thead>
*
* <tbody>
* <tr>
* <th scope="row">setHostnameVerifier</th>
* <td>The ability to set a callback which can decide whether to
* allow a mismatch between the host being connected to by
* an HttpsURLConnection and the common name field in
* server certificate.
* </td>
* <td>Malicious
* code can set a verifier that monitors host names visited by
* HttpsURLConnection requests or that allows server certificates
* with invalid common names.
* </td>
* </tr>
*
* <tr>
* <th scope="row">getSSLSessionContext</th>
* <td>The ability to get the SSLSessionContext of an SSLSession.
* </td>
* <td>Malicious code may monitor sessions which have been established
* with SSL peers or might invalidate sessions to slow down performance.
* </td>
* </tr>
*
* <tr>
* <th scope="row">setDefaultSSLContext</th>
* <td>The ability to set the default SSL context
* </td>
* <td>Malicious code can set a context that monitors the opening of
* connections or the plaintext data that is transmitted.
* </td>
* </tr>
*
* </tbody>
* </table>
*
* @see java.security.BasicPermission
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
* @since 1.4
* @author Marianne Mueller
* @author Roland Schemers
*/
public final class SSLPermission extends BasicPermission {
private static final long serialVersionUID = -3456898025505876775L;
/**
* Creates a new SSLPermission with the specified name.
* The name is the symbolic name of the SSLPermission, such as
* "setDefaultAuthenticator", etc. An asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match.
*
* @param name the name of the SSLPermission.
*
* @throws NullPointerException if <code>name</code> is null.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public SSLPermission(String name)
{
super(name);
}
/**
* Creates a new SSLPermission object with the specified name.
* The name is the symbolic name of the SSLPermission, and the
* actions String is currently unused and should be null.
*
* @param name the name of the SSLPermission.
* @param actions ignored.
*
* @throws NullPointerException if <code>name</code> is null.
* @throws IllegalArgumentException if <code>name</code> is empty.
*/
public SSLPermission(String name, String actions)
{
super(name, actions);
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 1996, 2003, 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 javax.net.ssl;
/**
* Reports an error in the operation of the SSL protocol. Normally
* this indicates a flaw in one of the protocol implementations.
*
* @since 1.4
* @author David Brownell
*/
public
class SSLProtocolException extends SSLException
{
private static final long serialVersionUID = 5445067063799134928L;
/**
* Constructs an exception reporting an SSL protocol error
* detected by an SSL subsystem.
*
* @param reason describes the problem.
*/
public SSLProtocolException(String reason)
{
super(reason);
}
}

View file

@ -0,0 +1,557 @@
/*
* Copyright (c) 1997, 2017, 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 javax.net.ssl;
import java.io.*;
import java.net.*;
/**
* This class extends <code>ServerSocket</code> and
* provides secure server sockets using protocols such as the Secure
* Sockets Layer (SSL) or Transport Layer Security (TLS) protocols.
* <P>
* Instances of this class are generally created using an
* <code>SSLServerSocketFactory</code>. The primary function
* of an <code>SSLServerSocket</code>
* is to create <code>SSLSocket</code>s by <code>accept</code>ing
* connections.
* <P>
* An <code>SSLServerSocket</code> contains several pieces of state data
* which are inherited by the <code>SSLSocket</code> at
* socket creation. These include the enabled cipher
* suites and protocols, whether client
* authentication is necessary, and whether created sockets should
* begin handshaking in client or server mode. The state
* inherited by the created <code>SSLSocket</code> can be
* overriden by calling the appropriate methods.
*
* @see java.net.ServerSocket
* @see SSLSocket
*
* @since 1.4
* @author David Brownell
*/
public abstract class SSLServerSocket extends ServerSocket {
/**
* Used only by subclasses.
* <P>
* Create an unbound TCP server socket using the default authentication
* context.
*
* @throws IOException if an I/O error occurs when creating the socket
*/
protected SSLServerSocket()
throws IOException
{ super(); }
/**
* Used only by subclasses.
* <P>
* Create a TCP server socket on a port, using the default
* authentication context. The connection backlog defaults to
* fifty connections queued up before the system starts to
* reject new connection requests.
* <P>
* A port number of <code>0</code> creates a socket on any free port.
* <P>
* If there is a security manager, its <code>checkListen</code>
* method is called with the <code>port</code> argument as its
* argument to ensure the operation is allowed. This could result
* in a SecurityException.
*
* @param port the port on which to listen
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkListen</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkListen
*/
protected SSLServerSocket(int port)
throws IOException
{ super(port); }
/**
* Used only by subclasses.
* <P>
* Create a TCP server socket on a port, using the default
* authentication context and a specified backlog of connections.
* <P>
* A port number of <code>0</code> creates a socket on any free port.
* <P>
* The <code>backlog</code> argument is the requested maximum number of
* pending connections on the socket. Its exact semantics are implementation
* specific. In particular, an implementation may impose a maximum length
* or may choose to ignore the parameter altogther. The value provided
* should be greater than <code>0</code>. If it is less than or equal to
* <code>0</code>, then an implementation specific default will be used.
* <P>
* If there is a security manager, its <code>checkListen</code>
* method is called with the <code>port</code> argument as its
* argument to ensure the operation is allowed. This could result
* in a SecurityException.
*
* @param port the port on which to listen
* @param backlog requested maximum length of the queue of incoming
* connections.
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkListen</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkListen
*/
protected SSLServerSocket(int port, int backlog)
throws IOException
{ super(port, backlog); }
/**
* Used only by subclasses.
* <P>
* Create a TCP server socket on a port, using the default
* authentication context and a specified backlog of connections
* as well as a particular specified network interface. This
* constructor is used on multihomed hosts, such as those used
* for firewalls or as routers, to control through which interface
* a network service is provided.
* <P>
* If there is a security manager, its <code>checkListen</code>
* method is called with the <code>port</code> argument as its
* argument to ensure the operation is allowed. This could result
* in a SecurityException.
* <P>
* A port number of <code>0</code> creates a socket on any free port.
* <P>
* The <code>backlog</code> argument is the requested maximum number of
* pending connections on the socket. Its exact semantics are implementation
* specific. In particular, an implementation may impose a maximum length
* or may choose to ignore the parameter altogther. The value provided
* should be greater than <code>0</code>. If it is less than or equal to
* <code>0</code>, then an implementation specific default will be used.
* <P>
* If <i>address</i> is null, it will default accepting connections
* on any/all local addresses.
*
* @param port the port on which to listen
* @param backlog requested maximum length of the queue of incoming
* connections.
* @param address the address of the network interface through
* which connections will be accepted
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkListen</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkListen
*/
protected SSLServerSocket(int port, int backlog, InetAddress address)
throws IOException
{ super(port, backlog, address); }
/**
* Returns the list of cipher suites which are currently enabled
* for use by newly accepted connections.
* <P>
* If this list has not been explicitly modified, a system-provided
* default guarantees a minimum quality of service in all enabled
* cipher suites.
* <P>
* Note that even if a suite is enabled, it may never be used. This
* can occur if the peer does not support it, or its use is restricted,
* or the requisite certificates (and private keys) for the suite are
* not available, or an anonymous suite is enabled but authentication
* is required.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suites enabled
* @see #getSupportedCipherSuites()
* @see #setEnabledCipherSuites(String [])
*/
public abstract String [] getEnabledCipherSuites();
/**
* Sets the cipher suites enabled for use by accepted connections.
* <P>
* The cipher suites must have been listed by getSupportedCipherSuites()
* as being supported. Following a successful call to this method,
* only suites listed in the <code>suites</code> parameter are enabled
* for use.
* <P>
* Suites that require authentication information which is not available
* in this ServerSocket's authentication context will not be used
* in any case, even if they are enabled.
* <P>
* Note that the standard list of cipher suite names may be found in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list or might not
* use the recommended name for a certain cipher suite.
* <P>
* <code>SSLSocket</code>s returned from <code>accept()</code>
* inherit this setting.
*
* @param suites Names of all the cipher suites to enable
* @exception IllegalArgumentException when one or more of ciphers
* named by the parameter is not supported, or when
* the parameter is null.
* @see #getSupportedCipherSuites()
* @see #getEnabledCipherSuites()
*/
public abstract void setEnabledCipherSuites(String suites []);
/**
* Returns the names of the cipher suites which could be enabled for use
* on an SSL connection.
* <P>
* Normally, only a subset of these will actually
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites are useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getEnabledCipherSuites()
* @see #setEnabledCipherSuites(String [])
*/
public abstract String [] getSupportedCipherSuites();
/**
* Returns the names of the protocols which could be enabled for use.
*
* @return an array of protocol names supported
* @see #getEnabledProtocols()
* @see #setEnabledProtocols(String [])
*/
public abstract String [] getSupportedProtocols();
/**
* Returns the names of the protocols which are currently
* enabled for use by the newly accepted connections.
* <P>
* Note that even if a protocol is enabled, it may never be used.
* This can occur if the peer does not support the protocol, or its
* use is restricted, or there are no enabled cipher suites supported
* by the protocol.
*
* @return an array of protocol names
* @see #getSupportedProtocols()
* @see #setEnabledProtocols(String [])
*/
public abstract String [] getEnabledProtocols();
/**
* Controls which particular protocols are enabled for use by
* accepted connections.
* <P>
* The protocols must have been listed by
* getSupportedProtocols() as being supported.
* Following a successful call to this method, only protocols listed
* in the <code>protocols</code> parameter are enabled for use.
* <P>
* <code>SSLSocket</code>s returned from <code>accept()</code>
* inherit this setting.
*
* @param protocols Names of all the protocols to enable.
* @exception IllegalArgumentException when one or more of
* the protocols named by the parameter is not supported or
* when the protocols parameter is null.
* @see #getEnabledProtocols()
* @see #getSupportedProtocols()
*/
public abstract void setEnabledProtocols(String protocols[]);
/**
* Controls whether <code>accept</code>ed server-mode
* <code>SSLSockets</code> will be initially configured to
* <i>require</i> client authentication.
* <P>
* A socket's client authentication setting is one of the following:
* <ul>
* <li> client authentication required
* <li> client authentication requested
* <li> no client authentication desired
* </ul>
* <P>
* Unlike {@link #setWantClientAuth(boolean)}, if the accepted
* socket's option is set and the client chooses not to provide
* authentication information about itself, <i>the negotiations
* will stop and the connection will be dropped</i>.
* <P>
* Calling this method overrides any previous setting made by
* this method or {@link #setWantClientAuth(boolean)}.
* <P>
* The initial inherited setting may be overridden by calling
* {@link SSLSocket#setNeedClientAuth(boolean)} or
* {@link SSLSocket#setWantClientAuth(boolean)}.
*
* @param need set to true if client authentication is required,
* or false if no client authentication is desired.
* @see #getNeedClientAuth()
* @see #setWantClientAuth(boolean)
* @see #getWantClientAuth()
* @see #setUseClientMode(boolean)
*/
public abstract void setNeedClientAuth(boolean need);
/**
* Returns true if client authentication will be <i>required</i> on
* newly <code>accept</code>ed server-mode <code>SSLSocket</code>s.
* <P>
* The initial inherited setting may be overridden by calling
* {@link SSLSocket#setNeedClientAuth(boolean)} or
* {@link SSLSocket#setWantClientAuth(boolean)}.
*
* @return true if client authentication is required,
* or false if no client authentication is desired.
* @see #setNeedClientAuth(boolean)
* @see #setWantClientAuth(boolean)
* @see #getWantClientAuth()
* @see #setUseClientMode(boolean)
*/
public abstract boolean getNeedClientAuth();
/**
* Controls whether <code>accept</code>ed server-mode
* <code>SSLSockets</code> will be initially configured to
* <i>request</i> client authentication.
* <P>
* A socket's client authentication setting is one of the following:
* <ul>
* <li> client authentication required
* <li> client authentication requested
* <li> no client authentication desired
* </ul>
* <P>
* Unlike {@link #setNeedClientAuth(boolean)}, if the accepted
* socket's option is set and the client chooses not to provide
* authentication information about itself, <i>the negotiations
* will continue</i>.
* <P>
* Calling this method overrides any previous setting made by
* this method or {@link #setNeedClientAuth(boolean)}.
* <P>
* The initial inherited setting may be overridden by calling
* {@link SSLSocket#setNeedClientAuth(boolean)} or
* {@link SSLSocket#setWantClientAuth(boolean)}.
*
* @param want set to true if client authentication is requested,
* or false if no client authentication is desired.
* @see #getWantClientAuth()
* @see #setNeedClientAuth(boolean)
* @see #getNeedClientAuth()
* @see #setUseClientMode(boolean)
*/
public abstract void setWantClientAuth(boolean want);
/**
* Returns true if client authentication will be <i>requested</i> on
* newly accepted server-mode connections.
* <P>
* The initial inherited setting may be overridden by calling
* {@link SSLSocket#setNeedClientAuth(boolean)} or
* {@link SSLSocket#setWantClientAuth(boolean)}.
*
* @return true if client authentication is requested,
* or false if no client authentication is desired.
* @see #setWantClientAuth(boolean)
* @see #setNeedClientAuth(boolean)
* @see #getNeedClientAuth()
* @see #setUseClientMode(boolean)
*/
public abstract boolean getWantClientAuth();
/**
* Controls whether accepted connections are in the (default) SSL
* server mode, or the SSL client mode.
* <P>
* Servers normally authenticate themselves, and clients are not
* required to do so.
* <P>
* In rare cases, TCP servers
* need to act in the SSL client mode on newly accepted
* connections. For example, FTP clients acquire server sockets
* and listen there for reverse connections from the server. An
* FTP client would use an SSLServerSocket in "client" mode to
* accept the reverse connection while the FTP server uses an
* SSLSocket with "client" mode disabled to initiate the
* connection. During the resulting handshake, existing SSL
* sessions may be reused.
* <P>
* <code>SSLSocket</code>s returned from <code>accept()</code>
* inherit this setting.
*
* @param mode true if newly accepted connections should use SSL
* client mode.
* @see #getUseClientMode()
*/
public abstract void setUseClientMode(boolean mode);
/**
* Returns true if accepted connections will be in SSL client mode.
*
* @see #setUseClientMode(boolean)
* @return true if the connection should use SSL client mode.
*/
public abstract boolean getUseClientMode();
/**
* Controls whether new SSL sessions may be established by the
* sockets which are created from this server socket.
* <P>
* <code>SSLSocket</code>s returned from <code>accept()</code>
* inherit this setting.
*
* @param flag true indicates that sessions may be created; this
* is the default. false indicates that an existing session
* must be resumed.
* @see #getEnableSessionCreation()
*/
public abstract void setEnableSessionCreation(boolean flag);
/**
* Returns true if new SSL sessions may be established by the
* sockets which are created from this server socket.
*
* @return true indicates that sessions may be created; this
* is the default. false indicates that an existing
* session must be resumed
* @see #setEnableSessionCreation(boolean)
*/
public abstract boolean getEnableSessionCreation();
/**
* Returns the SSLParameters in effect for newly accepted connections.
* The ciphersuites and protocols of the returned SSLParameters
* are always non-null.
*
* @return the SSLParameters in effect for newly accepted connections
*
* @see #setSSLParameters(SSLParameters)
*
* @since 1.7
*/
public SSLParameters getSSLParameters() {
SSLParameters parameters = new SSLParameters();
parameters.setCipherSuites(getEnabledCipherSuites());
parameters.setProtocols(getEnabledProtocols());
if (getNeedClientAuth()) {
parameters.setNeedClientAuth(true);
} else if (getWantClientAuth()) {
parameters.setWantClientAuth(true);
}
return parameters;
}
/**
* Applies SSLParameters to newly accepted connections.
*
* <p>This means:
* <ul>
* <li>If {@code params.getCipherSuites()} is non-null,
* {@code setEnabledCipherSuites()} is called with that value.</li>
* <li>If {@code params.getProtocols()} is non-null,
* {@code setEnabledProtocols()} is called with that value.</li>
* <li>If {@code params.getNeedClientAuth()} or
* {@code params.getWantClientAuth()} return {@code true},
* {@code setNeedClientAuth(true)} and
* {@code setWantClientAuth(true)} are called, respectively;
* otherwise {@code setWantClientAuth(false)} is called.</li>
* <li>If {@code params.getServerNames()} is non-null, the socket will
* configure its server names with that value.</li>
* <li>If {@code params.getSNIMatchers()} is non-null, the socket will
* configure its SNI matchers with that value.</li>
* </ul>
*
* @param params the parameters
* @throws IllegalArgumentException if the setEnabledCipherSuites() or
* the setEnabledProtocols() call fails
*
* @see #getSSLParameters()
*
* @since 1.7
*/
public void setSSLParameters(SSLParameters params) {
String[] s;
s = params.getCipherSuites();
if (s != null) {
setEnabledCipherSuites(s);
}
s = params.getProtocols();
if (s != null) {
setEnabledProtocols(s);
}
if (params.getNeedClientAuth()) {
setNeedClientAuth(true);
} else if (params.getWantClientAuth()) {
setWantClientAuth(true);
} else {
setWantClientAuth(false);
}
}
}

View file

@ -0,0 +1,215 @@
/*
* Copyright (c) 1997, 2017, 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 javax.net.ssl;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.SocketException;
import javax.net.ServerSocketFactory;
import java.security.*;
/**
* <code>SSLServerSocketFactory</code>s create
* <code>SSLServerSocket</code>s.
*
* @since 1.4
* @see SSLSocket
* @see SSLServerSocket
* @author David Brownell
*/
public abstract class SSLServerSocketFactory extends ServerSocketFactory
{
private static SSLServerSocketFactory theFactory;
private static boolean propertyChecked;
private static void log(String msg) {
if (SSLSocketFactory.DEBUG) {
System.out.println(msg);
}
}
/**
* Constructor is used only by subclasses.
*/
protected SSLServerSocketFactory() { /* NOTHING */ }
/**
* Returns the default SSL server socket factory.
*
* <p>The first time this method is called, the security property
* "ssl.ServerSocketFactory.provider" is examined. If it is non-null, a
* class by that name is loaded and instantiated. If that is successful and
* the object is an instance of SSLServerSocketFactory, it is made the
* default SSL server socket factory.
*
* <p>Otherwise, this method returns
* <code>SSLContext.getDefault().getServerSocketFactory()</code>. If that
* call fails, an inoperative factory is returned.
*
* @return the default <code>ServerSocketFactory</code>
* @see SSLContext#getDefault
*/
public static synchronized ServerSocketFactory getDefault() {
if (theFactory != null) {
return theFactory;
}
if (propertyChecked == false) {
propertyChecked = true;
String clsName = SSLSocketFactory.getSecurityProperty
("ssl.ServerSocketFactory.provider");
if (clsName != null) {
log("setting up default SSLServerSocketFactory");
try {
Class<?> cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
log("class " + clsName + " is loaded");
@SuppressWarnings("deprecation")
SSLServerSocketFactory fac = (SSLServerSocketFactory)cls.newInstance();
log("instantiated an instance of class " + clsName);
theFactory = fac;
return fac;
} catch (Exception e) {
log("SSLServerSocketFactory instantiation failed: " + e);
theFactory = new DefaultSSLServerSocketFactory(e);
return theFactory;
}
}
}
try {
return SSLContext.getDefault().getServerSocketFactory();
} catch (NoSuchAlgorithmException e) {
return new DefaultSSLServerSocketFactory(e);
}
}
/**
* Returns the list of cipher suites which are enabled by default.
* Unless a different list is enabled, handshaking on an SSL connection
* will use one of these cipher suites. The minimum quality of service
* for these defaults requires confidentiality protection and server
* authentication (that is, no anonymous cipher suites).
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @see #getSupportedCipherSuites()
* @return array of the cipher suites enabled by default
*/
public abstract String [] getDefaultCipherSuites();
/**
* Returns the names of the cipher suites which could be enabled for use
* on an SSL connection created by this factory.
* Normally, only a subset of these will actually
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites are useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getDefaultCipherSuites()
*/
public abstract String [] getSupportedCipherSuites();
}
//
// The default factory does NOTHING.
//
class DefaultSSLServerSocketFactory extends SSLServerSocketFactory {
private final Exception reason;
DefaultSSLServerSocketFactory(Exception reason) {
this.reason = reason;
}
private ServerSocket throwException() throws SocketException {
throw (SocketException)
new SocketException(reason.toString()).initCause(reason);
}
@Override
public ServerSocket createServerSocket() throws IOException {
return throwException();
}
@Override
public ServerSocket createServerSocket(int port)
throws IOException
{
return throwException();
}
@Override
public ServerSocket createServerSocket(int port, int backlog)
throws IOException
{
return throwException();
}
@Override
public ServerSocket
createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException
{
return throwException();
}
@Override
public String [] getDefaultCipherSuites() {
return new String[0];
}
@Override
public String [] getSupportedCipherSuites() {
return new String[0];
}
}

View file

@ -0,0 +1,420 @@
/*
* Copyright (c) 1997, 2017, 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 javax.net.ssl;
import java.security.Principal;
/**
* In SSL, sessions are used to describe an ongoing relationship between
* two entities. Each SSL connection involves one session at a time, but
* that session may be used on many connections between those entities,
* simultaneously or sequentially. The session used on a connection may
* also be replaced by a different session. Sessions are created, or
* rejoined, as part of the SSL handshaking protocol. Sessions may be
* invalidated due to policies affecting security or resource usage,
* or by an application explicitly calling {@code invalidate}.
* Session management policies are typically used to tune performance.
*
* <P> In addition to the standard session attributes, SSL sessions expose
* these read-only attributes: <UL>
*
* <LI> <em>Peer Identity.</em> Sessions are between a particular
* client and a particular server. The identity of the peer may
* have been established as part of session setup. Peers are
* generally identified by X.509 certificate chains.
*
* <LI> <em>Cipher Suite Name.</em> Cipher suites describe the
* kind of cryptographic protection that's used by connections
* in a particular session.
*
* <LI> <em>Peer Host.</em> All connections in a session are
* between the same two hosts. The address of the host on the other
* side of the connection is available.
*
* </UL>
*
* <P> Sessions may be explicitly invalidated. Invalidation may also
* be done implicitly, when faced with certain kinds of errors.
*
* @since 1.4
* @author David Brownell
*/
public interface SSLSession {
/**
* Returns the identifier assigned to this Session.
*
* @return the Session identifier
*/
public byte[] getId();
/**
* Returns the context in which this session is bound.
* <P>
* This context may be unavailable in some environments,
* in which case this method returns null.
* <P>
* If the context is available and there is a
* security manager installed, the caller may require
* permission to access it or a security exception may be thrown.
* In a Java environment, the security manager's
* {@code checkPermission} method is called with a
* {@code SSLPermission("getSSLSessionContext")} permission.
*
* @throws SecurityException if the calling thread does not have
* permission to get SSL session context.
* @return the session context used for this session, or null
* if the context is unavailable.
*/
public SSLSessionContext getSessionContext();
/**
* Returns the time at which this Session representation was created,
* in milliseconds since midnight, January 1, 1970 UTC.
*
* @return the time this Session was created
*/
public long getCreationTime();
/**
* Returns the last time this Session representation was accessed by the
* session level infrastructure, in milliseconds since
* midnight, January 1, 1970 UTC.
* <P>
* Access indicates a new connection being established using session data.
* Application level operations, such as getting or setting a value
* associated with the session, are not reflected in this access time.
*
* <P> This information is particularly useful in session management
* policies. For example, a session manager thread could leave all
* sessions in a given context which haven't been used in a long time;
* or, the sessions might be sorted according to age to optimize some task.
*
* @return the last time this Session was accessed
*/
public long getLastAccessedTime();
/**
* Invalidates the session.
* <P>
* Future connections will not be able to
* resume or join this session. However, any existing connection
* using this session can continue to use the session until the
* connection is closed.
*
* @see #isValid()
*/
public void invalidate();
/**
* Returns whether this session is valid and available for resuming or
* joining.
*
* @return true if this session may be rejoined.
* @see #invalidate()
*
* @since 1.5
*/
public boolean isValid();
/**
*
* Binds the specified {@code value} object into the
* session's application layer data
* with the given {@code name}.
* <P>
* Any existing binding using the same {@code name} is
* replaced. If the new (or existing) {@code value} implements the
* {@code SSLSessionBindingListener} interface, the object
* represented by {@code value} is notified appropriately.
* <p>
* For security reasons, the same named values may not be
* visible across different access control contexts.
*
* @param name the name to which the data object will be bound.
* This may not be null.
* @param value the data object to be bound. This may not be null.
* @throws IllegalArgumentException if either argument is null.
*/
public void putValue(String name, Object value);
/**
* Returns the object bound to the given name in the session's
* application layer data. Returns null if there is no such binding.
* <p>
* For security reasons, the same named values may not be
* visible across different access control contexts.
*
* @param name the name of the binding to find.
* @return the value bound to that name, or null if the binding does
* not exist.
* @throws IllegalArgumentException if the argument is null.
*/
public Object getValue(String name);
/**
* Removes the object bound to the given name in the session's
* application layer data. Does nothing if there is no object
* bound to the given name. If the bound existing object
* implements the {@code SessionBindingListener} interface,
* it is notified appropriately.
* <p>
* For security reasons, the same named values may not be
* visible across different access control contexts.
*
* @param name the name of the object to remove visible
* across different access control contexts
* @throws IllegalArgumentException if the argument is null.
*/
public void removeValue(String name);
/**
* Returns an array of the names of all the application layer
* data objects bound into the Session.
* <p>
* For security reasons, the same named values may not be
* visible across different access control contexts.
*
* @return a non-null (possibly empty) array of names of the objects
* bound to this Session.
*/
public String [] getValueNames();
/**
* Returns the identity of the peer which was established as part
* of defining the session.
* <P>
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* @return an ordered array of peer certificates,
* with the peer's own certificate first followed by any
* certificate authorities.
* @exception SSLPeerUnverifiedException if the peer's identity has not
* been verified
* @see #getPeerPrincipal()
*/
public java.security.cert.Certificate [] getPeerCertificates()
throws SSLPeerUnverifiedException;
/**
* Returns the certificate(s) that were sent to the peer during
* handshaking.
* <P>
* Note: This method is useful only when using certificate-based
* cipher suites.
* <P>
* When multiple certificates are available for use in a
* handshake, the implementation chooses what it considers the
* "best" certificate chain available, and transmits that to
* the other side. This method allows the caller to know
* which certificate chain was actually used.
*
* @return an ordered array of certificates,
* with the local certificate first followed by any
* certificate authorities. If no certificates were sent,
* then null is returned.
*
* @see #getLocalPrincipal()
*/
public java.security.cert.Certificate [] getLocalCertificates();
/**
* Returns the identity of the peer which was identified as part
* of defining the session.
* <P>
* Note: This method can be used only when using certificate-based
* cipher suites; using it with non-certificate-based cipher suites,
* such as Kerberos, will throw an SSLPeerUnverifiedException.
* <P>
* Note: The returned value may not be a valid certificate chain
* and should not be relied on for trust decisions.
*
* <p><em>Note: this method exists for compatibility with previous
* releases. New applications should use
* {@link #getPeerCertificates} instead.</em></p>
*
* @return an ordered array of peer X.509 certificates,
* with the peer's own certificate first followed by any
* certificate authorities. (The certificates are in
* the original JSSE certificate
* {@link javax.security.cert.X509Certificate} format.)
* @exception SSLPeerUnverifiedException if the peer's identity
* has not been verified
* @see #getPeerPrincipal()
* @deprecated The {@link #getPeerCertificates()} method that returns an
* array of {@code java.security.cert.Certificate} should
* be used instead.
*/
@Deprecated(since="9")
public javax.security.cert.X509Certificate [] getPeerCertificateChain()
throws SSLPeerUnverifiedException;
/**
* Returns the identity of the peer which was established as part of
* defining the session.
*
* @return the peer's principal. Returns an X500Principal of the
* end-entity certiticate for X509-based cipher suites, and
* KerberosPrincipal for Kerberos cipher suites.
*
* @throws SSLPeerUnverifiedException if the peer's identity has not
* been verified
*
* @see #getPeerCertificates()
* @see #getLocalPrincipal()
*
* @since 1.5
*/
public Principal getPeerPrincipal()
throws SSLPeerUnverifiedException;
/**
* Returns the principal that was sent to the peer during handshaking.
*
* @return the principal sent to the peer. Returns an X500Principal
* of the end-entity certificate for X509-based cipher suites, and
* KerberosPrincipal for Kerberos cipher suites. If no principal was
* sent, then null is returned.
*
* @see #getLocalCertificates()
* @see #getPeerPrincipal()
*
* @since 1.5
*/
public Principal getLocalPrincipal();
/**
* Returns the name of the SSL cipher suite which is used for all
* connections in the session.
*
* <P> This defines the level of protection
* provided to the data sent on the connection, including the kind
* of encryption used and most aspects of how authentication is done.
*
* @return the name of the session's cipher suite
*/
public String getCipherSuite();
/**
* Returns the standard name of the protocol used for all
* connections in the session.
*
* <P> This defines the protocol used in the connection.
*
* @return the standard name of the protocol used for all
* connections in the session.
*/
public String getProtocol();
/**
* Returns the host name of the peer in this session.
* <P>
* For the server, this is the client's host; and for
* the client, it is the server's host. The name may not be
* a fully qualified host name or even a host name at all as
* it may represent a string encoding of the peer's network address.
* If such a name is desired, it might
* be resolved through a name service based on the value returned
* by this method.
* <P>
* This value is not authenticated and should not be relied upon.
* It is mainly used as a hint for {@code SSLSession} caching
* strategies.
*
* @return the host name of the peer host, or null if no information
* is available.
*/
public String getPeerHost();
/**
* Returns the port number of the peer in this session.
* <P>
* For the server, this is the client's port number; and for
* the client, it is the server's port number.
* <P>
* This value is not authenticated and should not be relied upon.
* It is mainly used as a hint for {@code SSLSession} caching
* strategies.
*
* @return the port number of the peer host, or -1 if no information
* is available.
*
* @since 1.5
*/
public int getPeerPort();
/**
* Gets the current size of the largest SSL/TLS/DTLS packet that is
* expected when using this session.
* <P>
* An {@code SSLEngine} using this session may generate SSL/TLS/DTLS
* packets of any size up to and including the value returned by this
* method. All {@code SSLEngine} network buffers should be sized
* at least this large to avoid insufficient space problems when
* performing {@code wrap} and {@code unwrap} calls.
*
* @return the current maximum expected network packet size
*
* @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
* @see SSLEngine#unwrap(ByteBuffer, ByteBuffer)
*
* @since 1.5
*/
public int getPacketBufferSize();
/**
* Gets the current size of the largest application data that is
* expected when using this session.
* <P>
* {@code SSLEngine} application data buffers must be large
* enough to hold the application data from any inbound network
* application data packet received. Typically, outbound
* application data buffers can be of any size.
*
* @return the current maximum expected application packet size
*
* @see SSLEngine#wrap(ByteBuffer, ByteBuffer)
* @see SSLEngine#unwrap(ByteBuffer, ByteBuffer)
*
* @since 1.5
*/
public int getApplicationBufferSize();
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 1997, 2005, 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 javax.net.ssl;
import java.util.EventObject;
/**
* This event is propagated to a SSLSessionBindingListener.
* When a listener object is bound or unbound to an SSLSession by
* {@link SSLSession#putValue(String, Object)}
* or {@link SSLSession#removeValue(String)}, objects which
* implement the SSLSessionBindingListener will be receive an
* event of this type. The event's <code>name</code> field is the
* key in which the listener is being bound or unbound.
*
* @see SSLSession
* @see SSLSessionBindingListener
*
* @since 1.4
* @author Nathan Abramson
* @author David Brownell
*/
public
class SSLSessionBindingEvent
extends EventObject
{
private static final long serialVersionUID = 3989172637106345L;
/**
* @serial The name to which the object is being bound or unbound
*/
private String name;
/**
* Constructs a new SSLSessionBindingEvent.
*
* @param session the SSLSession acting as the source of the event
* @param name the name to which the object is being bound or unbound
* @exception IllegalArgumentException if <code>session</code> is null.
*/
public SSLSessionBindingEvent(SSLSession session, String name)
{
super(session);
this.name = name;
}
/**
* Returns the name to which the object is being bound, or the name
* from which the object is being unbound.
*
* @return the name to which the object is being bound or unbound
*/
public String getName()
{
return name;
}
/**
* Returns the SSLSession into which the listener is being bound or
* from which the listener is being unbound.
*
* @return the <code>SSLSession</code>
*/
public SSLSession getSession()
{
return (SSLSession) getSource();
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 1997, 2001, 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 javax.net.ssl;
import java.util.EventListener;
/**
* This interface is implemented by objects which want to know when
* they are being bound or unbound from a SSLSession. When either event
* occurs via {@link SSLSession#putValue(String, Object)}
* or {@link SSLSession#removeValue(String)}, the event is communicated
* through a SSLSessionBindingEvent identifying the session.
*
* @see SSLSession
* @see SSLSessionBindingEvent
*
* @since 1.4
* @author Nathan Abramson
* @author David Brownell
*/
public
interface SSLSessionBindingListener
extends EventListener
{
/**
* This is called to notify the listener that it is being bound into
* an SSLSession.
*
* @param event the event identifying the SSLSession into
* which the listener is being bound.
*/
public void valueBound(SSLSessionBindingEvent event);
/**
* This is called to notify the listener that it is being unbound
* from a SSLSession.
*
* @param event the event identifying the SSLSession from
* which the listener is being unbound.
*/
public void valueUnbound(SSLSessionBindingEvent event);
}

View file

@ -0,0 +1,141 @@
/*
* Copyright (c) 1997, 2013, 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 javax.net.ssl;
import java.util.Enumeration;
/**
* A <code>SSLSessionContext</code> represents a set of
* <code>SSLSession</code>s associated with a single entity. For example,
* it could be associated with a server or client who participates in many
* sessions concurrently.
* <p>
* Not all environments will contain session contexts.
* <p>
* There are <code>SSLSessionContext</code> parameters that affect how
* sessions are stored:
* <UL>
* <LI>Sessions can be set to expire after a specified
* time limit.
* <LI>The number of sessions that can be stored in context
* can be limited.
* </UL>
* A session can be retrieved based on its session id, and all session id's
* in a <code>SSLSessionContext</code> can be listed.
*
* @see SSLSession
*
* @since 1.4
* @author Nathan Abramson
* @author David Brownell
*/
public interface SSLSessionContext {
/**
* Returns the <code>SSLSession</code> bound to the specified session id.
*
* @param sessionId the Session identifier
* @return the <code>SSLSession</code> or null if
* the specified session id does not refer to a valid SSLSession.
*
* @throws NullPointerException if <code>sessionId</code> is null.
*/
public SSLSession getSession(byte[] sessionId);
/**
* Returns an Enumeration of all session id's grouped under this
* <code>SSLSessionContext</code>.
*
* @return an enumeration of all the Session id's
*/
public Enumeration<byte[]> getIds();
/**
* Sets the timeout limit for <code>SSLSession</code> objects grouped
* under this <code>SSLSessionContext</code>.
* <p>
* If the timeout limit is set to 't' seconds, a session exceeds the
* timeout limit 't' seconds after its creation time.
* When the timeout limit is exceeded for a session, the
* <code>SSLSession</code> object is invalidated and future connections
* cannot resume or rejoin the session.
* A check for sessions exceeding the timeout is made immediately whenever
* the timeout limit is changed for this <code>SSLSessionContext</code>.
*
* @param seconds the new session timeout limit in seconds; zero means
* there is no limit.
*
* @exception IllegalArgumentException if the timeout specified is {@code < 0}.
* @see #getSessionTimeout
*/
public void setSessionTimeout(int seconds)
throws IllegalArgumentException;
/**
* Returns the timeout limit of <code>SSLSession</code> objects grouped
* under this <code>SSLSessionContext</code>.
* <p>
* If the timeout limit is set to 't' seconds, a session exceeds the
* timeout limit 't' seconds after its creation time.
* When the timeout limit is exceeded for a session, the
* <code>SSLSession</code> object is invalidated and future connections
* cannot resume or rejoin the session.
* A check for sessions exceeding the timeout limit is made immediately
* whenever the timeout limit is changed for this
* <code>SSLSessionContext</code>.
*
* @return the session timeout limit in seconds; zero means there is no
* limit.
* @see #setSessionTimeout
*/
public int getSessionTimeout();
/**
* Sets the size of the cache used for storing
* <code>SSLSession</code> objects grouped under this
* <code>SSLSessionContext</code>.
*
* @param size the new session cache size limit; zero means there is no
* limit.
* @exception IllegalArgumentException if the specified size is {@code < 0}.
* @see #getSessionCacheSize
*/
public void setSessionCacheSize(int size)
throws IllegalArgumentException;
/**
* Returns the size of the cache used for storing
* <code>SSLSession</code> objects grouped under this
* <code>SSLSessionContext</code>.
*
* @return size of the session cache; zero means there is no size limit.
* @see #setSessionCacheSize
*/
public int getSessionCacheSize();
}

View file

@ -0,0 +1,834 @@
/*
* Copyright (c) 1997, 2017, 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 javax.net.ssl;
import java.io.IOException;
import java.net.*;
import java.util.List;
import java.util.function.BiFunction;
/**
* This class extends <code>Socket</code> and provides secure
* sockets using protocols such as the "Secure
* Sockets Layer" (SSL) or IETF "Transport Layer Security" (TLS) protocols.
* <P>
* Such sockets are normal stream sockets, but they
* add a layer of security protections over the underlying network transport
* protocol, such as TCP. Those protections include: <UL>
*
* <LI> <em>Integrity Protection</em>. SSL protects against
* modification of messages by an active wiretapper.
*
* <LI> <em>Authentication</em>. In most modes, SSL provides
* peer authentication. Servers are usually authenticated,
* and clients may be authenticated as requested by servers.
*
* <LI> <em>Confidentiality (Privacy Protection)</em>. In most
* modes, SSL encrypts data being sent between client and server.
* This protects the confidentiality of data, so that passive
* wiretappers won't see sensitive data such as financial
* information or personal information of many kinds.
*
* </UL>
*
* <P>These kinds of protection are specified by a "cipher suite", which
* is a combination of cryptographic algorithms used by a given SSL connection.
* During the negotiation process, the two endpoints must agree on
* a ciphersuite that is available in both environments.
* If there is no such suite in common, no SSL connection can
* be established, and no data can be exchanged.
*
* <P> The cipher suite used is established by a negotiation process
* called "handshaking". The goal of this
* process is to create or rejoin a "session", which may protect many
* connections over time. After handshaking has completed, you can access
* session attributes by using the <em>getSession</em> method.
* The initial handshake on this connection can be initiated in
* one of three ways: <UL>
*
* <LI> calling <code>startHandshake</code> which explicitly
* begins handshakes, or
* <LI> any attempt to read or write application data on
* this socket causes an implicit handshake, or
* <LI> a call to <code>getSession</code> tries to set up a session
* if there is no currently valid session, and
* an implicit handshake is done.
* </UL>
*
* <P>If handshaking fails for any reason, the <code>SSLSocket</code>
* is closed, and no further communications can be done.
*
* <P>There are two groups of cipher suites which you will need to know
* about when managing cipher suites: <UL>
*
* <LI> <em>Supported</em> cipher suites: all the suites which are
* supported by the SSL implementation. This list is reported
* using <em>getSupportedCipherSuites</em>.
*
* <LI> <em>Enabled</em> cipher suites, which may be fewer
* than the full set of supported suites. This group is
* set using the <em>setEnabledCipherSuites</em> method, and
* queried using the <em>getEnabledCipherSuites</em> method.
* Initially, a default set of cipher suites will be enabled on
* a new socket that represents the minimum suggested configuration.
*
* </UL>
*
* <P> Implementation defaults require that only cipher
* suites which authenticate servers and provide confidentiality
* be enabled by default.
* Only if both sides explicitly agree to unauthenticated and/or
* non-private (unencrypted) communications will such a ciphersuite be
* selected.
*
* <P>When an <code>SSLSocket</code> is first created, no handshaking
* is done so that applications may first set their communication
* preferences: what cipher suites to use, whether the socket should be
* in client or server mode, etc.
* However, security is always provided by the time that application data
* is sent over the connection.
*
* <P> You may register to receive event notification of handshake
* completion. This involves
* the use of two additional classes. <em>HandshakeCompletedEvent</em>
* objects are passed to <em>HandshakeCompletedListener</em> instances,
* which are registered by users of this API.
*
* An <code>SSLSocket</code> is created by <code>SSLSocketFactory</code>,
* or by <code>accept</code>ing a connection from a
* <code>SSLServerSocket</code>.
*
* <P>A SSL socket must choose to operate in the client or server mode.
* This will determine who begins the handshaking process, as well
* as which messages should be sent by each party. Each
* connection must have one client and one server, or handshaking
* will not progress properly. Once the initial handshaking has started, a
* socket can not switch between client and server modes, even when
* performing renegotiations.
*
* @see java.net.Socket
* @see SSLServerSocket
* @see SSLSocketFactory
*
* @since 1.4
* @author David Brownell
*/
public abstract class SSLSocket extends Socket
{
/**
* Used only by subclasses.
* Constructs an uninitialized, unconnected TCP socket.
*/
protected SSLSocket()
{ super(); }
/**
* Used only by subclasses.
* Constructs a TCP connection to a named host at a specified port.
* This acts as the SSL client.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param host name of the host with which to connect, or
* <code>null</code> for the loopback address.
* @param port number of the server's port
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws UnknownHostException if the host is not known
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @see SecurityManager#checkConnect
*/
protected SSLSocket(String host, int port)
throws IOException, UnknownHostException
{ super(host, port); }
/**
* Used only by subclasses.
* Constructs a TCP connection to a server at a specified address
* and port. This acts as the SSL client.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param address the server's host
* @param port its port
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter is outside the
* specified range of valid port values, which is between 0 and
* 65535, inclusive.
* @throws NullPointerException if <code>address</code> is null.
* @see SecurityManager#checkConnect
*/
protected SSLSocket(InetAddress address, int port)
throws IOException
{ super(address, port); }
/**
* Used only by subclasses.
* Constructs an SSL connection to a named host at a specified port,
* binding the client side of the connection a given address and port.
* This acts as the SSL client.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param host name of the host with which to connect, or
* <code>null</code> for the loopback address.
* @param port number of the server's port
* @param clientAddress the client's address the socket is bound to, or
* <code>null</code> for the <code>anyLocal</code> address.
* @param clientPort the client's port the socket is bound to, or
* <code>zero</code> for a system selected free port.
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws UnknownHostException if the host is not known
* @throws IllegalArgumentException if the port parameter or clientPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
* @see SecurityManager#checkConnect
*/
protected SSLSocket(String host, int port,
InetAddress clientAddress, int clientPort)
throws IOException, UnknownHostException
{ super(host, port, clientAddress, clientPort); }
/**
* Used only by subclasses.
* Constructs an SSL connection to a server at a specified address
* and TCP port, binding the client side of the connection a given
* address and port. This acts as the SSL client.
* <p>
* If there is a security manager, its <code>checkConnect</code>
* method is called with the host address and <code>port</code>
* as its arguments. This could result in a SecurityException.
*
* @param address the server's host
* @param port its port
* @param clientAddress the client's address the socket is bound to, or
* <code>null</code> for the <code>anyLocal</code> address.
* @param clientPort the client's port the socket is bound to, or
* <code>zero</code> for a system selected free port.
* @throws IOException if an I/O error occurs when creating the socket
* @throws SecurityException if a security manager exists and its
* <code>checkConnect</code> method doesn't allow the operation.
* @throws IllegalArgumentException if the port parameter or clientPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
* @throws NullPointerException if <code>address</code> is null.
* @see SecurityManager#checkConnect
*/
protected SSLSocket(InetAddress address, int port,
InetAddress clientAddress, int clientPort)
throws IOException
{ super(address, port, clientAddress, clientPort); }
/**
* Returns the names of the cipher suites which could be enabled for use
* on this connection. Normally, only a subset of these will actually
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites might be useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getEnabledCipherSuites()
* @see #setEnabledCipherSuites(String [])
*/
public abstract String [] getSupportedCipherSuites();
/**
* Returns the names of the SSL cipher suites which are currently
* enabled for use on this connection. When an SSLSocket is first
* created, all enabled cipher suites support a minimum quality of
* service. Thus, in some environments this value might be empty.
* <P>
* Note that even if a suite is enabled, it may never be used. This
* can occur if the peer does not support it, or its use is restricted,
* or the requisite certificates (and private keys) for the suite are
* not available, or an anonymous suite is enabled but authentication
* is required.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @return an array of cipher suite names
* @see #getSupportedCipherSuites()
* @see #setEnabledCipherSuites(String [])
*/
public abstract String [] getEnabledCipherSuites();
/**
* Sets the cipher suites enabled for use on this connection.
* <P>
* Each cipher suite in the <code>suites</code> parameter must have
* been listed by getSupportedCipherSuites(), or the method will
* fail. Following a successful call to this method, only suites
* listed in the <code>suites</code> parameter are enabled for use.
* <P>
* Note that the standard list of cipher suite names may be found in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation. Providers
* may support cipher suite names not found in this list or might not
* use the recommended name for a certain cipher suite.
* <P>
* See {@link #getEnabledCipherSuites()} for more information
* on why a specific ciphersuite may never be used on a connection.
*
* @param suites Names of all the cipher suites to enable
* @throws IllegalArgumentException when one or more of the ciphers
* named by the parameter is not supported, or when the
* parameter is null.
* @see #getSupportedCipherSuites()
* @see #getEnabledCipherSuites()
*/
public abstract void setEnabledCipherSuites(String suites []);
/**
* Returns the names of the protocols which could be enabled for use
* on an SSL connection.
*
* @return an array of protocols supported
*/
public abstract String [] getSupportedProtocols();
/**
* Returns the names of the protocol versions which are currently
* enabled for use on this connection.
* <P>
* Note that even if a protocol is enabled, it may never be used.
* This can occur if the peer does not support the protocol, or its
* use is restricted, or there are no enabled cipher suites supported
* by the protocol.
*
* @see #setEnabledProtocols(String [])
* @return an array of protocols
*/
public abstract String [] getEnabledProtocols();
/**
* Sets the protocol versions enabled for use on this connection.
* <P>
* The protocols must have been listed by
* <code>getSupportedProtocols()</code> as being supported.
* Following a successful call to this method, only protocols listed
* in the <code>protocols</code> parameter are enabled for use.
*
* @param protocols Names of all the protocols to enable.
* @throws IllegalArgumentException when one or more of
* the protocols named by the parameter is not supported or
* when the protocols parameter is null.
* @see #getEnabledProtocols()
*/
public abstract void setEnabledProtocols(String protocols[]);
/**
* Returns the SSL Session in use by this connection. These can
* be long lived, and frequently correspond to an entire login session
* for some user. The session specifies a particular cipher suite
* which is being actively used by all connections in that session,
* as well as the identities of the session's client and server.
* <P>
* This method will initiate the initial handshake if
* necessary and then block until the handshake has been
* established.
* <P>
* If an error occurs during the initial handshake, this method
* returns an invalid session object which reports an invalid
* cipher suite of "SSL_NULL_WITH_NULL_NULL".
*
* @return the <code>SSLSession</code>
*/
public abstract SSLSession getSession();
/**
* Returns the {@code SSLSession} being constructed during a SSL/TLS
* handshake.
* <p>
* TLS protocols may negotiate parameters that are needed when using
* an instance of this class, but before the {@code SSLSession} has
* been completely initialized and made available via {@code getSession}.
* For example, the list of valid signature algorithms may restrict
* the type of certificates that can used during TrustManager
* decisions, or the maximum TLS fragment packet sizes can be
* resized to better support the network environment.
* <p>
* This method provides early access to the {@code SSLSession} being
* constructed. Depending on how far the handshake has progressed,
* some data may not yet be available for use. For example, if a
* remote server will be sending a Certificate chain, but that chain
* has yet not been processed, the {@code getPeerCertificates}
* method of {@code SSLSession} will throw a
* SSLPeerUnverifiedException. Once that chain has been processed,
* {@code getPeerCertificates} will return the proper value.
* <p>
* Unlike {@link #getSession()}, this method does not initiate the
* initial handshake and does not block until handshaking is
* complete.
*
* @see SSLEngine
* @see SSLSession
* @see ExtendedSSLSession
* @see X509ExtendedKeyManager
* @see X509ExtendedTrustManager
*
* @return null if this instance is not currently handshaking, or
* if the current handshake has not progressed far enough to
* create a basic SSLSession. Otherwise, this method returns the
* {@code SSLSession} currently being negotiated.
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
*
* @since 1.7
*/
public SSLSession getHandshakeSession() {
throw new UnsupportedOperationException();
}
/**
* Registers an event listener to receive notifications that an
* SSL handshake has completed on this connection.
*
* @param listener the HandShake Completed event listener
* @see #startHandshake()
* @see #removeHandshakeCompletedListener(HandshakeCompletedListener)
* @throws IllegalArgumentException if the argument is null.
*/
public abstract void addHandshakeCompletedListener(
HandshakeCompletedListener listener);
/**
* Removes a previously registered handshake completion listener.
*
* @param listener the HandShake Completed event listener
* @throws IllegalArgumentException if the listener is not registered,
* or the argument is null.
* @see #addHandshakeCompletedListener(HandshakeCompletedListener)
*/
public abstract void removeHandshakeCompletedListener(
HandshakeCompletedListener listener);
/**
* Starts an SSL handshake on this connection. Common reasons include
* a need to use new encryption keys, to change cipher suites, or to
* initiate a new session. To force complete reauthentication, the
* current session could be invalidated before starting this handshake.
*
* <P> If data has already been sent on the connection, it continues
* to flow during this handshake. When the handshake completes, this
* will be signaled with an event.
*
* This method is synchronous for the initial handshake on a connection
* and returns when the negotiated handshake is complete. Some
* protocols may not support multiple handshakes on an existing socket
* and may throw an IOException.
*
* @throws IOException on a network level error
* @see #addHandshakeCompletedListener(HandshakeCompletedListener)
*/
public abstract void startHandshake() throws IOException;
/**
* Configures the socket to use client (or server) mode when
* handshaking.
* <P>
* This method must be called before any handshaking occurs.
* Once handshaking has begun, the mode can not be reset for the
* life of this socket.
* <P>
* Servers normally authenticate themselves, and clients
* are not required to do so.
*
* @param mode true if the socket should start its handshaking
* in "client" mode
* @throws IllegalArgumentException if a mode change is attempted
* after the initial handshake has begun.
* @see #getUseClientMode()
*/
public abstract void setUseClientMode(boolean mode);
/**
* Returns true if the socket is set to use client mode when
* handshaking.
*
* @return true if the socket should do handshaking
* in "client" mode
* @see #setUseClientMode(boolean)
*/
public abstract boolean getUseClientMode();
/**
* Configures the socket to <i>require</i> client authentication. This
* option is only useful for sockets in the server mode.
* <P>
* A socket's client authentication setting is one of the following:
* <ul>
* <li> client authentication required
* <li> client authentication requested
* <li> no client authentication desired
* </ul>
* <P>
* Unlike {@link #setWantClientAuth(boolean)}, if this option is set and
* the client chooses not to provide authentication information
* about itself, <i>the negotiations will stop and the connection
* will be dropped</i>.
* <P>
* Calling this method overrides any previous setting made by
* this method or {@link #setWantClientAuth(boolean)}.
*
* @param need set to true if client authentication is required,
* or false if no client authentication is desired.
* @see #getNeedClientAuth()
* @see #setWantClientAuth(boolean)
* @see #getWantClientAuth()
* @see #setUseClientMode(boolean)
*/
public abstract void setNeedClientAuth(boolean need);
/**
* Returns true if the socket will <i>require</i> client authentication.
* This option is only useful to sockets in the server mode.
*
* @return true if client authentication is required,
* or false if no client authentication is desired.
* @see #setNeedClientAuth(boolean)
* @see #setWantClientAuth(boolean)
* @see #getWantClientAuth()
* @see #setUseClientMode(boolean)
*/
public abstract boolean getNeedClientAuth();
/**
* Configures the socket to <i>request</i> client authentication.
* This option is only useful for sockets in the server mode.
* <P>
* A socket's client authentication setting is one of the following:
* <ul>
* <li> client authentication required
* <li> client authentication requested
* <li> no client authentication desired
* </ul>
* <P>
* Unlike {@link #setNeedClientAuth(boolean)}, if this option is set and
* the client chooses not to provide authentication information
* about itself, <i>the negotiations will continue</i>.
* <P>
* Calling this method overrides any previous setting made by
* this method or {@link #setNeedClientAuth(boolean)}.
*
* @param want set to true if client authentication is requested,
* or false if no client authentication is desired.
* @see #getWantClientAuth()
* @see #setNeedClientAuth(boolean)
* @see #getNeedClientAuth()
* @see #setUseClientMode(boolean)
*/
public abstract void setWantClientAuth(boolean want);
/**
* Returns true if the socket will <i>request</i> client authentication.
* This option is only useful for sockets in the server mode.
*
* @return true if client authentication is requested,
* or false if no client authentication is desired.
* @see #setNeedClientAuth(boolean)
* @see #getNeedClientAuth()
* @see #setWantClientAuth(boolean)
* @see #setUseClientMode(boolean)
*/
public abstract boolean getWantClientAuth();
/**
* Controls whether new SSL sessions may be established by this socket.
* If session creations are not allowed, and there are no
* existing sessions to resume, there will be no successful
* handshaking.
*
* @param flag true indicates that sessions may be created; this
* is the default. false indicates that an existing session
* must be resumed
* @see #getEnableSessionCreation()
*/
public abstract void setEnableSessionCreation(boolean flag);
/**
* Returns true if new SSL sessions may be established by this socket.
*
* @return true indicates that sessions may be created; this
* is the default. false indicates that an existing session
* must be resumed
* @see #setEnableSessionCreation(boolean)
*/
public abstract boolean getEnableSessionCreation();
/**
* Returns the SSLParameters in effect for this SSLSocket.
* The ciphersuites and protocols of the returned SSLParameters
* are always non-null.
*
* @return the SSLParameters in effect for this SSLSocket.
* @since 1.6
*/
public SSLParameters getSSLParameters() {
SSLParameters params = new SSLParameters();
params.setCipherSuites(getEnabledCipherSuites());
params.setProtocols(getEnabledProtocols());
if (getNeedClientAuth()) {
params.setNeedClientAuth(true);
} else if (getWantClientAuth()) {
params.setWantClientAuth(true);
}
return params;
}
/**
* Applies SSLParameters to this socket.
*
* <p>This means:
* <ul>
* <li>If {@code params.getCipherSuites()} is non-null,
* {@code setEnabledCipherSuites()} is called with that value.</li>
* <li>If {@code params.getProtocols()} is non-null,
* {@code setEnabledProtocols()} is called with that value.</li>
* <li>If {@code params.getNeedClientAuth()} or
* {@code params.getWantClientAuth()} return {@code true},
* {@code setNeedClientAuth(true)} and
* {@code setWantClientAuth(true)} are called, respectively;
* otherwise {@code setWantClientAuth(false)} is called.</li>
* <li>If {@code params.getServerNames()} is non-null, the socket will
* configure its server names with that value.</li>
* <li>If {@code params.getSNIMatchers()} is non-null, the socket will
* configure its SNI matchers with that value.</li>
* </ul>
*
* @param params the parameters
* @throws IllegalArgumentException if the setEnabledCipherSuites() or
* the setEnabledProtocols() call fails
* @since 1.6
*/
public void setSSLParameters(SSLParameters params) {
String[] s;
s = params.getCipherSuites();
if (s != null) {
setEnabledCipherSuites(s);
}
s = params.getProtocols();
if (s != null) {
setEnabledProtocols(s);
}
if (params.getNeedClientAuth()) {
setNeedClientAuth(true);
} else if (params.getWantClientAuth()) {
setWantClientAuth(true);
} else {
setWantClientAuth(false);
}
}
/**
* Returns the most recent application protocol value negotiated for this
* connection.
* <p>
* If supported by the underlying SSL/TLS/DTLS implementation,
* application name negotiation mechanisms such as <a
* href="http://www.ietf.org/rfc/rfc7301.txt"> RFC 7301 </a>, the
* Application-Layer Protocol Negotiation (ALPN), can negotiate
* application-level values between peers.
*
* @implSpec
* The implementation in this class throws
* {@code UnsupportedOperationException} and performs no other action.
*
* @return null if it has not yet been determined if application
* protocols might be used for this connection, an empty
* {@code String} if application protocols values will not
* be used, or a non-empty application protocol {@code String}
* if a value was successfully negotiated.
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @since 9
*/
public String getApplicationProtocol() {
throw new UnsupportedOperationException();
}
/**
* Returns the application protocol value negotiated on a SSL/TLS
* handshake currently in progress.
* <p>
* Like {@link #getHandshakeSession()},
* a connection may be in the middle of a handshake. The
* application protocol may or may not yet be available.
*
* @implSpec
* The implementation in this class throws
* {@code UnsupportedOperationException} and performs no other action.
*
* @return null if it has not yet been determined if application
* protocols might be used for this handshake, an empty
* {@code String} if application protocols values will not
* be used, or a non-empty application protocol {@code String}
* if a value was successfully negotiated.
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @since 9
*/
public String getHandshakeApplicationProtocol() {
throw new UnsupportedOperationException();
}
/**
* Registers a callback function that selects an application protocol
* value for a SSL/TLS/DTLS handshake.
* The function overrides any values supplied using
* {@link SSLParameters#setApplicationProtocols
* SSLParameters.setApplicationProtocols} and it supports the following
* type parameters:
* <blockquote>
* <dl>
* <dt> {@code SSLSocket}
* <dd> The function's first argument allows the current {@code SSLSocket}
* to be inspected, including the handshake session and configuration
* settings.
* <dt> {@code List<String>}
* <dd> The function's second argument lists the application protocol names
* advertised by the TLS peer.
* <dt> {@code String}
* <dd> The function's result is an application protocol name, or null to
* indicate that none of the advertised names are acceptable.
* If the return value is an empty {@code String} then application
* protocol indications will not be used.
* If the return value is null (no value chosen) or is a value that
* was not advertised by the peer, the underlying protocol will
* determine what action to take. (For example, ALPN will send a
* "no_application_protocol" alert and terminate the connection.)
* </dl>
* </blockquote>
*
* For example, the following call registers a callback function that
* examines the TLS handshake parameters and selects an application protocol
* name:
* <pre>{@code
* serverSocket.setHandshakeApplicationProtocolSelector(
* (serverSocket, clientProtocols) -> {
* SSLSession session = serverSocket.getHandshakeSession();
* return chooseApplicationProtocol(
* serverSocket,
* clientProtocols,
* session.getProtocol(),
* session.getCipherSuite());
* });
* }</pre>
*
* @apiNote
* This method should be called by TLS server applications before the TLS
* handshake begins. Also, this {@code SSLSocket} should be configured with
* parameters that are compatible with the application protocol selected by
* the callback function. For example, enabling a poor choice of cipher
* suites could result in no suitable application protocol.
* See {@link SSLParameters}.
*
* @implSpec
* The implementation in this class throws
* {@code UnsupportedOperationException} and performs no other action.
*
* @param selector the callback function, or null to de-register.
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @since 9
*/
public void setHandshakeApplicationProtocolSelector(
BiFunction<SSLSocket, List<String>, String> selector) {
throw new UnsupportedOperationException();
}
/**
* Retrieves the callback function that selects an application protocol
* value during a SSL/TLS/DTLS handshake.
* See {@link #setHandshakeApplicationProtocolSelector
* setHandshakeApplicationProtocolSelector}
* for the function's type parameters.
*
* @implSpec
* The implementation in this class throws
* {@code UnsupportedOperationException} and performs no other action.
*
* @return the callback function, or null if none has been set.
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation.
* @since 9
*/
public BiFunction<SSLSocket, List<String>, String>
getHandshakeApplicationProtocolSelector() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,320 @@
/*
* Copyright (c) 1997, 2017, 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 javax.net.ssl;
import java.net.*;
import javax.net.SocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.util.Locale;
import sun.security.action.GetPropertyAction;
/**
* <code>SSLSocketFactory</code>s create <code>SSLSocket</code>s.
*
* @since 1.4
* @see SSLSocket
* @author David Brownell
*/
public abstract class SSLSocketFactory extends SocketFactory
{
private static SSLSocketFactory theFactory;
private static boolean propertyChecked;
static final boolean DEBUG;
static {
String s = GetPropertyAction.privilegedGetProperty("javax.net.debug", "")
.toLowerCase(Locale.ENGLISH);
DEBUG = s.contains("all") || s.contains("ssl");
}
private static void log(String msg) {
if (DEBUG) {
System.out.println(msg);
}
}
/**
* Constructor is used only by subclasses.
*/
public SSLSocketFactory() {
}
/**
* Returns the default SSL socket factory.
*
* <p>The first time this method is called, the security property
* "ssl.SocketFactory.provider" is examined. If it is non-null, a class by
* that name is loaded and instantiated. If that is successful and the
* object is an instance of SSLSocketFactory, it is made the default SSL
* socket factory.
*
* <p>Otherwise, this method returns
* <code>SSLContext.getDefault().getSocketFactory()</code>. If that
* call fails, an inoperative factory is returned.
*
* @return the default <code>SocketFactory</code>
* @see SSLContext#getDefault
*/
public static synchronized SocketFactory getDefault() {
if (theFactory != null) {
return theFactory;
}
if (propertyChecked == false) {
propertyChecked = true;
String clsName = getSecurityProperty("ssl.SocketFactory.provider");
if (clsName != null) {
log("setting up default SSLSocketFactory");
try {
Class<?> cls = null;
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
log("class " + clsName + " is loaded");
@SuppressWarnings("deprecation")
SSLSocketFactory fac = (SSLSocketFactory)cls.newInstance();
log("instantiated an instance of class " + clsName);
theFactory = fac;
return fac;
} catch (Exception e) {
log("SSLSocketFactory instantiation failed: " + e.toString());
theFactory = new DefaultSSLSocketFactory(e);
return theFactory;
}
}
}
try {
return SSLContext.getDefault().getSocketFactory();
} catch (NoSuchAlgorithmException e) {
return new DefaultSSLSocketFactory(e);
}
}
static String getSecurityProperty(final String name) {
return AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public String run() {
String s = java.security.Security.getProperty(name);
if (s != null) {
s = s.trim();
if (s.length() == 0) {
s = null;
}
}
return s;
}
});
}
/**
* Returns the list of cipher suites which are enabled by default.
* Unless a different list is enabled, handshaking on an SSL connection
* will use one of these cipher suites. The minimum quality of service
* for these defaults requires confidentiality protection and server
* authentication (that is, no anonymous cipher suites).
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @see #getSupportedCipherSuites()
* @return array of the cipher suites enabled by default
*/
public abstract String [] getDefaultCipherSuites();
/**
* Returns the names of the cipher suites which could be enabled for use
* on an SSL connection. Normally, only a subset of these will actually
* be enabled by default, since this list may include cipher suites which
* do not meet quality of service requirements for those defaults. Such
* cipher suites are useful in specialized applications.
* <P>
* The returned array includes cipher suites from the list of standard
* cipher suite names in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#jsse-cipher-suite-names">
* JSSE Cipher Suite Names</a> section of the Java Cryptography
* Architecture Standard Algorithm Name Documentation, and may also
* include other cipher suites that the provider supports.
*
* @see #getDefaultCipherSuites()
* @return an array of cipher suite names
*/
public abstract String [] getSupportedCipherSuites();
/**
* Returns a socket layered over an existing socket connected to the named
* host, at the given port. This constructor can be used when tunneling SSL
* through a proxy or when negotiating the use of SSL over an existing
* socket. The host and port refer to the logical peer destination.
* This socket is configured using the socket options established for
* this factory.
*
* @param s the existing socket
* @param host the server host
* @param port the server port
* @param autoClose close the underlying socket when this socket is closed
* @return a socket connected to the specified host and port
* @throws IOException if an I/O error occurs when creating the socket
* @throws NullPointerException if the parameter s is null
*/
public abstract Socket createSocket(Socket s, String host,
int port, boolean autoClose) throws IOException;
/**
* Creates a server mode {@link Socket} layered over an
* existing connected socket, and is able to read data which has
* already been consumed/removed from the {@link Socket}'s
* underlying {@link InputStream}.
* <p>
* This method can be used by a server application that needs to
* observe the inbound data but still create valid SSL/TLS
* connections: for example, inspection of Server Name Indication
* (SNI) extensions (See section 3 of <A
* HREF="http://www.ietf.org/rfc/rfc6066.txt">TLS Extensions
* (RFC6066)</A>). Data that has been already removed from the
* underlying {@link InputStream} should be loaded into the
* {@code consumed} stream before this method is called, perhaps
* using a {@link java.io.ByteArrayInputStream}. When this
* {@link Socket} begins handshaking, it will read all of the data in
* {@code consumed} until it reaches {@code EOF}, then all further
* data is read from the underlying {@link InputStream} as
* usual.
* <p>
* The returned socket is configured using the socket options
* established for this factory, and is set to use server mode when
* handshaking (see {@link SSLSocket#setUseClientMode(boolean)}).
*
* @param s
* the existing socket
* @param consumed
* the consumed inbound network data that has already been
* removed from the existing {@link Socket}
* {@link InputStream}. This parameter may be
* {@code null} if no data has been removed.
* @param autoClose close the underlying socket when this socket is closed.
*
* @return the {@link Socket} compliant with the socket options
* established for this factory
*
* @throws IOException if an I/O error occurs when creating the socket
* @throws UnsupportedOperationException if the underlying provider
* does not implement the operation
* @throws NullPointerException if {@code s} is {@code null}
*
* @since 1.8
*/
public Socket createSocket(Socket s, InputStream consumed,
boolean autoClose) throws IOException {
throw new UnsupportedOperationException();
}
}
// file private
class DefaultSSLSocketFactory extends SSLSocketFactory
{
private Exception reason;
DefaultSSLSocketFactory(Exception reason) {
this.reason = reason;
}
private Socket throwException() throws SocketException {
throw (SocketException)
new SocketException(reason.toString()).initCause(reason);
}
@Override
public Socket createSocket()
throws IOException
{
return throwException();
}
@Override
public Socket createSocket(String host, int port)
throws IOException
{
return throwException();
}
@Override
public Socket createSocket(Socket s, String host,
int port, boolean autoClose)
throws IOException
{
return throwException();
}
@Override
public Socket createSocket(InetAddress address, int port)
throws IOException
{
return throwException();
}
@Override
public Socket createSocket(String host, int port,
InetAddress clientAddress, int clientPort)
throws IOException
{
return throwException();
}
@Override
public Socket createSocket(InetAddress address, int port,
InetAddress clientAddress, int clientPort)
throws IOException
{
return throwException();
}
@Override
public String [] getDefaultCipherSuites() {
return new String[0];
}
@Override
public String [] getSupportedCipherSuites() {
return new String[0];
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2012, 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 javax.net.ssl;
/**
* Standard constants definitions
*
* @since 1.8
*/
public final class StandardConstants {
// Suppress default constructor for noninstantiability
private StandardConstants() {
throw new AssertionError(
"No javax.net.ssl.StandardConstants instances for you!");
}
/**
* The "host_name" type representing of a DNS hostname
* (see {@link SNIHostName}) in a Server Name Indication (SNI) extension.
* <P>
* The SNI extension is a feature that extends the SSL/TLS protocols to
* indicate what server name the client is attempting to connect to during
* handshaking. See section 3, "Server Name Indication", of <A
* HREF="http://www.ietf.org/rfc/rfc6066.txt">TLS Extensions (RFC 6066)</A>.
* <P>
* The value of this constant is {@value}.
*
* @see SNIServerName
* @see SNIHostName
*/
public static final int SNI_HOST_NAME = 0x00;
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 1999, 2003, 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 javax.net.ssl;
/**
* This is the base interface for JSSE trust managers.
* <P>
* <code>TrustManager</code>s are responsible for managing the trust material
* that is used when making trust decisions, and for deciding whether
* credentials presented by a peer should be accepted.
* <P>
* <code>TrustManager</code>s are created by either
* using a <code>TrustManagerFactory</code>,
* or by implementing one of the <code>TrustManager</code> subclasses.
*
* @see TrustManagerFactory
* @since 1.4
*/
public interface TrustManager {
}

View file

@ -0,0 +1,315 @@
/*
* Copyright (c) 1999, 2017, 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 javax.net.ssl;
import java.security.Security;
import java.security.*;
import java.util.Objects;
import sun.security.jca.GetInstance;
/**
* This class acts as a factory for trust managers based on a
* source of trust material. Each trust manager manages a specific
* type of trust material for use by secure sockets. The trust
* material is based on a KeyStore and/or provider-specific sources.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code TrustManagerFactory} algorithm:
* <ul>
* <li>{@code PKIX}</li>
* </ul>
* This algorithm is described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#trustmanagerfactory-algorithms">
* TrustManagerFactory section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @since 1.4
* @see TrustManager
*/
public class TrustManagerFactory {
// The provider
private Provider provider;
// The provider implementation (delegate)
private TrustManagerFactorySpi factorySpi;
// The name of the trust management algorithm.
private String algorithm;
/**
* Obtains the default TrustManagerFactory algorithm name.
*
* <p>The default TrustManager can be changed at runtime by setting
* the value of the {@code ssl.TrustManagerFactory.algorithm}
* security property to the desired algorithm name.
*
* @see java.security.Security security properties
* @return the default algorithm name as specified by the
* {@code ssl.TrustManagerFactory.algorithm} security property, or an
* implementation-specific default if no such property exists.
*/
public static final String getDefaultAlgorithm() {
String type;
type = AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public String run() {
return Security.getProperty(
"ssl.TrustManagerFactory.algorithm");
}
});
if (type == null) {
type = "SunX509";
}
return type;
}
/**
* Creates a TrustManagerFactory object.
*
* @param factorySpi the delegate
* @param provider the provider
* @param algorithm the algorithm
*/
protected TrustManagerFactory(TrustManagerFactorySpi factorySpi,
Provider provider, String algorithm) {
this.factorySpi = factorySpi;
this.provider = provider;
this.algorithm = algorithm;
}
/**
* Returns the algorithm name of this <code>TrustManagerFactory</code>
* object.
*
* <p>This is the same name that was specified in one of the
* <code>getInstance</code> calls that created this
* <code>TrustManagerFactory</code> object.
*
* @return the algorithm name of this <code>TrustManagerFactory</code>
* object
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns a <code>TrustManagerFactory</code> object that acts as a
* factory for trust managers.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new TrustManagerFactory object encapsulating the
* TrustManagerFactorySpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard name of the requested trust management
* algorithm. See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @return the new {@code TrustManagerFactory} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code TrustManagerFactorySpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final TrustManagerFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("TrustManagerFactory", TrustManagerFactorySpi.class,
algorithm);
return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a <code>TrustManagerFactory</code> object that acts as a
* factory for trust managers.
*
* <p> A new KeyManagerFactory object encapsulating the
* KeyManagerFactorySpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard name of the requested trust management
* algorithm. See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new {@code TrustManagerFactory} object
*
* @throws IllegalArgumentException if the provider name is
* {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code TrustManagerFactorySpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final TrustManagerFactory getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("TrustManagerFactory", TrustManagerFactorySpi.class,
algorithm, provider);
return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a <code>TrustManagerFactory</code> object that acts as a
* factory for trust managers.
*
* <p> A new TrustManagerFactory object encapsulating the
* TrustManagerFactorySpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard name of the requested trust management
* algorithm. See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard algorithm names.
*
* @param provider an instance of the provider.
*
* @return the new {@code TrustManagerFactory} object
*
* @throws IllegalArgumentException if the provider is {@code null}
*
* @throws NoSuchAlgorithmException if a {@code TrustManagerFactorySpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static final TrustManagerFactory getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
GetInstance.Instance instance = GetInstance.getInstance
("TrustManagerFactory", TrustManagerFactorySpi.class,
algorithm, provider);
return new TrustManagerFactory((TrustManagerFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the provider of this <code>TrustManagerFactory</code> object.
*
* @return the provider of this <code>TrustManagerFactory</code> object
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Initializes this factory with a source of certificate
* authorities and related trust material.
* <P>
* The provider typically uses a KeyStore as a basis for making
* trust decisions.
* <P>
* For more flexible initialization, please see
* {@link #init(ManagerFactoryParameters)}.
*
* @param ks the key store, or null
* @throws KeyStoreException if this operation fails
*/
public final void init(KeyStore ks) throws KeyStoreException {
factorySpi.engineInit(ks);
}
/**
* Initializes this factory with a source of provider-specific
* trust material.
* <P>
* In some cases, initialization parameters other than a keystore
* may be needed by a provider. Users of that particular provider
* are expected to pass an implementation of the appropriate
* <CODE>ManagerFactoryParameters</CODE> as defined by the
* provider. The provider can then call the specified methods in
* the <CODE>ManagerFactoryParameters</CODE> implementation to obtain the
* needed information.
*
* @param spec an implementation of a provider-specific parameter
* specification
* @throws InvalidAlgorithmParameterException if an error is
* encountered
*/
public final void init(ManagerFactoryParameters spec) throws
InvalidAlgorithmParameterException {
factorySpi.engineInit(spec);
}
/**
* Returns one trust manager for each type of trust material.
*
* @throws IllegalStateException if the factory is not initialized.
*
* @return the trust managers
*/
public final TrustManager[] getTrustManagers() {
return factorySpi.engineGetTrustManagers();
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 1999, 2008, 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 javax.net.ssl;
import java.security.*;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the <code>TrustManagerFactory</code> class.
*
* <p> All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a particular trust manager factory.
*
* @since 1.4
* @see TrustManagerFactory
* @see TrustManager
*/
public abstract class TrustManagerFactorySpi {
/**
* Initializes this factory with a source of certificate
* authorities and related trust material.
*
* @param ks the key store or null
* @throws KeyStoreException if this operation fails
* @see TrustManagerFactory#init(KeyStore)
*/
protected abstract void engineInit(KeyStore ks) throws KeyStoreException;
/**
* Initializes this factory with a source of provider-specific
* key material.
* <P>
* In some cases, initialization parameters other than a keystore
* may be needed by a provider. Users of that
* particular provider are expected to pass an implementation of
* the appropriate <CODE>ManagerFactoryParameters</CODE> as
* defined by the provider. The provider can then call the
* specified methods in the <CODE>ManagerFactoryParameters</CODE>
* implementation to obtain the needed information.
*
* @param spec an implementation of a provider-specific parameter
* specification
* @throws InvalidAlgorithmParameterException if there is problem
* with the parameters
* @see TrustManagerFactory#init(ManagerFactoryParameters spec)
*/
protected abstract void engineInit(ManagerFactoryParameters spec)
throws InvalidAlgorithmParameterException;
/**
* Returns one trust manager for each type of trust material.
*
* @throws IllegalStateException if the factory is not initialized.
*
* @return the trust managers
*/
protected abstract TrustManager[] engineGetTrustManagers();
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2004, 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 javax.net.ssl;
import java.security.Principal;
/**
* Abstract class that provides for extension of the X509KeyManager
* interface.
* <P>
* Methods in this class should be overriden to provide actual
* implementations.
*
* @since 1.5
* @author Brad R. Wetmore
*/
public abstract class X509ExtendedKeyManager implements X509KeyManager {
/**
* Constructor used by subclasses only.
*/
protected X509ExtendedKeyManager() {
}
/**
* Choose an alias to authenticate the client side of an
* <code>SSLEngine</code> connection given the public key type
* and the list of certificate issuer authorities recognized by
* the peer (if any).
* <P>
* The default implementation returns null.
*
* @param keyType the key algorithm type name(s), ordered
* with the most-preferred key type first.
* @param issuers the list of acceptable CA issuer subject names
* or null if it does not matter which issuers are used.
* @param engine the <code>SSLEngine</code> to be used for this
* connection. This parameter can be null, which indicates
* that implementations of this interface are free to
* select an alias applicable to any engine.
* @return the alias name for the desired key, or null if there
* are no matches.
*/
public String chooseEngineClientAlias(String[] keyType,
Principal[] issuers, SSLEngine engine) {
return null;
}
/**
* Choose an alias to authenticate the server side of an
* <code>SSLEngine</code> connection given the public key type
* and the list of certificate issuer authorities recognized by
* the peer (if any).
* <P>
* The default implementation returns null.
*
* @param keyType the key algorithm type name.
* @param issuers the list of acceptable CA issuer subject names
* or null if it does not matter which issuers are used.
* @param engine the <code>SSLEngine</code> to be used for this
* connection. This parameter can be null, which indicates
* that implementations of this interface are free to
* select an alias applicable to any engine.
* @return the alias name for the desired key, or null if there
* are no matches.
*/
public String chooseEngineServerAlias(String keyType,
Principal[] issuers, SSLEngine engine) {
return null;
}
}

View file

@ -0,0 +1,235 @@
/*
* Copyright (c) 2010, 2015, 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 javax.net.ssl;
import java.net.Socket;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
/**
* Extensions to the {@code X509TrustManager} interface to support
* SSL/TLS/DTLS connection sensitive trust management.
* <p>
* To prevent man-in-the-middle attacks, hostname checks can be done
* to verify that the hostname in an end-entity certificate matches the
* targeted hostname. TLS/DTLS does not require such checks, but some
* protocols over TLS/DTLS (such as HTTPS) do. In earlier versions of the
* JDK, the certificate chain checks were done at the SSL/TLS/DTLS layer,
* and the hostname verification checks were done at the layer over TLS/DTLS.
* This class allows for the checking to be done during a single call to
* this class.
* <p>
* RFC 2830 defines the server identification specification for the "LDAPS"
* algorithm. RFC 2818 defines both the server identification and the
* client identification specification for the "HTTPS" algorithm.
*
* @see X509TrustManager
* @see HostnameVerifier
*
* @since 1.7
*/
public abstract class X509ExtendedTrustManager implements X509TrustManager {
/**
* Given the partial or complete certificate chain provided by the
* peer, build and validate the certificate path based on the
* authentication type and ssl parameters.
* <p>
* The authentication type is determined by the actual certificate
* used. For instance, if RSAPublicKey is used, the authType
* should be "RSA". Checking is case-sensitive.
* <p>
* If the {@code socket} parameter is an instance of
* {@link javax.net.ssl.SSLSocket}, and the endpoint identification
* algorithm of the {@code SSLParameters} is non-empty, to prevent
* man-in-the-middle attacks, the address that the {@code socket}
* connected to should be checked against the peer's identity presented
* in the end-entity X509 certificate, as specified in the endpoint
* identification algorithm.
* <p>
* If the {@code socket} parameter is an instance of
* {@link javax.net.ssl.SSLSocket}, and the algorithm constraints of the
* {@code SSLParameters} is non-null, for every certificate in the
* certification path, fields such as subject public key, the signature
* algorithm, key usage, extended key usage, etc. need to conform to the
* algorithm constraints in place on this socket.
*
* @param chain the peer certificate chain
* @param authType the key exchange algorithm used
* @param socket the socket used for this connection. This parameter
* can be null, which indicates that implementations need not check
* the ssl parameters
* @throws IllegalArgumentException if null or zero-length array is passed
* in for the {@code chain} parameter or if null or zero-length
* string is passed in for the {@code authType} parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager
*
* @see SSLParameters#getEndpointIdentificationAlgorithm
* @see SSLParameters#setEndpointIdentificationAlgorithm(String)
* @see SSLParameters#getAlgorithmConstraints
* @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
*/
public abstract void checkClientTrusted(X509Certificate[] chain,
String authType, Socket socket) throws CertificateException;
/**
* Given the partial or complete certificate chain provided by the
* peer, build and validate the certificate path based on the
* authentication type and ssl parameters.
* <p>
* The authentication type is the key exchange algorithm portion
* of the cipher suites represented as a String, such as "RSA",
* "DHE_DSS". Note: for some exportable cipher suites, the key
* exchange algorithm is determined at run time during the
* handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
* the authType should be RSA_EXPORT when an ephemeral RSA key is
* used for the key exchange, and RSA when the key from the server
* certificate is used. Checking is case-sensitive.
* <p>
* If the {@code socket} parameter is an instance of
* {@link javax.net.ssl.SSLSocket}, and the endpoint identification
* algorithm of the {@code SSLParameters} is non-empty, to prevent
* man-in-the-middle attacks, the address that the {@code socket}
* connected to should be checked against the peer's identity presented
* in the end-entity X509 certificate, as specified in the endpoint
* identification algorithm.
* <p>
* If the {@code socket} parameter is an instance of
* {@link javax.net.ssl.SSLSocket}, and the algorithm constraints of the
* {@code SSLParameters} is non-null, for every certificate in the
* certification path, fields such as subject public key, the signature
* algorithm, key usage, extended key usage, etc. need to conform to the
* algorithm constraints in place on this socket.
*
* @param chain the peer certificate chain
* @param authType the key exchange algorithm used
* @param socket the socket used for this connection. This parameter
* can be null, which indicates that implementations need not check
* the ssl parameters
* @throws IllegalArgumentException if null or zero-length array is passed
* in for the {@code chain} parameter or if null or zero-length
* string is passed in for the {@code authType} parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager
*
* @see SSLParameters#getEndpointIdentificationAlgorithm
* @see SSLParameters#setEndpointIdentificationAlgorithm(String)
* @see SSLParameters#getAlgorithmConstraints
* @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
*/
public abstract void checkServerTrusted(X509Certificate[] chain,
String authType, Socket socket) throws CertificateException;
/**
* Given the partial or complete certificate chain provided by the
* peer, build and validate the certificate path based on the
* authentication type and ssl parameters.
* <p>
* The authentication type is determined by the actual certificate
* used. For instance, if RSAPublicKey is used, the authType
* should be "RSA". Checking is case-sensitive.
* <p>
* If the {@code engine} parameter is available, and the endpoint
* identification algorithm of the {@code SSLParameters} is
* non-empty, to prevent man-in-the-middle attacks, the address that
* the {@code engine} connected to should be checked against
* the peer's identity presented in the end-entity X509 certificate,
* as specified in the endpoint identification algorithm.
* <p>
* If the {@code engine} parameter is available, and the algorithm
* constraints of the {@code SSLParameters} is non-null, for every
* certificate in the certification path, fields such as subject public
* key, the signature algorithm, key usage, extended key usage, etc.
* need to conform to the algorithm constraints in place on this engine.
*
* @param chain the peer certificate chain
* @param authType the key exchange algorithm used
* @param engine the engine used for this connection. This parameter
* can be null, which indicates that implementations need not check
* the ssl parameters
* @throws IllegalArgumentException if null or zero-length array is passed
* in for the {@code chain} parameter or if null or zero-length
* string is passed in for the {@code authType} parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager
*
* @see SSLParameters#getEndpointIdentificationAlgorithm
* @see SSLParameters#setEndpointIdentificationAlgorithm(String)
* @see SSLParameters#getAlgorithmConstraints
* @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
*/
public abstract void checkClientTrusted(X509Certificate[] chain,
String authType, SSLEngine engine) throws CertificateException;
/**
* Given the partial or complete certificate chain provided by the
* peer, build and validate the certificate path based on the
* authentication type and ssl parameters.
* <p>
* The authentication type is the key exchange algorithm portion
* of the cipher suites represented as a String, such as "RSA",
* "DHE_DSS". Note: for some exportable cipher suites, the key
* exchange algorithm is determined at run time during the
* handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
* the authType should be RSA_EXPORT when an ephemeral RSA key is
* used for the key exchange, and RSA when the key from the server
* certificate is used. Checking is case-sensitive.
* <p>
* If the {@code engine} parameter is available, and the endpoint
* identification algorithm of the {@code SSLParameters} is
* non-empty, to prevent man-in-the-middle attacks, the address that
* the {@code engine} connected to should be checked against
* the peer's identity presented in the end-entity X509 certificate,
* as specified in the endpoint identification algorithm.
* <p>
* If the {@code engine} parameter is available, and the algorithm
* constraints of the {@code SSLParameters} is non-null, for every
* certificate in the certification path, fields such as subject public
* key, the signature algorithm, key usage, extended key usage, etc.
* need to conform to the algorithm constraints in place on this engine.
*
* @param chain the peer certificate chain
* @param authType the key exchange algorithm used
* @param engine the engine used for this connection. This parameter
* can be null, which indicates that implementations need not check
* the ssl parameters
* @throws IllegalArgumentException if null or zero-length array is passed
* in for the {@code chain} parameter or if null or zero-length
* string is passed in for the {@code authType} parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager
*
* @see SSLParameters#getEndpointIdentificationAlgorithm
* @see SSLParameters#setEndpointIdentificationAlgorithm(String)
* @see SSLParameters#getAlgorithmConstraints
* @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
*/
public abstract void checkServerTrusted(X509Certificate[] chain,
String authType, SSLEngine engine) throws CertificateException;
}

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 1999, 2016, 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 javax.net.ssl;
import java.security.PrivateKey;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.net.Socket;
/**
* Instances of this interface manage which X509 certificate-based
* key pairs are used to authenticate the local side of a secure
* socket.
* <P>
* During secure socket negotiations, implementations
* call methods in this interface to:
* <UL>
* <LI> determine the set of aliases that are available for negotiations
* based on the criteria presented,
* <LI> select the <i> best alias</i> based on
* the criteria presented, and
* <LI> obtain the corresponding key material for given aliases.
* </UL>
* <P>
* Note: the X509ExtendedKeyManager should be used in favor of this
* class.
*
* @since 1.4
*/
public interface X509KeyManager extends KeyManager {
/**
* Get the matching aliases for authenticating the client side of a secure
* socket given the public key type and the list of
* certificate issuer authorities recognized by the peer (if any).
*
* @param keyType the key algorithm type name
* @param issuers the list of acceptable CA issuer subject names,
* or null if it does not matter which issuers are used.
* @return an array of the matching alias names, or null if there
* were no matches.
*/
public String[] getClientAliases(String keyType, Principal[] issuers);
/**
* Choose an alias to authenticate the client side of a secure
* socket given the public key type and the list of
* certificate issuer authorities recognized by the peer (if any).
*
* @param keyType the key algorithm type name(s), ordered
* with the most-preferred key type first.
* @param issuers the list of acceptable CA issuer subject names
* or null if it does not matter which issuers are used.
* @param socket the socket to be used for this connection. This
* parameter can be null, which indicates that
* implementations are free to select an alias applicable
* to any socket.
* @return the alias name for the desired key, or null if there
* are no matches.
*/
public String chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket);
/**
* Get the matching aliases for authenticating the server side of a secure
* socket given the public key type and the list of
* certificate issuer authorities recognized by the peer (if any).
*
* @param keyType the key algorithm type name
* @param issuers the list of acceptable CA issuer subject names
* or null if it does not matter which issuers are used.
* @return an array of the matching alias names, or null
* if there were no matches.
*/
public String[] getServerAliases(String keyType, Principal[] issuers);
/**
* Choose an alias to authenticate the server side of a secure
* socket given the public key type and the list of
* certificate issuer authorities recognized by the peer (if any).
*
* @param keyType the key algorithm type name.
* @param issuers the list of acceptable CA issuer subject names
* or null if it does not matter which issuers are used.
* @param socket the socket to be used for this connection. This
* parameter can be null, which indicates that
* implementations are free to select an alias applicable
* to any socket.
* @return the alias name for the desired key, or null if there
* are no matches.
*/
public String chooseServerAlias(String keyType, Principal[] issuers,
Socket socket);
/**
* Returns the certificate chain associated with the given alias.
*
* @param alias the alias name
* @return the certificate chain (ordered with the user's certificate first
* and the root certificate authority last), or null
* if the alias can't be found.
*/
public X509Certificate[] getCertificateChain(String alias);
/**
* Returns the key associated with the given alias.
*
* @param alias the alias name
* @return the requested key, or null if the alias can't be found.
*/
public PrivateKey getPrivateKey(String alias);
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 1999, 2005, 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 javax.net.ssl;
import java.security.cert.*;
/**
* Instance of this interface manage which X509 certificates
* may be used to authenticate the remote side of a secure
* socket. Decisions may be based on trusted certificate
* authorities, certificate revocation lists, online
* status checking or other means.
*
* @since 1.4
*/
public interface X509TrustManager extends TrustManager {
/**
* Given the partial or complete certificate chain provided by the
* peer, build a certificate path to a trusted root and return if
* it can be validated and is trusted for client SSL
* authentication based on the authentication type.
* <p>
* The authentication type is determined by the actual certificate
* used. For instance, if RSAPublicKey is used, the authType
* should be "RSA". Checking is case-sensitive.
*
* @param chain the peer certificate chain
* @param authType the authentication type based on the client certificate
* @throws IllegalArgumentException if null or zero-length chain
* is passed in for the chain parameter or if null or zero-length
* string is passed in for the authType parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException;
/**
* Given the partial or complete certificate chain provided by the
* peer, build a certificate path to a trusted root and return if
* it can be validated and is trusted for server SSL
* authentication based on the authentication type.
* <p>
* The authentication type is the key exchange algorithm portion
* of the cipher suites represented as a String, such as "RSA",
* "DHE_DSS". Note: for some exportable cipher suites, the key
* exchange algorithm is determined at run time during the
* handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
* the authType should be RSA_EXPORT when an ephemeral RSA key is
* used for the key exchange, and RSA when the key from the server
* certificate is used. Checking is case-sensitive.
*
* @param chain the peer certificate chain
* @param authType the key exchange algorithm used
* @throws IllegalArgumentException if null or zero-length chain
* is passed in for the chain parameter or if null or zero-length
* string is passed in for the authType parameter
* @throws CertificateException if the certificate chain is not trusted
* by this TrustManager.
*/
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException;
/**
* Return an array of certificate authority certificates
* which are trusted for authenticating peers.
*
* @return a non-null (possibly empty) array of acceptable
* CA issuer certificates.
*/
public X509Certificate[] getAcceptedIssuers();
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 1999, 2017, 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.
*/
/**
* Provides classes for the secure socket package. Using the secure
* socket classes, you can communicate using SSL or a related security
* protocol to reliably detect any errors introduced into the network
* byte stream and to optionally encrypt the data and/or authenticate
* the communicating peers.
*
* <ul>
* <li><a href="{@docRoot}/../specs/security/standard-names.html">
* <b>Java&trade; Security Standard Algorithm Names Specification
* </b></a></li>
* </ul>
*
* @since 1.4
*/
package javax.net.ssl;

View file

@ -0,0 +1,183 @@
/*
* Copyright (c) 1998, 2015, 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 javax.security.auth;
/**
* This class is for authentication permissions. An {@code AuthPermission}
* contains a name (also referred to as a "target name") but no actions
* list; you either have the named permission or you don't.
*
* <p> The target name is the name of a security configuration parameter
* (see below). Currently the {@code AuthPermission} object is used to
* guard access to the {@link Policy}, {@link Subject},
* {@link javax.security.auth.login.LoginContext}, and
* {@link javax.security.auth.login.Configuration} objects.
*
* <p> The standard target names for an Authentication Permission are:
*
* <pre>
* doAs - allow the caller to invoke the
* {@code Subject.doAs} methods.
*
* doAsPrivileged - allow the caller to invoke the
* {@code Subject.doAsPrivileged} methods.
*
* getSubject - allow for the retrieval of the
* Subject(s) associated with the
* current Thread.
*
* getSubjectFromDomainCombiner - allow for the retrieval of the
* Subject associated with the
* a {@code SubjectDomainCombiner}.
*
* setReadOnly - allow the caller to set a Subject
* to be read-only.
*
* modifyPrincipals - allow the caller to modify the {@code Set}
* of Principals associated with a
* {@code Subject}
*
* modifyPublicCredentials - allow the caller to modify the
* {@code Set} of public credentials
* associated with a {@code Subject}
*
* modifyPrivateCredentials - allow the caller to modify the
* {@code Set} of private credentials
* associated with a {@code Subject}
*
* refreshCredential - allow code to invoke the {@code refresh}
* method on a credential which implements
* the {@code Refreshable} interface.
*
* destroyCredential - allow code to invoke the {@code destroy}
* method on a credential {@code object}
* which implements the {@code Destroyable}
* interface.
*
* createLoginContext.{name} - allow code to instantiate a
* {@code LoginContext} with the
* specified {@code name}. {@code name}
* is used as the index into the installed login
* {@code Configuration}
* (that returned by
* {@code Configuration.getConfiguration()}).
* <i>name</i> can be wildcarded (set to '*')
* to allow for any name.
*
* getLoginConfiguration - allow for the retrieval of the system-wide
* login Configuration.
*
* createLoginConfiguration.{type} - allow code to obtain a Configuration
* object via
* {@code Configuration.getInstance}.
*
* setLoginConfiguration - allow for the setting of the system-wide
* login Configuration.
*
* refreshLoginConfiguration - allow for the refreshing of the system-wide
* login Configuration.
* </pre>
*
* <p>Please note that granting this permission with the "modifyPrincipals",
* "modifyPublicCredentials" or "modifyPrivateCredentials" target allows
* a JAAS login module to populate principal or credential objects into
* the Subject. Although reading information inside the private credentials
* set requires a {@link PrivateCredentialPermission} of the credential type to
* be granted, reading information inside the principals set and the public
* credentials set requires no additional permission. These objects can contain
* potentially sensitive information. For example, login modules that read
* local user information or perform a Kerberos login are able to add
* potentially sensitive information such as user ids, groups and domain names
* to the principals set.
*
* <p> The following target name has been deprecated in favor of
* {@code createLoginContext.{name}}.
*
* <pre>
* createLoginContext - allow code to instantiate a
* {@code LoginContext}.
* </pre>
*
* <p> {@code javax.security.auth.Policy} has been
* deprecated in favor of {@code java.security.Policy}.
* Therefore, the following target names have also been deprecated:
*
* <pre>
* getPolicy - allow the caller to retrieve the system-wide
* Subject-based access control policy.
*
* setPolicy - allow the caller to set the system-wide
* Subject-based access control policy.
*
* refreshPolicy - allow the caller to refresh the system-wide
* Subject-based access control policy.
* </pre>
*
* @implNote
* Implementations may define additional target names, but should use naming
* conventions such as reverse domain name notation to avoid name clashes.
* @since 1.4
*/
public final class AuthPermission extends
java.security.BasicPermission {
private static final long serialVersionUID = 5806031445061587174L;
/**
* Creates a new AuthPermission with the specified name.
* The name is the symbolic name of the AuthPermission.
*
* @param name the name of the AuthPermission
*
* @throws NullPointerException if {@code name} is {@code null}.
* @throws IllegalArgumentException if {@code name} is empty.
*/
public AuthPermission(String name) {
// for backwards compatibility --
// createLoginContext is deprecated in favor of createLoginContext.*
super("createLoginContext".equals(name) ?
"createLoginContext.*" : name);
}
/**
* Creates a new AuthPermission object with the specified name.
* The name is the symbolic name of the AuthPermission, and the
* actions String is currently unused and should be null.
*
* @param name the name of the AuthPermission
*
* @param actions should be null.
*
* @throws NullPointerException if {@code name} is {@code null}.
* @throws IllegalArgumentException if {@code name} is empty.
*/
public AuthPermission(String name, String actions) {
// for backwards compatibility --
// createLoginContext is deprecated in favor of createLoginContext.*
super("createLoginContext".equals(name) ?
"createLoginContext.*" : name, actions);
}
}

Some files were not shown because too many files have changed in this diff Show more