feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
55
jdkSrc/jdk8/javax/crypto/AEADBadTagException.java
Normal file
55
jdkSrc/jdk8/javax/crypto/AEADBadTagException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
60
jdkSrc/jdk8/javax/crypto/BadPaddingException.java
Normal file
60
jdkSrc/jdk8/javax/crypto/BadPaddingException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
2765
jdkSrc/jdk8/javax/crypto/Cipher.java
Normal file
2765
jdkSrc/jdk8/javax/crypto/Cipher.java
Normal file
File diff suppressed because it is too large
Load Diff
353
jdkSrc/jdk8/javax/crypto/CipherInputStream.java
Normal file
353
jdkSrc/jdk8/javax/crypto/CipherInputStream.java
Normal file
@@ -0,0 +1,353 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
* This class may catch BadPaddingException and other exceptions thrown by
|
||||
* failed integrity checks during decryption. These exceptions are not
|
||||
* re-thrown, so the client may not be informed that integrity checks
|
||||
* failed. Because of this behavior, this class may not be suitable
|
||||
* for use with decryption in an authenticated mode of operation (e.g. GCM).
|
||||
* Applications that require authenticated encryption can use the Cipher API
|
||||
* directly as an alternative to using this class.
|
||||
*
|
||||
* <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.
|
||||
* <p>
|
||||
*
|
||||
* @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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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)
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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()
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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()
|
||||
* @since JCE1.2
|
||||
*/
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
227
jdkSrc/jdk8/javax/crypto/CipherOutputStream.java
Normal file
227
jdkSrc/jdk8/javax/crypto/CipherOutputStream.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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. In particular, this
|
||||
* class catches BadPaddingException and other exceptions thrown by
|
||||
* failed integrity checks during decryption. These exceptions are not
|
||||
* re-thrown, so the client will not be informed that integrity checks
|
||||
* failed. Because of this behavior, this class may not be suitable
|
||||
* for use with decryption in an authenticated mode of operation (e.g. GCM)
|
||||
* if the application requires explicit notification when authentication
|
||||
* fails. Such an application can use the Cipher API directly as an
|
||||
* alternative to using this class.
|
||||
*
|
||||
* <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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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)
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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.
|
||||
* @since JCE1.2
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
991
jdkSrc/jdk8/javax/crypto/CipherSpi.java
Normal file
991
jdkSrc/jdk8/javax/crypto/CipherSpi.java
Normal file
@@ -0,0 +1,991 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.StringTokenizer;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.Provider;
|
||||
import java.security.Key;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.ProviderException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
|
||||
* for the <code>Cipher</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 cipher algorithm.
|
||||
*
|
||||
* <p>In order to create an instance of <code>Cipher</code>, which
|
||||
* encapsulates an instance of this <code>CipherSpi</code> class, an
|
||||
* application calls one of the
|
||||
* {@link Cipher#getInstance(java.lang.String) getInstance}
|
||||
* factory methods of the
|
||||
* {@link Cipher Cipher} engine class and specifies the requested
|
||||
* <i>transformation</i>.
|
||||
* Optionally, the application may also specify the name of a provider.
|
||||
*
|
||||
* <p>A <i>transformation</i> is a string that describes the operation (or
|
||||
* set of operations) to be performed on the given input, to produce some
|
||||
* output. A transformation always includes the name of a cryptographic
|
||||
* algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and
|
||||
* padding scheme.
|
||||
*
|
||||
* <p> A transformation is of the form:
|
||||
*
|
||||
* <ul>
|
||||
* <li>"<i>algorithm/mode/padding</i>" or
|
||||
*
|
||||
* <li>"<i>algorithm</i>"
|
||||
* </ul>
|
||||
*
|
||||
* <P> (in the latter case,
|
||||
* provider-specific default values for the mode and padding scheme are used).
|
||||
* For example, the following is a valid transformation:
|
||||
*
|
||||
* <pre>
|
||||
* Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>");
|
||||
* </pre>
|
||||
*
|
||||
* <p>A provider may supply a separate class for each combination
|
||||
* of <i>algorithm/mode/padding</i>, or may decide to provide more generic
|
||||
* classes representing sub-transformations corresponding to
|
||||
* <i>algorithm</i> or <i>algorithm/mode</i> or <i>algorithm//padding</i>
|
||||
* (note the double slashes),
|
||||
* in which case the requested mode and/or padding are set automatically by
|
||||
* the <code>getInstance</code> methods of <code>Cipher</code>, which invoke
|
||||
* the {@link #engineSetMode(java.lang.String) engineSetMode} and
|
||||
* {@link #engineSetPadding(java.lang.String) engineSetPadding}
|
||||
* methods of the provider's subclass of <code>CipherSpi</code>.
|
||||
*
|
||||
* <p>A <code>Cipher</code> property in a provider master class may have one of
|
||||
* the following formats:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* // provider's subclass of "CipherSpi" implements "algName" with
|
||||
* // pluggable mode and padding
|
||||
* <code>Cipher.</code><i>algName</i>
|
||||
* </pre>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* // provider's subclass of "CipherSpi" implements "algName" in the
|
||||
* // specified "mode", with pluggable padding
|
||||
* <code>Cipher.</code><i>algName/mode</i>
|
||||
* </pre>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* // provider's subclass of "CipherSpi" implements "algName" with the
|
||||
* // specified "padding", with pluggable mode
|
||||
* <code>Cipher.</code><i>algName//padding</i>
|
||||
* </pre>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* // provider's subclass of "CipherSpi" implements "algName" with the
|
||||
* // specified "mode" and "padding"
|
||||
* <code>Cipher.</code><i>algName/mode/padding</i>
|
||||
* </pre>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>For example, a provider may supply a subclass of <code>CipherSpi</code>
|
||||
* that implements <i>AES/ECB/PKCS5Padding</i>, one that implements
|
||||
* <i>AES/CBC/PKCS5Padding</i>, one that implements
|
||||
* <i>AES/CFB/PKCS5Padding</i>, and yet another one that implements
|
||||
* <i>AES/OFB/PKCS5Padding</i>. That provider would have the following
|
||||
* <code>Cipher</code> properties in its master class:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* <code>Cipher.</code><i>AES/ECB/PKCS5Padding</i>
|
||||
* </pre>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* <code>Cipher.</code><i>AES/CBC/PKCS5Padding</i>
|
||||
* </pre>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* <code>Cipher.</code><i>AES/CFB/PKCS5Padding</i>
|
||||
* </pre>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* <code>Cipher.</code><i>AES/OFB/PKCS5Padding</i>
|
||||
* </pre>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>Another provider may implement a class for each of the above modes
|
||||
* (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>,
|
||||
* and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>,
|
||||
* and a generic <i>AES</i> class that subclasses from <code>CipherSpi</code>.
|
||||
* That provider would have the following
|
||||
* <code>Cipher</code> properties in its master class:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>
|
||||
* <pre>
|
||||
* <code>Cipher.</code><i>AES</i>
|
||||
* </pre>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>The <code>getInstance</code> factory method of the <code>Cipher</code>
|
||||
* engine class follows these rules in order to instantiate a provider's
|
||||
* implementation of <code>CipherSpi</code> for a
|
||||
* transformation of the form "<i>algorithm</i>":
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* Check if the provider has registered a subclass of <code>CipherSpi</code>
|
||||
* for the specified "<i>algorithm</i>".
|
||||
* <p>If the answer is YES, instantiate this
|
||||
* class, for whose mode and padding scheme default values (as supplied by
|
||||
* the provider) are used.
|
||||
* <p>If the answer is NO, throw a <code>NoSuchAlgorithmException</code>
|
||||
* exception.
|
||||
* </ol>
|
||||
*
|
||||
* <p>The <code>getInstance</code> factory method of the <code>Cipher</code>
|
||||
* engine class follows these rules in order to instantiate a provider's
|
||||
* implementation of <code>CipherSpi</code> for a
|
||||
* transformation of the form "<i>algorithm/mode/padding</i>":
|
||||
*
|
||||
* <ol>
|
||||
* <li>
|
||||
* Check if the provider has registered a subclass of <code>CipherSpi</code>
|
||||
* for the specified "<i>algorithm/mode/padding</i>" transformation.
|
||||
* <p>If the answer is YES, instantiate it.
|
||||
* <p>If the answer is NO, go to the next step.
|
||||
* <li>
|
||||
* Check if the provider has registered a subclass of <code>CipherSpi</code>
|
||||
* for the sub-transformation "<i>algorithm/mode</i>".
|
||||
* <p>If the answer is YES, instantiate it, and call
|
||||
* <code>engineSetPadding(<i>padding</i>)</code> on the new instance.
|
||||
* <p>If the answer is NO, go to the next step.
|
||||
* <li>
|
||||
* Check if the provider has registered a subclass of <code>CipherSpi</code>
|
||||
* for the sub-transformation "<i>algorithm//padding</i>" (note the double
|
||||
* slashes).
|
||||
* <p>If the answer is YES, instantiate it, and call
|
||||
* <code>engineSetMode(<i>mode</i>)</code> on the new instance.
|
||||
* <p>If the answer is NO, go to the next step.
|
||||
* <li>
|
||||
* Check if the provider has registered a subclass of <code>CipherSpi</code>
|
||||
* for the sub-transformation "<i>algorithm</i>".
|
||||
* <p>If the answer is YES, instantiate it, and call
|
||||
* <code>engineSetMode(<i>mode</i>)</code> and
|
||||
* <code>engineSetPadding(<i>padding</i>)</code> on the new instance.
|
||||
* <p>If the answer is NO, throw a <code>NoSuchAlgorithmException</code>
|
||||
* exception.
|
||||
* </ol>
|
||||
*
|
||||
* @author Jan Luehe
|
||||
* @see KeyGenerator
|
||||
* @see SecretKey
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class CipherSpi {
|
||||
|
||||
/**
|
||||
* Sets the mode of this cipher.
|
||||
*
|
||||
* @param mode the cipher mode
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if the requested cipher mode does
|
||||
* not exist
|
||||
*/
|
||||
protected abstract void engineSetMode(String mode)
|
||||
throws NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Sets the padding mechanism of this cipher.
|
||||
*
|
||||
* @param padding the padding mechanism
|
||||
*
|
||||
* @exception NoSuchPaddingException if the requested padding mechanism
|
||||
* does not exist
|
||||
*/
|
||||
protected abstract void engineSetPadding(String padding)
|
||||
throws NoSuchPaddingException;
|
||||
|
||||
/**
|
||||
* Returns the block size (in bytes).
|
||||
*
|
||||
* @return the block size (in bytes), or 0 if the underlying algorithm is
|
||||
* not a block cipher
|
||||
*/
|
||||
protected abstract int engineGetBlockSize();
|
||||
|
||||
/**
|
||||
* Returns the length in bytes that an output buffer would
|
||||
* need to be in order to hold the result of the next <code>update</code>
|
||||
* or <code>doFinal</code> operation, given the input length
|
||||
* <code>inputLen</code> (in bytes).
|
||||
*
|
||||
* <p>This call takes into account any unprocessed (buffered) data from a
|
||||
* previous <code>update</code> call, padding, and AEAD tagging.
|
||||
*
|
||||
* <p>The actual output length of the next <code>update</code> or
|
||||
* <code>doFinal</code> 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);
|
||||
|
||||
/**
|
||||
* Returns the initialization vector (IV) in a new buffer.
|
||||
*
|
||||
* <p> This is useful in the context of password-based encryption or
|
||||
* decryption, where the IV is derived from a user-provided passphrase.
|
||||
*
|
||||
* @return the initialization vector in a new buffer, or null if the
|
||||
* underlying algorithm does not use an IV, or if the IV has not yet
|
||||
* been set.
|
||||
*/
|
||||
protected abstract byte[] engineGetIV();
|
||||
|
||||
/**
|
||||
* Returns the parameters used with this cipher.
|
||||
*
|
||||
* <p>The returned parameters may be the same that were used to initialize
|
||||
* this cipher, or may contain a combination of default and random
|
||||
* parameter values used by the underlying cipher implementation if this
|
||||
* cipher requires algorithm parameters but was not initialized with any.
|
||||
*
|
||||
* @return the parameters used with this cipher, or null if this cipher
|
||||
* does not use any parameters.
|
||||
*/
|
||||
protected abstract AlgorithmParameters engineGetParameters();
|
||||
|
||||
/**
|
||||
* Initializes this cipher with a key and a source
|
||||
* of randomness.
|
||||
*
|
||||
* <p>The cipher is initialized for one of the following four operations:
|
||||
* encryption, decryption, key wrapping or key unwrapping, depending on
|
||||
* the value of <code>opmode</code>.
|
||||
*
|
||||
* <p>If this cipher requires any algorithm parameters that cannot be
|
||||
* derived from the given <code>key</code>, the underlying cipher
|
||||
* implementation is supposed to generate the required parameters itself
|
||||
* (using provider-specific default or random values) if it is being
|
||||
* initialized for encryption or key wrapping, and raise an
|
||||
* <code>InvalidKeyException</code> if it is being
|
||||
* initialized for decryption or key unwrapping.
|
||||
* The generated parameters can be retrieved using
|
||||
* {@link #engineGetParameters() engineGetParameters} or
|
||||
* {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
|
||||
*
|
||||
* <p>If this cipher requires algorithm parameters that cannot be
|
||||
* derived from the input parameters, and there are no reasonable
|
||||
* provider-specific default values, initialization will
|
||||
* necessarily fail.
|
||||
*
|
||||
* <p>If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from <code>random</code>.
|
||||
*
|
||||
* <p>Note that when a Cipher object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing
|
||||
* it.
|
||||
*
|
||||
* @param opmode the operation mode of this cipher (this is one of
|
||||
* the following:
|
||||
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
||||
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
||||
* @param key the encryption key
|
||||
* @param random the source of randomness
|
||||
*
|
||||
* @exception InvalidKeyException if the given key is inappropriate for
|
||||
* initializing this cipher, or requires
|
||||
* algorithm parameters that cannot be
|
||||
* determined from the given key.
|
||||
* @throws UnsupportedOperationException if {@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
|
||||
* by the cipher.
|
||||
*/
|
||||
protected abstract void engineInit(int opmode, Key key,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException;
|
||||
|
||||
/**
|
||||
* Initializes this cipher with a key, a set of
|
||||
* algorithm parameters, and a source of randomness.
|
||||
*
|
||||
* <p>The cipher is initialized for one of the following four operations:
|
||||
* encryption, decryption, key wrapping or key unwrapping, depending on
|
||||
* the value of <code>opmode</code>.
|
||||
*
|
||||
* <p>If this cipher requires any algorithm parameters and
|
||||
* <code>params</code> is null, the underlying cipher implementation is
|
||||
* supposed to generate the required parameters itself (using
|
||||
* provider-specific default or random values) if it is being
|
||||
* initialized for encryption or key wrapping, and raise an
|
||||
* <code>InvalidAlgorithmParameterException</code> if it is being
|
||||
* initialized for decryption or key unwrapping.
|
||||
* The generated parameters can be retrieved using
|
||||
* {@link #engineGetParameters() engineGetParameters} or
|
||||
* {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
|
||||
*
|
||||
* <p>If this cipher requires algorithm parameters that cannot be
|
||||
* derived from the input parameters, and there are no reasonable
|
||||
* provider-specific default values, initialization will
|
||||
* necessarily fail.
|
||||
*
|
||||
* <p>If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from <code>random</code>.
|
||||
*
|
||||
* <p>Note that when a Cipher object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing
|
||||
* it.
|
||||
*
|
||||
* @param opmode the operation mode of this cipher (this is one of
|
||||
* the following:
|
||||
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
||||
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
||||
* @param key the encryption key
|
||||
* @param params the algorithm parameters
|
||||
* @param random the source of randomness
|
||||
*
|
||||
* @exception InvalidKeyException if the given key is inappropriate for
|
||||
* initializing this cipher
|
||||
* @exception InvalidAlgorithmParameterException if the given algorithm
|
||||
* parameters are inappropriate for this cipher,
|
||||
* or if this cipher requires
|
||||
* algorithm parameters and <code>params</code> is null.
|
||||
* @throws UnsupportedOperationException if {@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
|
||||
* by the cipher.
|
||||
*/
|
||||
protected abstract void engineInit(int opmode, Key key,
|
||||
AlgorithmParameterSpec params,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Initializes this cipher with a key, a set of
|
||||
* algorithm parameters, and a source of randomness.
|
||||
*
|
||||
* <p>The cipher is initialized for one of the following four operations:
|
||||
* encryption, decryption, key wrapping or key unwrapping, depending on
|
||||
* the value of <code>opmode</code>.
|
||||
*
|
||||
* <p>If this cipher requires any algorithm parameters and
|
||||
* <code>params</code> is null, the underlying cipher implementation is
|
||||
* supposed to generate the required parameters itself (using
|
||||
* provider-specific default or random values) if it is being
|
||||
* initialized for encryption or key wrapping, and raise an
|
||||
* <code>InvalidAlgorithmParameterException</code> if it is being
|
||||
* initialized for decryption or key unwrapping.
|
||||
* The generated parameters can be retrieved using
|
||||
* {@link #engineGetParameters() engineGetParameters} or
|
||||
* {@link #engineGetIV() engineGetIV} (if the parameter is an IV).
|
||||
*
|
||||
* <p>If this cipher requires algorithm parameters that cannot be
|
||||
* derived from the input parameters, and there are no reasonable
|
||||
* provider-specific default values, initialization will
|
||||
* necessarily fail.
|
||||
*
|
||||
* <p>If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from <code>random</code>.
|
||||
*
|
||||
* <p>Note that when a Cipher object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing
|
||||
* it.
|
||||
*
|
||||
* @param opmode the operation mode of this cipher (this is one of
|
||||
* the following:
|
||||
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
|
||||
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
|
||||
* @param key the encryption key
|
||||
* @param params the algorithm parameters
|
||||
* @param random the source of randomness
|
||||
*
|
||||
* @exception InvalidKeyException if the given key is inappropriate for
|
||||
* initializing this cipher
|
||||
* @exception InvalidAlgorithmParameterException if the given algorithm
|
||||
* parameters are inappropriate for this cipher,
|
||||
* or if this cipher requires
|
||||
* algorithm parameters and <code>params</code> is null.
|
||||
* @throws UnsupportedOperationException if {@code opmode} is
|
||||
* {@code WRAP_MODE} or {@code UNWRAP_MODE} is not implemented
|
||||
* by the cipher.
|
||||
*/
|
||||
protected abstract void engineInit(int opmode, Key key,
|
||||
AlgorithmParameters params,
|
||||
SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Continues a multiple-part encryption or decryption operation
|
||||
* (depending on how this cipher was initialized), processing another data
|
||||
* part.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code> inclusive, are processed,
|
||||
* and the result is stored in a new buffer.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
*
|
||||
* @return the new buffer with the result, or null if the underlying
|
||||
* cipher is a block cipher and the input data is too short to result in a
|
||||
* new block.
|
||||
*/
|
||||
protected abstract byte[] engineUpdate(byte[] input, int inputOffset,
|
||||
int inputLen);
|
||||
|
||||
/**
|
||||
* Continues a multiple-part encryption or decryption operation
|
||||
* (depending on how this cipher was initialized), processing another data
|
||||
* part.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code> inclusive, are processed,
|
||||
* and the result is stored 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.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
* @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
|
||||
*/
|
||||
protected abstract int engineUpdate(byte[] input, int inputOffset,
|
||||
int inputLen, byte[] output,
|
||||
int outputOffset)
|
||||
throws ShortBufferException;
|
||||
|
||||
/**
|
||||
* Continues a multiple-part encryption or decryption operation
|
||||
* (depending on how this cipher was initialized), processing another data
|
||||
* part.
|
||||
*
|
||||
* <p>All <code>input.remaining()</code> bytes starting at
|
||||
* <code>input.position()</code> are processed. The result is stored
|
||||
* in the output buffer.
|
||||
* Upon return, the input buffer's position will be equal
|
||||
* to its limit; its limit will not have changed. The output buffer's
|
||||
* position will have advanced by n, where n is the value returned
|
||||
* by this method; the output buffer's limit will not have changed.
|
||||
*
|
||||
* <p>If <code>output.remaining()</code> bytes are insufficient to
|
||||
* hold the result, a <code>ShortBufferException</code> is thrown.
|
||||
*
|
||||
* <p>Subclasses should consider overriding this method if they can
|
||||
* process ByteBuffers more efficiently than byte arrays.
|
||||
*
|
||||
* @param input the input ByteBuffer
|
||||
* @param output the output ByteByffer
|
||||
*
|
||||
* @return the number of bytes stored in <code>output</code>
|
||||
*
|
||||
* @exception ShortBufferException if there is insufficient space in the
|
||||
* output buffer
|
||||
*
|
||||
* @throws NullPointerException if either parameter is <CODE>null</CODE>
|
||||
* @since 1.5
|
||||
*/
|
||||
protected int engineUpdate(ByteBuffer input, ByteBuffer output)
|
||||
throws ShortBufferException {
|
||||
try {
|
||||
return bufferCrypt(input, output, true);
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
// never thrown for engineUpdate()
|
||||
throw new ProviderException("Internal error in update()");
|
||||
} catch (BadPaddingException e) {
|
||||
// never thrown for engineUpdate()
|
||||
throw new ProviderException("Internal error in update()");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts data in a single-part operation,
|
||||
* or finishes a multiple-part operation.
|
||||
* The data is encrypted or decrypted, depending on how this cipher was
|
||||
* initialized.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code> inclusive, and any input
|
||||
* bytes that may have been buffered during a previous <code>update</code>
|
||||
* operation, are processed, with padding (if requested) being applied.
|
||||
* If an AEAD mode such as GCM/CCM is being used, the authentication
|
||||
* tag is appended in the case of encryption, or verified in the
|
||||
* case of decryption.
|
||||
* The result is stored in a new buffer.
|
||||
*
|
||||
* <p>Upon finishing, this method resets this cipher object to the state
|
||||
* it was in when previously initialized via a call to
|
||||
* <code>engineInit</code>.
|
||||
* That is, the object is reset and available to encrypt or decrypt
|
||||
* (depending on the operation mode that was specified in the call to
|
||||
* <code>engineInit</code>) more data.
|
||||
*
|
||||
* <p>Note: if any exception is thrown, this cipher object may need to
|
||||
* be reset before it can be used again.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
*
|
||||
* @return the new buffer with the result
|
||||
*
|
||||
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
||||
* no padding has been requested (only in encryption mode), and the total
|
||||
* input length of the data processed by this cipher is not a multiple of
|
||||
* block size; or if this encryption algorithm is unable to
|
||||
* process the input data provided.
|
||||
* @exception BadPaddingException if this cipher is in decryption mode,
|
||||
* and (un)padding has been requested, but the decrypted data is not
|
||||
* bounded by the appropriate padding bytes
|
||||
* @exception AEADBadTagException if this cipher is decrypting in an
|
||||
* AEAD mode (such as GCM/CCM), and the received authentication tag
|
||||
* does not match the calculated value
|
||||
*/
|
||||
protected abstract byte[] engineDoFinal(byte[] input, int inputOffset,
|
||||
int inputLen)
|
||||
throws IllegalBlockSizeException, BadPaddingException;
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts data in a single-part operation,
|
||||
* or finishes a multiple-part operation.
|
||||
* The data is encrypted or decrypted, depending on how this cipher was
|
||||
* initialized.
|
||||
*
|
||||
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
|
||||
* buffer, starting at <code>inputOffset</code> inclusive, and any input
|
||||
* bytes that may have been buffered during a previous <code>update</code>
|
||||
* operation, are processed, with padding (if requested) being applied.
|
||||
* If an AEAD mode such as GCM/CCM is being used, the authentication
|
||||
* tag is appended in the case of encryption, or verified in the
|
||||
* case of decryption.
|
||||
* The result is stored 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.
|
||||
*
|
||||
* <p>Upon finishing, this method resets this cipher object to the state
|
||||
* it was in when previously initialized via a call to
|
||||
* <code>engineInit</code>.
|
||||
* That is, the object is reset and available to encrypt or decrypt
|
||||
* (depending on the operation mode that was specified in the call to
|
||||
* <code>engineInit</code>) more data.
|
||||
*
|
||||
* <p>Note: if any exception is thrown, this cipher object may need to
|
||||
* be reset before it can be used again.
|
||||
*
|
||||
* @param input the input buffer
|
||||
* @param inputOffset the offset in <code>input</code> where the input
|
||||
* starts
|
||||
* @param inputLen the input length
|
||||
* @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 IllegalBlockSizeException if this cipher is a block cipher,
|
||||
* no padding has been requested (only in encryption mode), and the total
|
||||
* input length of the data processed by this cipher is not a multiple of
|
||||
* block size; or if this encryption algorithm is unable to
|
||||
* process the input data provided.
|
||||
* @exception ShortBufferException if the given output buffer is too small
|
||||
* to hold the result
|
||||
* @exception BadPaddingException if this cipher is in decryption mode,
|
||||
* and (un)padding has been requested, but the decrypted data is not
|
||||
* bounded by the appropriate padding bytes
|
||||
* @exception AEADBadTagException if this cipher is decrypting in an
|
||||
* AEAD mode (such as GCM/CCM), and the received authentication tag
|
||||
* does not match the calculated value
|
||||
*/
|
||||
protected abstract int engineDoFinal(byte[] input, int inputOffset,
|
||||
int inputLen, byte[] output,
|
||||
int outputOffset)
|
||||
throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException;
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts data in a single-part operation,
|
||||
* or finishes a multiple-part operation.
|
||||
* The data is encrypted or decrypted, depending on how this cipher was
|
||||
* initialized.
|
||||
*
|
||||
* <p>All <code>input.remaining()</code> bytes starting at
|
||||
* <code>input.position()</code> are processed.
|
||||
* If an AEAD mode such as GCM/CCM is being used, the authentication
|
||||
* tag is appended in the case of encryption, or verified in the
|
||||
* case of decryption.
|
||||
* The result is stored in the output buffer.
|
||||
* Upon return, the input buffer's position will be equal
|
||||
* to its limit; its limit will not have changed. The output buffer's
|
||||
* position will have advanced by n, where n is the value returned
|
||||
* by this method; the output buffer's limit will not have changed.
|
||||
*
|
||||
* <p>If <code>output.remaining()</code> bytes are insufficient to
|
||||
* hold the result, a <code>ShortBufferException</code> is thrown.
|
||||
*
|
||||
* <p>Upon finishing, this method resets this cipher object to the state
|
||||
* it was in when previously initialized via a call to
|
||||
* <code>engineInit</code>.
|
||||
* That is, the object is reset and available to encrypt or decrypt
|
||||
* (depending on the operation mode that was specified in the call to
|
||||
* <code>engineInit</code>) more data.
|
||||
*
|
||||
* <p>Note: if any exception is thrown, this cipher object may need to
|
||||
* be reset before it can be used again.
|
||||
*
|
||||
* <p>Subclasses should consider overriding this method if they can
|
||||
* process ByteBuffers more efficiently than byte arrays.
|
||||
*
|
||||
* @param input the input ByteBuffer
|
||||
* @param output the output ByteByffer
|
||||
*
|
||||
* @return the number of bytes stored in <code>output</code>
|
||||
*
|
||||
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
||||
* no padding has been requested (only in encryption mode), and the total
|
||||
* input length of the data processed by this cipher is not a multiple of
|
||||
* block size; or if this encryption algorithm is unable to
|
||||
* process the input data provided.
|
||||
* @exception ShortBufferException if there is insufficient space in the
|
||||
* output buffer
|
||||
* @exception BadPaddingException if this cipher is in decryption mode,
|
||||
* and (un)padding has been requested, but the decrypted data is not
|
||||
* bounded by the appropriate padding bytes
|
||||
* @exception AEADBadTagException if this cipher is decrypting in an
|
||||
* AEAD mode (such as GCM/CCM), and the received authentication tag
|
||||
* does not match the calculated value
|
||||
*
|
||||
* @throws NullPointerException if either parameter is <CODE>null</CODE>
|
||||
* @since 1.5
|
||||
*/
|
||||
protected int engineDoFinal(ByteBuffer input, ByteBuffer output)
|
||||
throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
return bufferCrypt(input, output, false);
|
||||
}
|
||||
|
||||
// copied from sun.security.jca.JCAUtil
|
||||
// will be changed to reference that method once that code has been
|
||||
// integrated and promoted
|
||||
static int getTempArraySize(int totalSize) {
|
||||
return Math.min(4096, totalSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation for encryption using ByteBuffers. Used for both
|
||||
* engineUpdate() and engineDoFinal().
|
||||
*/
|
||||
private int bufferCrypt(ByteBuffer input, ByteBuffer output,
|
||||
boolean isUpdate) throws ShortBufferException,
|
||||
IllegalBlockSizeException, BadPaddingException {
|
||||
if ((input == null) || (output == null)) {
|
||||
throw new NullPointerException
|
||||
("Input and output buffers must not be null");
|
||||
}
|
||||
int inPos = input.position();
|
||||
int inLimit = input.limit();
|
||||
int inLen = inLimit - inPos;
|
||||
if (isUpdate && (inLen == 0)) {
|
||||
return 0;
|
||||
}
|
||||
int outLenNeeded = engineGetOutputSize(inLen);
|
||||
|
||||
if (output.remaining() < outLenNeeded) {
|
||||
throw new ShortBufferException("Need at least " + outLenNeeded
|
||||
+ " bytes of space in output buffer");
|
||||
}
|
||||
|
||||
boolean a1 = input.hasArray();
|
||||
boolean a2 = output.hasArray();
|
||||
int total = 0;
|
||||
byte[] inArray, outArray;
|
||||
if (a2) { // output has an accessible byte[]
|
||||
outArray = output.array();
|
||||
int outPos = output.position();
|
||||
int outOfs = output.arrayOffset() + outPos;
|
||||
|
||||
if (a1) { // input also has an accessible byte[]
|
||||
inArray = input.array();
|
||||
int inOfs = input.arrayOffset() + inPos;
|
||||
if (isUpdate) {
|
||||
total = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
|
||||
} else {
|
||||
total = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
|
||||
}
|
||||
input.position(inLimit);
|
||||
} else { // input does not have accessible byte[]
|
||||
inArray = new byte[getTempArraySize(inLen)];
|
||||
do {
|
||||
int chunk = Math.min(inLen, inArray.length);
|
||||
if (chunk > 0) {
|
||||
input.get(inArray, 0, chunk);
|
||||
}
|
||||
int n;
|
||||
if (isUpdate || (inLen > chunk)) {
|
||||
n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
|
||||
} else {
|
||||
n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
|
||||
}
|
||||
total += n;
|
||||
outOfs += n;
|
||||
inLen -= chunk;
|
||||
} while (inLen > 0);
|
||||
}
|
||||
output.position(outPos + total);
|
||||
} else { // output does not have an accessible byte[]
|
||||
if (a1) { // but input has an accessible byte[]
|
||||
inArray = input.array();
|
||||
int inOfs = input.arrayOffset() + inPos;
|
||||
if (isUpdate) {
|
||||
outArray = engineUpdate(inArray, inOfs, inLen);
|
||||
} else {
|
||||
outArray = engineDoFinal(inArray, inOfs, inLen);
|
||||
}
|
||||
input.position(inLimit);
|
||||
if (outArray != null && outArray.length != 0) {
|
||||
output.put(outArray);
|
||||
total = outArray.length;
|
||||
}
|
||||
} else { // input also does not have an accessible byte[]
|
||||
inArray = new byte[getTempArraySize(inLen)];
|
||||
do {
|
||||
int chunk = Math.min(inLen, inArray.length);
|
||||
if (chunk > 0) {
|
||||
input.get(inArray, 0, chunk);
|
||||
}
|
||||
int n;
|
||||
if (isUpdate || (inLen > chunk)) {
|
||||
outArray = engineUpdate(inArray, 0, chunk);
|
||||
} else {
|
||||
outArray = engineDoFinal(inArray, 0, chunk);
|
||||
}
|
||||
if (outArray != null && outArray.length != 0) {
|
||||
output.put(outArray);
|
||||
total += outArray.length;
|
||||
}
|
||||
inLen -= chunk;
|
||||
} while (inLen > 0);
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a key.
|
||||
*
|
||||
* <p>This concrete method has been added to this previously-defined
|
||||
* abstract class. (For backwards compatibility, it cannot be abstract.)
|
||||
* It may be overridden by a provider to wrap a key.
|
||||
* Such an override is expected to throw an IllegalBlockSizeException or
|
||||
* InvalidKeyException (under the specified circumstances),
|
||||
* if the given key cannot be wrapped.
|
||||
* If this method is not overridden, it always throws an
|
||||
* UnsupportedOperationException.
|
||||
*
|
||||
* @param key the key to be wrapped.
|
||||
*
|
||||
* @return the wrapped key.
|
||||
*
|
||||
* @exception IllegalBlockSizeException if this cipher is a block cipher,
|
||||
* no padding has been requested, and the length of the encoding of the
|
||||
* key to be wrapped is not a multiple of the block size.
|
||||
*
|
||||
* @exception InvalidKeyException if it is impossible or unsafe to
|
||||
* wrap the key with this cipher (e.g., a hardware protected key is
|
||||
* being passed to a software-only cipher).
|
||||
*
|
||||
* @throws UnsupportedOperationException if this method is not supported.
|
||||
*/
|
||||
protected byte[] engineWrap(Key key)
|
||||
throws IllegalBlockSizeException, InvalidKeyException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap a previously wrapped key.
|
||||
*
|
||||
* <p>This concrete method has been added to this previously-defined
|
||||
* abstract class. (For backwards compatibility, it cannot be abstract.)
|
||||
* It may be overridden by a provider to unwrap a previously wrapped key.
|
||||
* Such an override is expected to throw an InvalidKeyException if
|
||||
* the given wrapped key cannot be unwrapped.
|
||||
* If this method is not overridden, it always throws an
|
||||
* UnsupportedOperationException.
|
||||
*
|
||||
* @param wrappedKey the key to be unwrapped.
|
||||
*
|
||||
* @param wrappedKeyAlgorithm the algorithm associated with the wrapped
|
||||
* key.
|
||||
*
|
||||
* @param wrappedKeyType the type of the wrapped key. This is one of
|
||||
* <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or
|
||||
* <code>PUBLIC_KEY</code>.
|
||||
*
|
||||
* @return the unwrapped key.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no installed providers
|
||||
* can create keys of type <code>wrappedKeyType</code> for the
|
||||
* <code>wrappedKeyAlgorithm</code>.
|
||||
*
|
||||
* @exception InvalidKeyException if <code>wrappedKey</code> does not
|
||||
* represent a wrapped key of type <code>wrappedKeyType</code> for
|
||||
* the <code>wrappedKeyAlgorithm</code>.
|
||||
*
|
||||
* @throws UnsupportedOperationException if this method is not supported.
|
||||
*/
|
||||
protected Key engineUnwrap(byte[] wrappedKey,
|
||||
String wrappedKeyAlgorithm,
|
||||
int wrappedKeyType)
|
||||
throws InvalidKeyException, NoSuchAlgorithmException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key size of the given key object in bits.
|
||||
* <p>This concrete method has been added to this previously-defined
|
||||
* abstract class. It throws an <code>UnsupportedOperationException</code>
|
||||
* if it is not overridden by the provider.
|
||||
*
|
||||
* @param key the key object.
|
||||
*
|
||||
* @return the key size of the given key object.
|
||||
*
|
||||
* @exception InvalidKeyException if <code>key</code> is invalid.
|
||||
*/
|
||||
protected int engineGetKeySize(Key key)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multi-part update of the Additional Authentication
|
||||
* Data (AAD), using a subset of the provided buffer.
|
||||
* <p>
|
||||
* Calls to this method provide AAD to the cipher when operating in
|
||||
* modes such as AEAD (GCM/CCM). If this cipher is operating in
|
||||
* either GCM or CCM mode, all AAD must be supplied before beginning
|
||||
* operations on the ciphertext (via the {@code update} and {@code
|
||||
* doFinal} methods).
|
||||
*
|
||||
* @param src the buffer containing the AAD
|
||||
* @param offset the offset in {@code src} where the AAD input starts
|
||||
* @param len the number of AAD bytes
|
||||
*
|
||||
* @throws IllegalStateException if this cipher is in a wrong state
|
||||
* (e.g., has not been initialized), does not accept AAD, or if
|
||||
* operating in either GCM or CCM mode and one of the {@code update}
|
||||
* methods has already been called for the active
|
||||
* encryption/decryption operation
|
||||
* @throws UnsupportedOperationException if this method
|
||||
* has not been overridden by an implementation
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
protected void engineUpdateAAD(byte[] src, int offset, int len) {
|
||||
throw new UnsupportedOperationException(
|
||||
"The underlying Cipher implementation "
|
||||
+ "does not support this method");
|
||||
}
|
||||
|
||||
/**
|
||||
* Continues a multi-part update of the Additional Authentication
|
||||
* Data (AAD).
|
||||
* <p>
|
||||
* Calls to this method provide AAD to the cipher when operating in
|
||||
* modes such as AEAD (GCM/CCM). If this cipher is operating in
|
||||
* either GCM or CCM mode, all AAD must be supplied before beginning
|
||||
* operations on the ciphertext (via the {@code update} and {@code
|
||||
* doFinal} methods).
|
||||
* <p>
|
||||
* All {@code src.remaining()} bytes starting at
|
||||
* {@code src.position()} are processed.
|
||||
* Upon return, the input buffer's position will be equal
|
||||
* to its limit; its limit will not have changed.
|
||||
*
|
||||
* @param src the buffer containing the AAD
|
||||
*
|
||||
* @throws IllegalStateException if this cipher is in a wrong state
|
||||
* (e.g., has not been initialized), does not accept AAD, or if
|
||||
* operating in either GCM or CCM mode and one of the {@code update}
|
||||
* methods has already been called for the active
|
||||
* encryption/decryption operation
|
||||
* @throws UnsupportedOperationException if this method
|
||||
* has not been overridden by an implementation
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
protected void engineUpdateAAD(ByteBuffer src) {
|
||||
throw new UnsupportedOperationException(
|
||||
"The underlying Cipher implementation "
|
||||
+ "does not support this method");
|
||||
}
|
||||
}
|
||||
177
jdkSrc/jdk8/javax/crypto/CryptoAllPermission.java
Normal file
177
jdkSrc/jdk8/javax/crypto/CryptoAllPermission.java
Normal 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();
|
||||
}
|
||||
}
|
||||
543
jdkSrc/jdk8/javax/crypto/CryptoPermission.java
Normal file
543
jdkSrc/jdk8/javax/crypto/CryptoPermission.java
Normal file
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* 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.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:<p>
|
||||
* <ul>
|
||||
* <li> <i>p</i> is an instance of CryptoPermission, and<p>
|
||||
* <li> <i>p</i>'s algorithm name equals or (in the case of wildcards)
|
||||
* is implied by this permission's algorithm name, and<p>
|
||||
* <li> <i>p</i>'s maximum allowable key size is less or
|
||||
* equal to this permission's maximum allowable key size, and<p>
|
||||
* <li> <i>p</i>'s algorithm parameter spec equals or is
|
||||
* implied by this permission's algorithm parameter spec, and<p>
|
||||
* <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).
|
||||
* </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();
|
||||
}
|
||||
}
|
||||
504
jdkSrc/jdk8/javax/crypto/CryptoPermissions.java
Normal file
504
jdkSrc/jdk8/javax/crypto/CryptoPermissions.java
Normal file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
* 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.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.ObjectInputStream.GetField;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectOutputStream.PutField;
|
||||
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
|
||||
*/
|
||||
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.
|
||||
*
|
||||
*/
|
||||
public boolean implies(Permission permission) {
|
||||
if (!(permission instanceof CryptoPermission)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CryptoPermission cryptoPerm = (CryptoPermission)permission;
|
||||
|
||||
PermissionCollection pc =
|
||||
getPermissionCollection(cryptoPerm.getAlgorithm());
|
||||
return pc.implies(cryptoPerm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of all the Permission objects in all the
|
||||
* PermissionCollections in this CryptoPermissions object.
|
||||
*
|
||||
* @return an enumeration of all the Permissions.
|
||||
*/
|
||||
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 Enumeration<PermissionCollection> perms;
|
||||
// the current set
|
||||
private Enumeration<Permission> permset;
|
||||
|
||||
PermissionsEnumerator(Enumeration<PermissionCollection> e) {
|
||||
perms = e;
|
||||
permset = getNextEnumWithMore();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
706
jdkSrc/jdk8/javax/crypto/CryptoPolicyParser.java
Normal file
706
jdkSrc/jdk8/javax/crypto/CryptoPolicyParser.java
Normal file
@@ -0,0 +1,706 @@
|
||||
/*
|
||||
* 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.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:
|
||||
*
|
||||
* permission <crypto permission class name>[, <algorithm name>
|
||||
* [[, <exemption mechanism name>][, <maxKeySize>
|
||||
* [, <AlgrithomParameterSpec class name>, <parameters
|
||||
* for constructing an AlgrithomParameterSpec object>]]]];
|
||||
*
|
||||
* @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(new Integer(match()));
|
||||
} else {
|
||||
if (peek("*")) {
|
||||
match("*");
|
||||
paramsV.addElement(new Integer(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>
|
||||
*
|
||||
* <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>
|
||||
*
|
||||
* <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+"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
433
jdkSrc/jdk8/javax/crypto/EncryptedPrivateKeyInfo.java
Normal file
433
jdkSrc/jdk8/javax/crypto/EncryptedPrivateKeyInfo.java
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2022, 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 "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 = DerValue.wrap(this.encoded);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("DER header error: no SEQ tag");
|
||||
}
|
||||
|
||||
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 Appendix A in the
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* 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 Appendix A in the
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 static 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");
|
||||
DerInputStream algid = values[1].toDerInputStream();
|
||||
algid.getOID();
|
||||
if (algid.available() != 0) {
|
||||
algid.getDerValue();
|
||||
}
|
||||
checkTag(values[2], DerValue.tag_OctetString, "privateKey");
|
||||
break;
|
||||
default:
|
||||
throw new IOException("invalid key encoding");
|
||||
}
|
||||
}
|
||||
}
|
||||
486
jdkSrc/jdk8/javax/crypto/ExemptionMechanism.java
Normal file
486
jdkSrc/jdk8/javax/crypto/ExemptionMechanism.java
Normal file
@@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.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 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.
|
||||
*
|
||||
* @param algorithm the standard name of the requested exemption
|
||||
* mechanism.
|
||||
* See the ExemptionMechanism section in the
|
||||
* <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Exemption">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard exemption mechanism names.
|
||||
*
|
||||
* @return the new <code>ExemptionMechanism</code> object.
|
||||
*
|
||||
* @exception NullPointerException if <code>algorithm</code>
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no Provider supports an
|
||||
* ExemptionMechanismSpi implementation for the
|
||||
* specified algorithm.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final ExemptionMechanism getInstance(String algorithm)
|
||||
throws NoSuchAlgorithmException {
|
||||
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}/../technotes/guides/security/StandardNames.html#Exemption">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard exemption mechanism names.
|
||||
*
|
||||
* @param provider the name of the provider.
|
||||
*
|
||||
* @return the new <code>ExemptionMechanism</code> object.
|
||||
*
|
||||
* @exception NullPointerException if <code>algorithm</code>
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if an ExemptionMechanismSpi
|
||||
* implementation for the specified algorithm is not
|
||||
* available from the specified provider.
|
||||
*
|
||||
* @exception NoSuchProviderException if the specified provider is not
|
||||
* registered in the security provider list.
|
||||
*
|
||||
* @exception IllegalArgumentException if the <code>provider</code>
|
||||
* is null or empty.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final ExemptionMechanism getInstance(String algorithm,
|
||||
String provider) throws NoSuchAlgorithmException,
|
||||
NoSuchProviderException {
|
||||
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}/../technotes/guides/security/StandardNames.html#Exemption">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard exemption mechanism names.
|
||||
*
|
||||
* @param provider the provider.
|
||||
*
|
||||
* @return the new <code>ExemptionMechanism</code> object.
|
||||
*
|
||||
* @exception NullPointerException if <code>algorithm</code>
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if an ExemptionMechanismSpi
|
||||
* implementation for the specified algorithm is not available
|
||||
* from the specified Provider object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the <code>provider</code>
|
||||
* is null.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final ExemptionMechanism getInstance(String algorithm,
|
||||
Provider provider) throws NoSuchAlgorithmException {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the key stored away by this ExemptionMechanism
|
||||
* object will be wiped out when there are no more references to it.
|
||||
*/
|
||||
protected void finalize() {
|
||||
keyStored = null;
|
||||
// Are there anything else we could do?
|
||||
}
|
||||
}
|
||||
59
jdkSrc/jdk8/javax/crypto/ExemptionMechanismException.java
Normal file
59
jdkSrc/jdk8/javax/crypto/ExemptionMechanismException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
170
jdkSrc/jdk8/javax/crypto/ExemptionMechanismSpi.java
Normal file
170
jdkSrc/jdk8/javax/crypto/ExemptionMechanismSpi.java
Normal 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;
|
||||
}
|
||||
60
jdkSrc/jdk8/javax/crypto/IllegalBlockSizeException.java
Normal file
60
jdkSrc/jdk8/javax/crypto/IllegalBlockSizeException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
153
jdkSrc/jdk8/javax/crypto/JarVerifier.java
Normal file
153
jdkSrc/jdk8/javax/crypto/JarVerifier.java
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 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.io.*;
|
||||
import java.net.*;
|
||||
import java.security.*;
|
||||
import java.util.jar.*;
|
||||
|
||||
/**
|
||||
* This class verifies 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 JarVerifier {
|
||||
|
||||
// The URL for the JAR file we want to verify.
|
||||
private URL jarURL;
|
||||
private boolean savePerms;
|
||||
private CryptoPermissions appPerms = null;
|
||||
|
||||
/**
|
||||
* Creates a JarVerifier 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
|
||||
*/
|
||||
JarVerifier(URL jarURL, boolean savePerms) {
|
||||
this.jarURL = jarURL;
|
||||
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 JarException, 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);
|
||||
}
|
||||
|
||||
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 the permissions which are bundled with the JAR file,
|
||||
* aka the "cryptoperms" file.
|
||||
*
|
||||
* NOTE: if this JarVerifier instance is constructed with "savePerms"
|
||||
* equal to false, then this method would always return null.
|
||||
*/
|
||||
CryptoPermissions getPermissions() {
|
||||
return appPerms;
|
||||
}
|
||||
}
|
||||
396
jdkSrc/jdk8/javax/crypto/JceSecurity.java
Normal file
396
jdkSrc/jdk8/javax/crypto/JceSecurity.java
Normal file
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* 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.util.jar.*;
|
||||
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 {
|
||||
|
||||
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 final static Map<Provider, Object> verificationResults =
|
||||
new IdentityHashMap<>();
|
||||
|
||||
// Map<Provider,?> of the providers currently being verified
|
||||
private final static Map<Provider, Object> verifyingProviders =
|
||||
new IdentityHashMap<>();
|
||||
|
||||
private static final boolean isRestricted;
|
||||
|
||||
private static final Debug debug =
|
||||
Debug.getInstance("jca", "Cipher");
|
||||
|
||||
/*
|
||||
* Don't let anyone instantiate this.
|
||||
*/
|
||||
private JceSecurity() {
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Object>() {
|
||||
public Object 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 {
|
||||
JarVerifier jv = new JarVerifier(codeBase, true);
|
||||
jv.verify();
|
||||
return jv.getPermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if the JAR at URL codeBase is a signed provider JAR file.
|
||||
*
|
||||
* @throws Exception on error
|
||||
*/
|
||||
static void verifyProviderJar(URL codeBase) throws Exception {
|
||||
// Verify the provider JAR file and all
|
||||
// supporting JAR files if there are any.
|
||||
JarVerifier jv = new JarVerifier(codeBase, false);
|
||||
jv.verify();
|
||||
}
|
||||
|
||||
private final static 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());
|
||||
verifyProviderJar(providerURL);
|
||||
// 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<URL>() {
|
||||
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.
|
||||
*
|
||||
* Following logic is used to decide what policy files are selected.
|
||||
*
|
||||
* If the new Security property (crypto.policy) is set in the
|
||||
* java.security file, or has been set dynamically using the
|
||||
* Security.setProperty() call before the JCE framework has
|
||||
* been initialized, that setting will be used.
|
||||
* Remember - this property is not defined by default. A conscious
|
||||
* user edit or an application call is required.
|
||||
*
|
||||
* Otherwise, if user has policy jar files installed in the legacy
|
||||
* <java-home>/lib/security/ directory, the JDK will honor whatever
|
||||
* setting is set by those policy files. (legacy/current behavior)
|
||||
*
|
||||
* If none of the above 2 conditions are met, the JDK will default
|
||||
* to using the unlimited crypto policy files found in the
|
||||
* <java-home>/lib/security/policy/unlimited/ directory
|
||||
*/
|
||||
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 javaHomeProperty = System.getProperty("java.home");
|
||||
String cryptoPolicyProperty = Security.getProperty("crypto.policy");
|
||||
Path cpPath = (cryptoPolicyProperty == null) ? null :
|
||||
Paths.get(cryptoPolicyProperty);
|
||||
|
||||
if ((cpPath != null) && ((cpPath.getNameCount() != 1) ||
|
||||
(cpPath.compareTo(cpPath.getFileName())) != 0)) {
|
||||
throw new SecurityException(
|
||||
"Invalid policy directory name format: " +
|
||||
cryptoPolicyProperty);
|
||||
}
|
||||
|
||||
if (cpPath == null) {
|
||||
// Security property is not set, use default path
|
||||
cpPath = Paths.get(javaHomeProperty, "lib", "security");
|
||||
} else {
|
||||
// populate with java.home
|
||||
cpPath = Paths.get(javaHomeProperty, "lib", "security",
|
||||
"policy", cryptoPolicyProperty);
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("crypto policy directory: " + cpPath);
|
||||
}
|
||||
|
||||
File exportJar = new File(cpPath.toFile(),"US_export_policy.jar");
|
||||
File importJar = new File(cpPath.toFile(),"local_policy.jar");
|
||||
|
||||
if (cryptoPolicyProperty == null && (!exportJar.exists() ||
|
||||
!importJar.exists())) {
|
||||
// Compatibility set up. If crypto.policy is not defined.
|
||||
// check to see if legacy jars exist in lib directory. If
|
||||
// they don't exist, we default to unlimited policy mode.
|
||||
cpPath = Paths.get(
|
||||
javaHomeProperty, "lib", "security", "policy", "unlimited");
|
||||
// point to the new jar files in limited directory
|
||||
exportJar = new File(cpPath.toFile(),"US_export_policy.jar");
|
||||
importJar = new File(cpPath.toFile(),"local_policy.jar");
|
||||
}
|
||||
|
||||
URL jceCipherURL = ClassLoader.getSystemResource
|
||||
("javax/crypto/Cipher.class");
|
||||
|
||||
if ((jceCipherURL == null) ||
|
||||
!exportJar.exists() || !importJar.exists()) {
|
||||
throw new SecurityException
|
||||
("Cannot locate policy or framework files!");
|
||||
}
|
||||
|
||||
// Read jurisdiction policies.
|
||||
CryptoPermissions defaultExport = new CryptoPermissions();
|
||||
CryptoPermissions exemptExport = new CryptoPermissions();
|
||||
loadPolicies(exportJar, defaultExport, exemptExport);
|
||||
|
||||
CryptoPermissions defaultImport = new CryptoPermissions();
|
||||
CryptoPermissions exemptImport = new CryptoPermissions();
|
||||
loadPolicies(importJar, defaultImport, exemptImport);
|
||||
|
||||
// Merge the export and import policies for default applications.
|
||||
if (defaultExport.isEmpty() || defaultImport.isEmpty()) {
|
||||
throw new SecurityException("Missing mandatory jurisdiction " +
|
||||
"policy files");
|
||||
}
|
||||
defaultPolicy = defaultExport.getMinimum(defaultImport);
|
||||
|
||||
// Merge the export and import policies for exempt applications.
|
||||
if (exemptExport.isEmpty()) {
|
||||
exemptPolicy = exemptImport.isEmpty() ? null : exemptImport;
|
||||
} else {
|
||||
exemptPolicy = exemptExport.getMinimum(exemptImport);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the policies from the specified file. Also checks that the
|
||||
* policies are correctly signed.
|
||||
*/
|
||||
private static void loadPolicies(File jarPathName,
|
||||
CryptoPermissions defaultPolicy,
|
||||
CryptoPermissions exemptPolicy)
|
||||
throws Exception {
|
||||
|
||||
JarFile jf = new JarFile(jarPathName);
|
||||
|
||||
Enumeration<JarEntry> entries = jf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry je = entries.nextElement();
|
||||
InputStream is = null;
|
||||
try {
|
||||
if (je.getName().startsWith("default_")) {
|
||||
is = jf.getInputStream(je);
|
||||
defaultPolicy.load(is);
|
||||
} else if (je.getName().startsWith("exempt_")) {
|
||||
is = jf.getInputStream(je);
|
||||
exemptPolicy.load(is);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} finally {
|
||||
if (is != null) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce the signer restraint, i.e. signer of JCE framework
|
||||
// jar should also be the signer of the two jurisdiction policy
|
||||
// jar files.
|
||||
JarVerifier.verifyPolicySigned(je.getCertificates());
|
||||
}
|
||||
// Close and nullify the JarFile reference to help GC.
|
||||
jf.close();
|
||||
jf = null;
|
||||
}
|
||||
|
||||
static CryptoPermissions getDefaultPolicy() {
|
||||
return defaultPolicy;
|
||||
}
|
||||
|
||||
static CryptoPermissions getExemptPolicy() {
|
||||
return exemptPolicy;
|
||||
}
|
||||
|
||||
static boolean isRestricted() {
|
||||
return isRestricted;
|
||||
}
|
||||
}
|
||||
259
jdkSrc/jdk8/javax/crypto/JceSecurityManager.java
Normal file
259
jdkSrc/jdk8/javax/crypto/JceSecurityManager.java
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.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<JceSecurityManager>() {
|
||||
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();
|
||||
}
|
||||
|
||||
// See bug 4341369 & 4334690 for more info.
|
||||
boolean isCallerTrusted() {
|
||||
// Get the caller and its codebase.
|
||||
Class<?>[] context = getClassContext();
|
||||
URL callerCodeBase = null;
|
||||
int i;
|
||||
for (i=0; i<context.length; i++) {
|
||||
callerCodeBase = JceSecurity.getCodeBase(context[i]);
|
||||
if (callerCodeBase != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// The caller is in the JCE framework.
|
||||
if (i == context.length) {
|
||||
return true;
|
||||
}
|
||||
//The caller has been verified.
|
||||
if (TrustedCallersCache.contains(context[i])) {
|
||||
return true;
|
||||
}
|
||||
// Check whether the caller is a trusted provider.
|
||||
try {
|
||||
JceSecurity.verifyProviderJar(callerCodeBase);
|
||||
} catch (Exception e2) {
|
||||
return false;
|
||||
}
|
||||
TrustedCallersCache.addElement(context[i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
650
jdkSrc/jdk8/javax/crypto/KeyAgreement.java
Normal file
650
jdkSrc/jdk8/javax/crypto/KeyAgreement.java
Normal file
@@ -0,0 +1,650 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package 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}/../technotes/guides/security/StandardNames.html#KeyAgreement">
|
||||
* KeyAgreement section</a> of the
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation.
|
||||
* 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.
|
||||
*
|
||||
* @param algorithm the standard name of the requested key agreement
|
||||
* algorithm.
|
||||
* See the KeyAgreement section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyAgreement">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return the new {@code KeyAgreement} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no Provider supports a
|
||||
* KeyAgreementSpi implementation for the
|
||||
* specified algorithm.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final KeyAgreement getInstance(String algorithm)
|
||||
throws NoSuchAlgorithmException {
|
||||
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}/../technotes/guides/security/StandardNames.html#KeyAgreement">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the name of the provider.
|
||||
*
|
||||
* @return the new {@code KeyAgreement} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a KeyAgreementSpi
|
||||
* implementation for the specified algorithm is not
|
||||
* available from the specified provider.
|
||||
*
|
||||
* @exception NoSuchProviderException if the specified provider is not
|
||||
* registered in the security provider list.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null or empty.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final KeyAgreement getInstance(String algorithm,
|
||||
String provider) throws NoSuchAlgorithmException,
|
||||
NoSuchProviderException {
|
||||
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}/../technotes/guides/security/StandardNames.html#KeyAgreement">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the provider.
|
||||
*
|
||||
* @return the new {@code KeyAgreement} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a KeyAgreementSpi
|
||||
* implementation for the specified algorithm is not available
|
||||
* from the specified Provider object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final KeyAgreement getInstance(String algorithm,
|
||||
Provider provider) throws NoSuchAlgorithmException {
|
||||
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 final static int I_NO_PARAMS = 1;
|
||||
private final static 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: " +
|
||||
this.provider.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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: " +
|
||||
this.provider.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
204
jdkSrc/jdk8/javax/crypto/KeyAgreementSpi.java
Normal file
204
jdkSrc/jdk8/javax/crypto/KeyAgreementSpi.java
Normal 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;
|
||||
}
|
||||
556
jdkSrc/jdk8/javax/crypto/KeyGenerator.java
Normal file
556
jdkSrc/jdk8/javax/crypto/KeyGenerator.java
Normal file
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package 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.
|
||||
*
|
||||
* <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}/../technotes/guides/security/StandardNames.html#KeyGenerator">
|
||||
* KeyGenerator section</a> of the
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation.
|
||||
* 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 final static int I_NONE = 1;
|
||||
private final static int I_RANDOM = 2;
|
||||
private final static int I_PARAMS = 3;
|
||||
private final static 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: " +
|
||||
this.provider.getName());
|
||||
}
|
||||
}
|
||||
|
||||
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: " +
|
||||
this.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.
|
||||
*
|
||||
* @param algorithm the standard name of the requested key algorithm.
|
||||
* See the KeyGenerator section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return the new {@code KeyGenerator} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no Provider supports a
|
||||
* KeyGeneratorSpi implementation for the
|
||||
* specified algorithm.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final KeyGenerator getInstance(String algorithm)
|
||||
throws NoSuchAlgorithmException {
|
||||
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}/../technotes/guides/security/StandardNames.html#KeyGenerator">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the name of the provider.
|
||||
*
|
||||
* @return the new {@code KeyGenerator} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a KeyGeneratorSpi
|
||||
* implementation for the specified algorithm is not
|
||||
* available from the specified provider.
|
||||
*
|
||||
* @exception NoSuchProviderException if the specified provider is not
|
||||
* registered in the security provider list.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null or empty.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final KeyGenerator getInstance(String algorithm,
|
||||
String provider) throws NoSuchAlgorithmException,
|
||||
NoSuchProviderException {
|
||||
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}/../technotes/guides/security/StandardNames.html#KeyGenerator">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the provider.
|
||||
*
|
||||
* @return the new {@code KeyGenerator} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a KeyGeneratorSpi
|
||||
* implementation for the specified algorithm is not available
|
||||
* from the specified Provider object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final KeyGenerator getInstance(String algorithm,
|
||||
Provider provider) throws NoSuchAlgorithmException {
|
||||
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 implemenations 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;
|
||||
}
|
||||
}
|
||||
86
jdkSrc/jdk8/javax/crypto/KeyGeneratorSpi.java
Normal file
86
jdkSrc/jdk8/javax/crypto/KeyGeneratorSpi.java
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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>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.
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
672
jdkSrc/jdk8/javax/crypto/Mac.java
Normal file
672
jdkSrc/jdk8/javax/crypto/Mac.java
Normal file
@@ -0,0 +1,672 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package 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}/../technotes/guides/security/StandardNames.html#Mac">
|
||||
* Mac section</a> of the
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation.
|
||||
* 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.
|
||||
*
|
||||
* @param algorithm the standard name of the requested MAC algorithm.
|
||||
* See the Mac section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Mac">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return the new {@code Mac} object.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no Provider supports a
|
||||
* MacSpi implementation for the
|
||||
* specified algorithm.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final Mac getInstance(String algorithm)
|
||||
throws NoSuchAlgorithmException {
|
||||
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}/../technotes/guides/security/StandardNames.html#Mac">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the name of the provider.
|
||||
*
|
||||
* @return the new {@code Mac} object.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a MacSpi
|
||||
* implementation for the specified algorithm is not
|
||||
* available from the specified provider.
|
||||
*
|
||||
* @exception NoSuchProviderException if the specified provider is not
|
||||
* registered in the security provider list.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null or empty.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final Mac getInstance(String algorithm, String provider)
|
||||
throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
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}/../technotes/guides/security/StandardNames.html#Mac">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the provider.
|
||||
*
|
||||
* @return the new {@code Mac} object.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a MacSpi
|
||||
* implementation for the specified algorithm is not available
|
||||
* from the specified Provider object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final Mac getInstance(String algorithm, Provider provider)
|
||||
throws NoSuchAlgorithmException {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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: " +
|
||||
this.provider.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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: " +
|
||||
this.provider.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
153
jdkSrc/jdk8/javax/crypto/MacSpi.java
Normal file
153
jdkSrc/jdk8/javax/crypto/MacSpi.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
61
jdkSrc/jdk8/javax/crypto/NoSuchPaddingException.java
Normal file
61
jdkSrc/jdk8/javax/crypto/NoSuchPaddingException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
47
jdkSrc/jdk8/javax/crypto/NullCipher.java
Normal file
47
jdkSrc/jdk8/javax/crypto/NullCipher.java
Normal 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);
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/javax/crypto/NullCipherSpi.java
Normal file
113
jdkSrc/jdk8/javax/crypto/NullCipherSpi.java
Normal 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;
|
||||
}
|
||||
}
|
||||
488
jdkSrc/jdk8/javax/crypto/SealedObject.java
Normal file
488
jdkSrc/jdk8/javax/crypto/SealedObject.java
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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 sun.misc.SharedSecrets;
|
||||
|
||||
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
|
||||
{
|
||||
ObjectInput a = getExtObjectInputStream(c);
|
||||
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());
|
||||
}
|
||||
|
||||
ObjectInput a = getExtObjectInputStream(c);
|
||||
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();
|
||||
}
|
||||
|
||||
// This method is also called inside SealedObjectForKeyProtector.java.
|
||||
private ObjectInputStream getExtObjectInputStream(Cipher c)
|
||||
throws BadPaddingException, IllegalBlockSizeException, IOException {
|
||||
|
||||
byte[] content = c.doFinal(this.encryptedContent);
|
||||
ByteArrayInputStream b = new ByteArrayInputStream(content);
|
||||
return new extObjectInputStream(b);
|
||||
}
|
||||
|
||||
static {
|
||||
SharedSecrets.setJavaxCryptoSealedObjectAccess((obj,c) -> obj.getExtObjectInputStream(c));
|
||||
}
|
||||
}
|
||||
|
||||
final class extObjectInputStream extends ObjectInputStream {
|
||||
|
||||
private static ClassLoader systemClassLoader = null;
|
||||
|
||||
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) {
|
||||
if (systemClassLoader == null) {
|
||||
systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
loader = systemClassLoader;
|
||||
if (loader == null) {
|
||||
throw new ClassNotFoundException(v.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return Class.forName(v.getName(), false, loader);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
jdkSrc/jdk8/javax/crypto/SecretKey.java
Normal file
68
jdkSrc/jdk8/javax/crypto/SecretKey.java
Normal 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;
|
||||
}
|
||||
429
jdkSrc/jdk8/javax/crypto/SecretKeyFactory.java
Normal file
429
jdkSrc/jdk8/javax/crypto/SecretKeyFactory.java
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package 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}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
|
||||
* SecretKeyFactory section</a> of the
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation.
|
||||
* 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.
|
||||
*
|
||||
* @param algorithm the standard name of the requested secret-key
|
||||
* algorithm.
|
||||
* See the SecretKeyFactory section in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @return the new {@code SecretKeyFactory} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if no Provider supports a
|
||||
* SecretKeyFactorySpi implementation for the
|
||||
* specified algorithm.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final SecretKeyFactory getInstance(String algorithm)
|
||||
throws NoSuchAlgorithmException {
|
||||
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}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the name of the provider.
|
||||
*
|
||||
* @return the new {@code SecretKeyFactory} object.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a SecretKeyFactorySpi
|
||||
* implementation for the specified algorithm is not
|
||||
* available from the specified provider.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm
|
||||
* is null.
|
||||
*
|
||||
* @throws NoSuchProviderException if the specified provider is not
|
||||
* registered in the security provider list.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null or empty.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final SecretKeyFactory getInstance(String algorithm,
|
||||
String provider) throws NoSuchAlgorithmException,
|
||||
NoSuchProviderException {
|
||||
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}/../technotes/guides/security/StandardNames.html#SecretKeyFactory">
|
||||
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
|
||||
* for information about standard algorithm names.
|
||||
*
|
||||
* @param provider the provider.
|
||||
*
|
||||
* @return the new {@code SecretKeyFactory} object.
|
||||
*
|
||||
* @exception NullPointerException if the specified algorithm
|
||||
* is null.
|
||||
*
|
||||
* @exception NoSuchAlgorithmException if a SecretKeyFactorySpi
|
||||
* implementation for the specified algorithm is not available
|
||||
* from the specified Provider object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the {@code provider}
|
||||
* is null.
|
||||
*
|
||||
* @see java.security.Provider
|
||||
*/
|
||||
public static final SecretKeyFactory getInstance(String algorithm,
|
||||
Provider provider) throws NoSuchAlgorithmException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
108
jdkSrc/jdk8/javax/crypto/SecretKeyFactorySpi.java
Normal file
108
jdkSrc/jdk8/javax/crypto/SecretKeyFactorySpi.java
Normal 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;
|
||||
}
|
||||
61
jdkSrc/jdk8/javax/crypto/ShortBufferException.java
Normal file
61
jdkSrc/jdk8/javax/crypto/ShortBufferException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
48
jdkSrc/jdk8/javax/crypto/interfaces/DHKey.java
Normal file
48
jdkSrc/jdk8/javax/crypto/interfaces/DHKey.java
Normal 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();
|
||||
}
|
||||
53
jdkSrc/jdk8/javax/crypto/interfaces/DHPrivateKey.java
Normal file
53
jdkSrc/jdk8/javax/crypto/interfaces/DHPrivateKey.java
Normal 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();
|
||||
}
|
||||
53
jdkSrc/jdk8/javax/crypto/interfaces/DHPublicKey.java
Normal file
53
jdkSrc/jdk8/javax/crypto/interfaces/DHPublicKey.java
Normal 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();
|
||||
}
|
||||
75
jdkSrc/jdk8/javax/crypto/interfaces/PBEKey.java
Normal file
75
jdkSrc/jdk8/javax/crypto/interfaces/PBEKey.java
Normal 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();
|
||||
}
|
||||
240
jdkSrc/jdk8/javax/crypto/spec/DESKeySpec.java
Normal file
240
jdkSrc/jdk8/javax/crypto/spec/DESKeySpec.java
Normal 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;
|
||||
}
|
||||
}
|
||||
126
jdkSrc/jdk8/javax/crypto/spec/DESedeKeySpec.java
Normal file
126
jdkSrc/jdk8/javax/crypto/spec/DESedeKeySpec.java
Normal 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;
|
||||
}
|
||||
}
|
||||
85
jdkSrc/jdk8/javax/crypto/spec/DHGenParameterSpec.java
Normal file
85
jdkSrc/jdk8/javax/crypto/spec/DHGenParameterSpec.java
Normal 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;
|
||||
}
|
||||
}
|
||||
123
jdkSrc/jdk8/javax/crypto/spec/DHParameterSpec.java
Normal file
123
jdkSrc/jdk8/javax/crypto/spec/DHParameterSpec.java
Normal 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;
|
||||
}
|
||||
}
|
||||
93
jdkSrc/jdk8/javax/crypto/spec/DHPrivateKeySpec.java
Normal file
93
jdkSrc/jdk8/javax/crypto/spec/DHPrivateKeySpec.java
Normal 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;
|
||||
}
|
||||
}
|
||||
93
jdkSrc/jdk8/javax/crypto/spec/DHPublicKeySpec.java
Normal file
93
jdkSrc/jdk8/javax/crypto/spec/DHPublicKeySpec.java
Normal 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;
|
||||
}
|
||||
}
|
||||
149
jdkSrc/jdk8/javax/crypto/spec/GCMParameterSpec.java
Normal file
149
jdkSrc/jdk8/javax/crypto/spec/GCMParameterSpec.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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 > (src.length - offset))) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
102
jdkSrc/jdk8/javax/crypto/spec/IvParameterSpec.java
Normal file
102
jdkSrc/jdk8/javax/crypto/spec/IvParameterSpec.java
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, 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 (offset < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("offset is negative");
|
||||
}
|
||||
if (len < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("len is negative");
|
||||
}
|
||||
if (iv.length - offset < len) {
|
||||
throw new IllegalArgumentException
|
||||
("IV buffer too short for given offset/length combination");
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
181
jdkSrc/jdk8/javax/crypto/spec/OAEPParameterSpec.java
Normal file
181
jdkSrc/jdk8/javax/crypto/spec/OAEPParameterSpec.java
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2020, 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="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
|
||||
*
|
||||
* Its ASN.1 definition in PKCS#1 standard is described below:
|
||||
* <pre>
|
||||
* RSAES-OAEP-params ::= SEQUENCE {
|
||||
* hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
|
||||
* maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
|
||||
* pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty
|
||||
* }
|
||||
* </pre>
|
||||
* where
|
||||
* <pre>
|
||||
* HashAlgorithm ::= AlgorithmIdentifier {
|
||||
* {OAEP-PSSDigestAlgorithms}
|
||||
* }
|
||||
* MaskGenAlgorithm ::= AlgorithmIdentifier { {PKCS1MGFAlgorithms} }
|
||||
* PSourceAlgorithm ::= AlgorithmIdentifier {
|
||||
* {PKCS1PSourceAlgorithms}
|
||||
* }
|
||||
*
|
||||
* OAEP-PSSDigestAlgorithms ALGORITHM-IDENTIFIER ::= {
|
||||
* { OID id-sha1 PARAMETERS NULL }|
|
||||
* { OID id-sha224 PARAMETERS NULL }|
|
||||
* { OID id-sha256 PARAMETERS NULL }|
|
||||
* { OID id-sha384 PARAMETERS NULL }|
|
||||
* { OID id-sha512 PARAMETERS NULL }|
|
||||
* { OID id-sha512-224 PARAMETERS NULL }|
|
||||
* { OID id-sha512-256 PARAMETERS NULL },
|
||||
* ... -- Allows for future expansion --
|
||||
* }
|
||||
* PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
|
||||
* { OID id-mgf1 PARAMETERS HashAlgorithm },
|
||||
* ... -- Allows for future expansion --
|
||||
* }
|
||||
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
|
||||
* { OID id-pSpecified PARAMETERS EncodingParameters },
|
||||
* ... -- Allows for future expansion --
|
||||
* }
|
||||
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
|
||||
* </pre>
|
||||
* <p>Note: the OAEPParameterSpec.DEFAULT uses the following:
|
||||
* <pre>
|
||||
* message digest -- "SHA-1"
|
||||
* mask generation function (mgf) -- "MGF1"
|
||||
* parameters for mgf -- MGF1ParameterSpec.SHA1
|
||||
* source of encoding input -- PSource.PSpecified.DEFAULT
|
||||
* </pre>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
239
jdkSrc/jdk8/javax/crypto/spec/PBEKeySpec.java
Normal file
239
jdkSrc/jdk8/javax/crypto/spec/PBEKeySpec.java
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
Arrays.fill(password, ' ');
|
||||
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;
|
||||
}
|
||||
}
|
||||
109
jdkSrc/jdk8/javax/crypto/spec/PBEParameterSpec.java
Normal file
109
jdkSrc/jdk8/javax/crypto/spec/PBEParameterSpec.java
Normal 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;
|
||||
}
|
||||
}
|
||||
114
jdkSrc/jdk8/javax/crypto/spec/PSource.java
Normal file
114
jdkSrc/jdk8/javax/crypto/spec/PSource.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2020, 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="https://tools.ietf.org/rfc/rfc8017.txt">PKCS#1 v2.2</a> standard.
|
||||
* <pre>
|
||||
* PSourceAlgorithm ::= AlgorithmIdentifier {
|
||||
* {PKCS1PSourceAlgorithms}
|
||||
* }
|
||||
* </pre>
|
||||
* where
|
||||
* <pre>
|
||||
* PKCS1PSourceAlgorithms ALGORITHM-IDENTIFIER ::= {
|
||||
* { OID id-pSpecified PARAMETERS EncodingParameters },
|
||||
* ... -- Allows for future expansion --
|
||||
* }
|
||||
* EncodingParameters ::= OCTET STRING(SIZE(0..MAX))
|
||||
* </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());
|
||||
}
|
||||
}
|
||||
}
|
||||
160
jdkSrc/jdk8/javax/crypto/spec/RC2ParameterSpec.java
Normal file
160
jdkSrc/jdk8/javax/crypto/spec/RC2ParameterSpec.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package 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);
|
||||
}
|
||||
}
|
||||
208
jdkSrc/jdk8/javax/crypto/spec/RC5ParameterSpec.java
Normal file
208
jdkSrc/jdk8/javax/crypto/spec/RC5ParameterSpec.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2021, 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/rfc2040.txt"><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.rsasecurity.com">RSA Security Inc.</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");
|
||||
}
|
||||
if (offset < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("offset is negative");
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
261
jdkSrc/jdk8/javax/crypto/spec/SecretKeySpec.java
Normal file
261
jdkSrc/jdk8/javax/crypto/spec/SecretKeySpec.java
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2023, 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.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
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 Appendix A in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* 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 Appendix A in the <a href=
|
||||
* "{@docRoot}/../technotes/guides/security/crypto/CryptoSpec.html#AppA">
|
||||
* Java Cryptography Architecture Reference Guide</a>
|
||||
* 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 (offset < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("offset is negative");
|
||||
}
|
||||
if (len < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("len is negative");
|
||||
}
|
||||
if (key.length - offset < len) {
|
||||
throw new IllegalArgumentException
|
||||
("Invalid offset/length combination");
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the state of this object from the stream.
|
||||
*
|
||||
* @param stream the {@code ObjectInputStream} from which data is read
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||
*/
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws IOException, ClassNotFoundException {
|
||||
stream.defaultReadObject();
|
||||
|
||||
if (key == null || algorithm == null) {
|
||||
throw new InvalidObjectException("Missing argument");
|
||||
}
|
||||
|
||||
this.key = key.clone();
|
||||
if (key.length == 0) {
|
||||
throw new InvalidObjectException("Invalid key length");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user