8187443: Forest Consolidation: Move files to unified layout

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

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Provides the implementation of the SunPKCS11 security provider.
*
* @provides java.security.Provider
*
* @moduleGraph
* @since 9
*/
module jdk.crypto.cryptoki {
// Depends on SunEC provider for EC related functionality
requires jdk.crypto.ec;
provides java.security.Provider with sun.security.pkcs11.SunPKCS11;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.util.*;
import java.lang.ref.*;
import java.security.Key;
import sun.security.util.Cache;
/**
* Key to P11Key translation cache. The PKCS#11 token can only perform
* operations on keys stored on the token (permanently or temporarily). That
* means that in order to allow the PKCS#11 provider to use keys from other
* providers, we need to transparently convert them to P11Keys. The engines
* do that using (Secret)KeyFactories, which in turn use this class as a
* cache.
*
* There are two KeyCache instances per provider, one for secret keys and
* one for public and private keys.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class KeyCache {
private final Cache<IdentityWrapper, P11Key> strongCache;
private WeakReference<Map<Key,P11Key>> cacheReference;
KeyCache() {
strongCache = Cache.newHardMemoryCache(16);
}
private static final class IdentityWrapper {
final Object obj;
IdentityWrapper(Object obj) {
this.obj = obj;
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof IdentityWrapper == false) {
return false;
}
IdentityWrapper other = (IdentityWrapper)o;
return this.obj == other.obj;
}
public int hashCode() {
return System.identityHashCode(obj);
}
}
synchronized P11Key get(Key key) {
P11Key p11Key = strongCache.get(new IdentityWrapper(key));
if (p11Key != null) {
return p11Key;
}
Map<Key,P11Key> map =
(cacheReference == null) ? null : cacheReference.get();
if (map == null) {
return null;
}
return map.get(key);
}
synchronized void put(Key key, P11Key p11Key) {
strongCache.put(new IdentityWrapper(key), p11Key);
Map<Key,P11Key> map =
(cacheReference == null) ? null : cacheReference.get();
if (map == null) {
map = new IdentityHashMap<>();
cacheReference = new WeakReference<>(map);
}
map.put(key, p11Key);
}
}

View file

@ -0,0 +1,929 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Locale;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import sun.nio.ch.DirectBuffer;
import sun.security.jca.JCAUtil;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* Cipher implementation class. This class currently supports
* DES, DESede, AES, ARCFOUR, and Blowfish.
*
* This class is designed to support ECB, CBC, CTR with NoPadding
* and ECB, CBC with PKCS5Padding. It will use its own padding impl
* if the native mechanism does not support padding.
*
* Note that PKCS#11 currently only supports ECB, CBC, and CTR.
* There are no provisions for other modes such as CFB, OFB, and PCBC.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11Cipher extends CipherSpi {
// mode constant for ECB mode
private final static int MODE_ECB = 3;
// mode constant for CBC mode
private final static int MODE_CBC = 4;
// mode constant for CTR mode
private final static int MODE_CTR = 5;
// padding constant for NoPadding
private final static int PAD_NONE = 5;
// padding constant for PKCS5Padding
private final static int PAD_PKCS5 = 6;
private static interface Padding {
// ENC: format the specified buffer with padding bytes and return the
// actual padding length
int setPaddingBytes(byte[] paddingBuffer, int padLen);
// DEC: return the length of trailing padding bytes given the specified
// padded data
int unpad(byte[] paddedData, int len)
throws BadPaddingException, IllegalBlockSizeException;
}
private static class PKCS5Padding implements Padding {
private final int blockSize;
PKCS5Padding(int blockSize)
throws NoSuchPaddingException {
if (blockSize == 0) {
throw new NoSuchPaddingException
("PKCS#5 padding not supported with stream ciphers");
}
this.blockSize = blockSize;
}
public int setPaddingBytes(byte[] paddingBuffer, int padLen) {
Arrays.fill(paddingBuffer, 0, padLen, (byte) (padLen & 0x007f));
return padLen;
}
public int unpad(byte[] paddedData, int len)
throws BadPaddingException, IllegalBlockSizeException {
if ((len < 1) || (len % blockSize != 0)) {
throw new IllegalBlockSizeException
("Input length must be multiples of " + blockSize);
}
byte padValue = paddedData[len - 1];
if (padValue < 1 || padValue > blockSize) {
throw new BadPaddingException("Invalid pad value!");
}
// sanity check padding bytes
int padStartIndex = len - padValue;
for (int i = padStartIndex; i < len; i++) {
if (paddedData[i] != padValue) {
throw new BadPaddingException("Invalid pad bytes!");
}
}
return padValue;
}
}
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// name of the key algorithm, e.g. DES instead of algorithm DES/CBC/...
private final String keyAlgorithm;
// mechanism id
private final long mechanism;
// associated session, if any
private Session session;
// key, if init() was called
private P11Key p11Key;
// flag indicating whether an operation is initialized
private boolean initialized;
// falg indicating encrypt or decrypt mode
private boolean encrypt;
// mode, one of MODE_* above (MODE_ECB for stream ciphers)
private int blockMode;
// block size, 0 for stream ciphers
private final int blockSize;
// padding type, on of PAD_* above (PAD_NONE for stream ciphers)
private int paddingType;
// when the padding is requested but unsupported by the native mechanism,
// we use the following to do padding and necessary data buffering.
// padding object which generate padding and unpad the decrypted data
private Padding paddingObj;
// buffer for holding back the block which contains padding bytes
private byte[] padBuffer;
private int padBufferLen;
// original IV, if in MODE_CBC or MODE_CTR
private byte[] iv;
// number of bytes buffered internally by the native mechanism and padBuffer
// if we do the padding
private int bytesBuffered;
// length of key size in bytes; currently only used by AES given its oid
// specification mandates a fixed size of the key
private int fixedKeySize = -1;
P11Cipher(Token token, String algorithm, long mechanism)
throws PKCS11Exception, NoSuchAlgorithmException {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
String[] algoParts = algorithm.split("/");
if (algoParts[0].startsWith("AES")) {
blockSize = 16;
int index = algoParts[0].indexOf('_');
if (index != -1) {
// should be well-formed since we specify what we support
fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1))/8;
}
keyAlgorithm = "AES";
} else {
keyAlgorithm = algoParts[0];
if (keyAlgorithm.equals("RC4") ||
keyAlgorithm.equals("ARCFOUR")) {
blockSize = 0;
} else { // DES, DESede, Blowfish
blockSize = 8;
}
}
this.blockMode =
(algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
String paddingStr =
(algoParts.length > 2 ? algoParts[2] : defPadding);
try {
engineSetPadding(paddingStr);
} catch (NoSuchPaddingException nspe) {
// should not happen
throw new ProviderException(nspe);
}
}
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
// Disallow change of mode for now since currently it's explicitly
// defined in transformation strings
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
}
private int parseMode(String mode) throws NoSuchAlgorithmException {
mode = mode.toUpperCase(Locale.ENGLISH);
int result;
if (mode.equals("ECB")) {
result = MODE_ECB;
} else if (mode.equals("CBC")) {
if (blockSize == 0) {
throw new NoSuchAlgorithmException
("CBC mode not supported with stream ciphers");
}
result = MODE_CBC;
} else if (mode.equals("CTR")) {
result = MODE_CTR;
} else {
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
}
return result;
}
// see JCE spec
protected void engineSetPadding(String padding)
throws NoSuchPaddingException {
paddingObj = null;
padBuffer = null;
padding = padding.toUpperCase(Locale.ENGLISH);
if (padding.equals("NOPADDING")) {
paddingType = PAD_NONE;
} else if (padding.equals("PKCS5PADDING")) {
if (this.blockMode == MODE_CTR) {
throw new NoSuchPaddingException
("PKCS#5 padding not supported with CTR mode");
}
paddingType = PAD_PKCS5;
if (mechanism != CKM_DES_CBC_PAD && mechanism != CKM_DES3_CBC_PAD &&
mechanism != CKM_AES_CBC_PAD) {
// no native padding support; use our own padding impl
paddingObj = new PKCS5Padding(blockSize);
padBuffer = new byte[blockSize];
}
} else {
throw new NoSuchPaddingException("Unsupported padding " + padding);
}
}
// see JCE spec
protected int engineGetBlockSize() {
return blockSize;
}
// see JCE spec
protected int engineGetOutputSize(int inputLen) {
return doFinalLength(inputLen);
}
// see JCE spec
protected byte[] engineGetIV() {
return (iv == null) ? null : iv.clone();
}
// see JCE spec
protected AlgorithmParameters engineGetParameters() {
if (iv == null) {
return null;
}
IvParameterSpec ivSpec = new IvParameterSpec(iv);
try {
AlgorithmParameters params =
AlgorithmParameters.getInstance(keyAlgorithm,
P11Util.getSunJceProvider());
params.init(ivSpec);
return params;
} catch (GeneralSecurityException e) {
// NoSuchAlgorithmException, NoSuchProviderException
// InvalidParameterSpecException
throw new ProviderException("Could not encode parameters", e);
}
}
// see JCE spec
protected void engineInit(int opmode, Key key, SecureRandom random)
throws InvalidKeyException {
try {
implInit(opmode, key, null, random);
} catch (InvalidAlgorithmParameterException e) {
throw new InvalidKeyException("init() failed", e);
}
}
// see JCE spec
protected void engineInit(int opmode, Key key,
AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
byte[] ivValue;
if (params != null) {
if (params instanceof IvParameterSpec == false) {
throw new InvalidAlgorithmParameterException
("Only IvParameterSpec supported");
}
IvParameterSpec ivSpec = (IvParameterSpec) params;
ivValue = ivSpec.getIV();
} else {
ivValue = null;
}
implInit(opmode, key, ivValue, random);
}
// see JCE spec
protected void engineInit(int opmode, Key key, AlgorithmParameters params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
byte[] ivValue;
if (params != null) {
try {
IvParameterSpec ivSpec =
params.getParameterSpec(IvParameterSpec.class);
ivValue = ivSpec.getIV();
} catch (InvalidParameterSpecException e) {
throw new InvalidAlgorithmParameterException
("Could not decode IV", e);
}
} else {
ivValue = null;
}
implInit(opmode, key, ivValue, random);
}
// actual init() implementation
private void implInit(int opmode, Key key, byte[] iv,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
reset(true);
if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
throw new InvalidKeyException("Key size is invalid");
}
switch (opmode) {
case Cipher.ENCRYPT_MODE:
encrypt = true;
break;
case Cipher.DECRYPT_MODE:
encrypt = false;
break;
default:
throw new InvalidAlgorithmParameterException
("Unsupported mode: " + opmode);
}
if (blockMode == MODE_ECB) { // ECB or stream cipher
if (iv != null) {
if (blockSize == 0) {
throw new InvalidAlgorithmParameterException
("IV not used with stream ciphers");
} else {
throw new InvalidAlgorithmParameterException
("IV not used in ECB mode");
}
}
} else { // MODE_CBC or MODE_CTR
if (iv == null) {
if (encrypt == false) {
String exMsg =
(blockMode == MODE_CBC ?
"IV must be specified for decryption in CBC mode" :
"IV must be specified for decryption in CTR mode");
throw new InvalidAlgorithmParameterException(exMsg);
}
// generate random IV
if (random == null) {
random = JCAUtil.getSecureRandom();
}
iv = new byte[blockSize];
random.nextBytes(iv);
} else {
if (iv.length != blockSize) {
throw new InvalidAlgorithmParameterException
("IV length must match block size");
}
}
}
this.iv = iv;
p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm);
try {
initialize();
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not initialize cipher", e);
}
}
private void cancelOperation() {
if (initialized == false) {
return;
}
if ((session == null) || (token.explicitCancel == false)) {
return;
}
try {
if (session.hasObjects() == false) {
session = token.killSession(session);
return;
} else {
// cancel operation by finishing it
int bufLen = doFinalLength(0);
byte[] buffer = new byte[bufLen];
if (encrypt) {
token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
} else {
token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
}
}
} catch (PKCS11Exception e) {
throw new ProviderException("Cancel failed", e);
}
}
private void ensureInitialized() throws PKCS11Exception {
if (initialized == false) {
initialize();
}
}
private void initialize() throws PKCS11Exception {
if (session == null) {
session = token.getOpSession();
}
CK_MECHANISM mechParams = (blockMode == MODE_CTR?
new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) :
new CK_MECHANISM(mechanism, iv));
try {
if (encrypt) {
token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID);
} else {
token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID);
}
} catch (PKCS11Exception ex) {
// release session when initialization failed
session = token.releaseSession(session);
throw ex;
}
bytesBuffered = 0;
padBufferLen = 0;
initialized = true;
}
// if update(inLen) is called, how big does the output buffer have to be?
private int updateLength(int inLen) {
if (inLen <= 0) {
return 0;
}
int result = inLen + bytesBuffered;
if (blockSize != 0 && blockMode != MODE_CTR) {
// minus the number of bytes in the last incomplete block.
result -= (result & (blockSize - 1));
}
return result;
}
// if doFinal(inLen) is called, how big does the output buffer have to be?
private int doFinalLength(int inLen) {
if (inLen < 0) {
return 0;
}
int result = inLen + bytesBuffered;
if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
// add the number of bytes to make the last block complete.
result += (blockSize - (result & (blockSize - 1)));
}
return result;
}
// reset the states to the pre-initialized values
private void reset(boolean doCancel) {
if (doCancel) cancelOperation();
initialized = false;
bytesBuffered = 0;
padBufferLen = 0;
if (session != null) {
session = token.releaseSession(session);
}
}
// see JCE spec
protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
try {
byte[] out = new byte[updateLength(inLen)];
int n = engineUpdate(in, inOfs, inLen, out, 0);
return P11Util.convert(out, 0, n);
} catch (ShortBufferException e) {
// convert since the output length is calculated by updateLength()
throw new ProviderException(e);
}
}
// see JCE spec
protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
int outOfs) throws ShortBufferException {
int outLen = out.length - outOfs;
return implUpdate(in, inOfs, inLen, out, outOfs, outLen);
}
// see JCE spec
@Override
protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
throws ShortBufferException {
return implUpdate(inBuffer, outBuffer);
}
// see JCE spec
protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
throws IllegalBlockSizeException, BadPaddingException {
try {
byte[] out = new byte[doFinalLength(inLen)];
int n = engineDoFinal(in, inOfs, inLen, out, 0);
return P11Util.convert(out, 0, n);
} catch (ShortBufferException e) {
// convert since the output length is calculated by doFinalLength()
throw new ProviderException(e);
}
}
// see JCE spec
protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
int outOfs) throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
int n = 0;
if ((inLen != 0) && (in != null)) {
n = engineUpdate(in, inOfs, inLen, out, outOfs);
outOfs += n;
}
n += implDoFinal(out, outOfs, out.length - outOfs);
return n;
}
// see JCE spec
@Override
protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
int n = engineUpdate(inBuffer, outBuffer);
n += implDoFinal(outBuffer);
return n;
}
private int implUpdate(byte[] in, int inOfs, int inLen,
byte[] out, int outOfs, int outLen) throws ShortBufferException {
if (outLen < updateLength(inLen)) {
throw new ShortBufferException();
}
try {
ensureInitialized();
int k = 0;
if (encrypt) {
k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
0, out, outOfs, outLen);
} else {
int newPadBufferLen = 0;
if (paddingObj != null) {
if (padBufferLen != 0) {
// NSS throws up when called with data not in multiple
// of blocks. Try to work around this by holding the
// extra data in padBuffer.
if (padBufferLen != padBuffer.length) {
int bufCapacity = padBuffer.length - padBufferLen;
if (inLen > bufCapacity) {
bufferInputBytes(in, inOfs, bufCapacity);
inOfs += bufCapacity;
inLen -= bufCapacity;
} else {
bufferInputBytes(in, inOfs, inLen);
return 0;
}
}
k = token.p11.C_DecryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
0, out, outOfs, outLen);
padBufferLen = 0;
}
newPadBufferLen = inLen & (blockSize - 1);
if (newPadBufferLen == 0) {
newPadBufferLen = padBuffer.length;
}
inLen -= newPadBufferLen;
}
if (inLen > 0) {
k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
inLen, 0, out, (outOfs + k), (outLen - k));
}
// update 'padBuffer' if using our own padding impl.
if (paddingObj != null) {
bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
}
}
bytesBuffered += (inLen - k);
return k;
} catch (PKCS11Exception e) {
if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
}
reset(false);
throw new ProviderException("update() failed", e);
}
}
private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
throws ShortBufferException {
int inLen = inBuffer.remaining();
if (inLen <= 0) {
return 0;
}
int outLen = outBuffer.remaining();
if (outLen < updateLength(inLen)) {
throw new ShortBufferException();
}
int origPos = inBuffer.position();
try {
ensureInitialized();
long inAddr = 0;
int inOfs = 0;
byte[] inArray = null;
if (inBuffer instanceof DirectBuffer) {
inAddr = ((DirectBuffer) inBuffer).address();
inOfs = origPos;
} else if (inBuffer.hasArray()) {
inArray = inBuffer.array();
inOfs = (origPos + inBuffer.arrayOffset());
}
long outAddr = 0;
int outOfs = 0;
byte[] outArray = null;
if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = (outBuffer.position() + outBuffer.arrayOffset());
} else {
outArray = new byte[outLen];
}
}
int k = 0;
if (encrypt) {
if (inAddr == 0 && inArray == null) {
inArray = new byte[inLen];
inBuffer.get(inArray);
} else {
inBuffer.position(origPos + inLen);
}
k = token.p11.C_EncryptUpdate(session.id(),
inAddr, inArray, inOfs, inLen,
outAddr, outArray, outOfs, outLen);
} else {
int newPadBufferLen = 0;
if (paddingObj != null) {
if (padBufferLen != 0) {
// NSS throws up when called with data not in multiple
// of blocks. Try to work around this by holding the
// extra data in padBuffer.
if (padBufferLen != padBuffer.length) {
int bufCapacity = padBuffer.length - padBufferLen;
if (inLen > bufCapacity) {
bufferInputBytes(inBuffer, bufCapacity);
inOfs += bufCapacity;
inLen -= bufCapacity;
} else {
bufferInputBytes(inBuffer, inLen);
return 0;
}
}
k = token.p11.C_DecryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, outAddr, outArray,
outOfs, outLen);
padBufferLen = 0;
}
newPadBufferLen = inLen & (blockSize - 1);
if (newPadBufferLen == 0) {
newPadBufferLen = padBuffer.length;
}
inLen -= newPadBufferLen;
}
if (inLen > 0) {
if (inAddr == 0 && inArray == null) {
inArray = new byte[inLen];
inBuffer.get(inArray);
} else {
inBuffer.position(inBuffer.position() + inLen);
}
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
inArray, inOfs, inLen, outAddr, outArray,
(outOfs + k), (outLen - k));
}
// update 'padBuffer' if using our own padding impl.
if (paddingObj != null && newPadBufferLen != 0) {
bufferInputBytes(inBuffer, newPadBufferLen);
}
}
bytesBuffered += (inLen - k);
if (!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray()) {
outBuffer.put(outArray, outOfs, k);
} else {
outBuffer.position(outBuffer.position() + k);
}
return k;
} catch (PKCS11Exception e) {
// Reset input buffer to its original position for
inBuffer.position(origPos);
if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
}
reset(false);
throw new ProviderException("update() failed", e);
}
}
private int implDoFinal(byte[] out, int outOfs, int outLen)
throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
int requiredOutLen = doFinalLength(0);
if (outLen < requiredOutLen) {
throw new ShortBufferException();
}
boolean doCancel = true;
try {
ensureInitialized();
int k = 0;
if (encrypt) {
if (paddingObj != null) {
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
requiredOutLen - bytesBuffered);
k = token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, actualPadLen,
0, out, outOfs, outLen);
}
k += token.p11.C_EncryptFinal(session.id(),
0, out, (outOfs + k), (outLen - k));
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (bytesBuffered == 0 && padBufferLen == 0) {
return 0;
}
if (paddingObj != null) {
if (padBufferLen != 0) {
k = token.p11.C_DecryptUpdate(session.id(), 0,
padBuffer, 0, padBufferLen, 0, padBuffer, 0,
padBuffer.length);
}
k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
padBuffer.length - k);
doCancel = false;
int actualPadLen = paddingObj.unpad(padBuffer, k);
k -= actualPadLen;
System.arraycopy(padBuffer, 0, out, outOfs, k);
} else {
k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
outLen);
doCancel = false;
}
}
return k;
} catch (PKCS11Exception e) {
doCancel = false;
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
reset(doCancel);
}
}
private int implDoFinal(ByteBuffer outBuffer)
throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
int outLen = outBuffer.remaining();
int requiredOutLen = doFinalLength(0);
if (outLen < requiredOutLen) {
throw new ShortBufferException();
}
boolean doCancel = true;
try {
ensureInitialized();
long outAddr = 0;
byte[] outArray = null;
int outOfs = 0;
if (outBuffer instanceof DirectBuffer) {
outAddr = ((DirectBuffer) outBuffer).address();
outOfs = outBuffer.position();
} else {
if (outBuffer.hasArray()) {
outArray = outBuffer.array();
outOfs = outBuffer.position() + outBuffer.arrayOffset();
} else {
outArray = new byte[outLen];
}
}
int k = 0;
if (encrypt) {
if (paddingObj != null) {
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
requiredOutLen - bytesBuffered);
k = token.p11.C_EncryptUpdate(session.id(),
0, padBuffer, 0, actualPadLen,
outAddr, outArray, outOfs, outLen);
}
k += token.p11.C_EncryptFinal(session.id(),
outAddr, outArray, (outOfs + k), (outLen - k));
doCancel = false;
} else {
// Special handling to match SunJCE provider behavior
if (bytesBuffered == 0 && padBufferLen == 0) {
return 0;
}
if (paddingObj != null) {
if (padBufferLen != 0) {
k = token.p11.C_DecryptUpdate(session.id(),
0, padBuffer, 0, padBufferLen,
0, padBuffer, 0, padBuffer.length);
padBufferLen = 0;
}
k += token.p11.C_DecryptFinal(session.id(),
0, padBuffer, k, padBuffer.length - k);
doCancel = false;
int actualPadLen = paddingObj.unpad(padBuffer, k);
k -= actualPadLen;
outArray = padBuffer;
outOfs = 0;
} else {
k = token.p11.C_DecryptFinal(session.id(),
outAddr, outArray, outOfs, outLen);
doCancel = false;
}
}
if ((!encrypt && paddingObj != null) ||
(!(outBuffer instanceof DirectBuffer) &&
!outBuffer.hasArray())) {
outBuffer.put(outArray, outOfs, k);
} else {
outBuffer.position(outBuffer.position() + k);
}
return k;
} catch (PKCS11Exception e) {
doCancel = false;
handleException(e);
throw new ProviderException("doFinal() failed", e);
} finally {
reset(doCancel);
}
}
private void handleException(PKCS11Exception e)
throws ShortBufferException, IllegalBlockSizeException {
long errorCode = e.getErrorCode();
if (errorCode == CKR_BUFFER_TOO_SMALL) {
throw (ShortBufferException)
(new ShortBufferException().initCause(e));
} else if (errorCode == CKR_DATA_LEN_RANGE ||
errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
throw (IllegalBlockSizeException)
(new IllegalBlockSizeException(e.toString()).initCause(e));
}
}
// see JCE spec
protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
InvalidKeyException {
// XXX key wrapping
throw new UnsupportedOperationException("engineWrap()");
}
// see JCE spec
protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
int wrappedKeyType)
throws InvalidKeyException, NoSuchAlgorithmException {
// XXX key unwrapping
throw new UnsupportedOperationException("engineUnwrap()");
}
// see JCE spec
@Override
protected int engineGetKeySize(Key key) throws InvalidKeyException {
int n = P11SecretKeyFactory.convertKey
(token, key, keyAlgorithm).length();
return n;
}
private final void bufferInputBytes(byte[] in, int inOfs, int len) {
System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
padBufferLen += len;
bytesBuffered += len;
}
private final void bufferInputBytes(ByteBuffer inBuffer, int len) {
inBuffer.get(padBuffer, padBufferLen, len);
padBufferLen += len;
bytesBuffered += len;
}
}

View file

@ -0,0 +1,263 @@
/*
* Copyright (c) 2003, 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 sun.security.pkcs11;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import javax.crypto.interfaces.*;
import javax.crypto.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* DH KeyFactory implementation.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11DHKeyFactory extends P11KeyFactory {
P11DHKeyFactory(Token token, String algorithm) {
super(token, algorithm);
}
PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
try {
if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key;
DHParameterSpec params = dhKey.getParams();
return generatePublic(
dhKey.getY(),
params.getP(),
params.getG()
);
} else if ("X.509".equals(key.getFormat())) {
// let SunJCE provider parse for us, then recurse
try {
KeyFactory factory = implGetSoftwareFactory();
key = (PublicKey)factory.translateKey(key);
return implTranslatePublicKey(key);
} catch (GeneralSecurityException e) {
throw new InvalidKeyException("Could not translate key", e);
}
} else {
throw new InvalidKeyException("PublicKey must be instance "
+ "of DHPublicKey or have X.509 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create DH public key", e);
}
}
PrivateKey implTranslatePrivateKey(PrivateKey key)
throws InvalidKeyException {
try {
if (key instanceof DHPrivateKey) {
DHPrivateKey dhKey = (DHPrivateKey)key;
DHParameterSpec params = dhKey.getParams();
return generatePrivate(
dhKey.getX(),
params.getP(),
params.getG()
);
} else if ("PKCS#8".equals(key.getFormat())) {
// let SunJCE provider parse for us, then recurse
try {
KeyFactory factory = implGetSoftwareFactory();
key = (PrivateKey)factory.translateKey(key);
return implTranslatePrivateKey(key);
} catch (GeneralSecurityException e) {
throw new InvalidKeyException("Could not translate key", e);
}
} else {
throw new InvalidKeyException("PrivateKey must be instance "
+ "of DHPrivateKey or have PKCS#8 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create DH private key", e);
}
}
// see JCA spec
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof X509EncodedKeySpec) {
try {
KeyFactory factory = implGetSoftwareFactory();
PublicKey key = factory.generatePublic(keySpec);
return implTranslatePublicKey(key);
} catch (GeneralSecurityException e) {
throw new InvalidKeySpecException
("Could not create DH public key", e);
}
}
if (keySpec instanceof DHPublicKeySpec == false) {
throw new InvalidKeySpecException("Only DHPublicKeySpec and "
+ "X509EncodedKeySpec supported for DH public keys");
}
try {
DHPublicKeySpec ds = (DHPublicKeySpec)keySpec;
return generatePublic(
ds.getY(),
ds.getP(),
ds.getG()
);
} catch (PKCS11Exception e) {
throw new InvalidKeySpecException
("Could not create DH public key", e);
}
}
// see JCA spec
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof PKCS8EncodedKeySpec) {
try {
KeyFactory factory = implGetSoftwareFactory();
PrivateKey key = factory.generatePrivate(keySpec);
return implTranslatePrivateKey(key);
} catch (GeneralSecurityException e) {
throw new InvalidKeySpecException
("Could not create DH private key", e);
}
}
if (keySpec instanceof DHPrivateKeySpec == false) {
throw new InvalidKeySpecException("Only DHPrivateKeySpec and "
+ "PKCS8EncodedKeySpec supported for DH private keys");
}
try {
DHPrivateKeySpec ds = (DHPrivateKeySpec)keySpec;
return generatePrivate(
ds.getX(),
ds.getP(),
ds.getG()
);
} catch (PKCS11Exception e) {
throw new InvalidKeySpecException
("Could not create DH private key", e);
}
}
private PublicKey generatePublic(BigInteger y, BigInteger p, BigInteger g)
throws PKCS11Exception {
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
new CK_ATTRIBUTE(CKA_VALUE, y),
new CK_ATTRIBUTE(CKA_PRIME, p),
new CK_ATTRIBUTE(CKA_BASE, g),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PUBLIC_KEY, CKK_DH, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.publicKey
(session, keyID, "DH", p.bitLength(), attributes);
} finally {
token.releaseSession(session);
}
}
private PrivateKey generatePrivate(BigInteger x, BigInteger p,
BigInteger g) throws PKCS11Exception {
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
new CK_ATTRIBUTE(CKA_VALUE, x),
new CK_ATTRIBUTE(CKA_PRIME, p),
new CK_ATTRIBUTE(CKA_BASE, g),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PRIVATE_KEY, CKK_DH, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.privateKey
(session, keyID, "DH", p.bitLength(), attributes);
} finally {
token.releaseSession(session);
}
}
<T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (DHPublicKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
KeySpec spec = new DHPublicKeySpec(
attributes[0].getBigInteger(),
attributes[1].getBigInteger(),
attributes[2].getBigInteger()
);
return keySpec.cast(spec);
} else { // X.509 handled in superclass
throw new InvalidKeySpecException("Only DHPublicKeySpec and "
+ "X509EncodedKeySpec supported for DH public keys");
}
}
<T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (DHPrivateKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
KeySpec spec = new DHPrivateKeySpec(
attributes[0].getBigInteger(),
attributes[1].getBigInteger(),
attributes[2].getBigInteger()
);
return keySpec.cast(spec);
} else { // PKCS#8 handled in superclass
throw new InvalidKeySpecException("Only DHPrivateKeySpec "
+ "and PKCS8EncodedKeySpec supported for DH private keys");
}
}
KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
return KeyFactory.getInstance("DH", P11Util.getSunJceProvider());
}
}

View file

@ -0,0 +1,263 @@
/*
* Copyright (c) 2003, 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 sun.security.pkcs11;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* DSA KeyFactory implementation.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11DSAKeyFactory extends P11KeyFactory {
P11DSAKeyFactory(Token token, String algorithm) {
super(token, algorithm);
}
PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
try {
if (key instanceof DSAPublicKey) {
DSAPublicKey dsaKey = (DSAPublicKey)key;
DSAParams params = dsaKey.getParams();
return generatePublic(
dsaKey.getY(),
params.getP(),
params.getQ(),
params.getG()
);
} else if ("X.509".equals(key.getFormat())) {
// let Sun provider parse for us, then recurse
byte[] encoded = key.getEncoded();
key = new sun.security.provider.DSAPublicKey(encoded);
return implTranslatePublicKey(key);
} else {
throw new InvalidKeyException("PublicKey must be instance "
+ "of DSAPublicKey or have X.509 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create DSA public key", e);
}
}
PrivateKey implTranslatePrivateKey(PrivateKey key)
throws InvalidKeyException {
try {
if (key instanceof DSAPrivateKey) {
DSAPrivateKey dsaKey = (DSAPrivateKey)key;
DSAParams params = dsaKey.getParams();
return generatePrivate(
dsaKey.getX(),
params.getP(),
params.getQ(),
params.getG()
);
} else if ("PKCS#8".equals(key.getFormat())) {
// let Sun provider parse for us, then recurse
byte[] encoded = key.getEncoded();
key = new sun.security.provider.DSAPrivateKey(encoded);
return implTranslatePrivateKey(key);
} else {
throw new InvalidKeyException("PrivateKey must be instance "
+ "of DSAPrivateKey or have PKCS#8 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create DSA private key", e);
}
}
// see JCA spec
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof X509EncodedKeySpec) {
try {
byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
PublicKey key = new sun.security.provider.DSAPublicKey(encoded);
return implTranslatePublicKey(key);
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException
("Could not create DSA public key", e);
}
}
if (keySpec instanceof DSAPublicKeySpec == false) {
throw new InvalidKeySpecException("Only DSAPublicKeySpec and "
+ "X509EncodedKeySpec supported for DSA public keys");
}
try {
DSAPublicKeySpec ds = (DSAPublicKeySpec)keySpec;
return generatePublic(
ds.getY(),
ds.getP(),
ds.getQ(),
ds.getG()
);
} catch (PKCS11Exception e) {
throw new InvalidKeySpecException
("Could not create DSA public key", e);
}
}
// see JCA spec
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof PKCS8EncodedKeySpec) {
try {
byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
PrivateKey key = new sun.security.provider.DSAPrivateKey(encoded);
return implTranslatePrivateKey(key);
} catch (GeneralSecurityException e) {
throw new InvalidKeySpecException
("Could not create DSA private key", e);
}
}
if (keySpec instanceof DSAPrivateKeySpec == false) {
throw new InvalidKeySpecException("Only DSAPrivateKeySpec and "
+ "PKCS8EncodedKeySpec supported for DSA private keys");
}
try {
DSAPrivateKeySpec ds = (DSAPrivateKeySpec)keySpec;
return generatePrivate(
ds.getX(),
ds.getP(),
ds.getQ(),
ds.getG()
);
} catch (PKCS11Exception e) {
throw new InvalidKeySpecException
("Could not create DSA private key", e);
}
}
private PublicKey generatePublic(BigInteger y, BigInteger p, BigInteger q,
BigInteger g) throws PKCS11Exception {
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
new CK_ATTRIBUTE(CKA_VALUE, y),
new CK_ATTRIBUTE(CKA_PRIME, p),
new CK_ATTRIBUTE(CKA_SUBPRIME, q),
new CK_ATTRIBUTE(CKA_BASE, g),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PUBLIC_KEY, CKK_DSA, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.publicKey
(session, keyID, "DSA", p.bitLength(), attributes);
} finally {
token.releaseSession(session);
}
}
private PrivateKey generatePrivate(BigInteger x, BigInteger p,
BigInteger q, BigInteger g) throws PKCS11Exception {
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
new CK_ATTRIBUTE(CKA_VALUE, x),
new CK_ATTRIBUTE(CKA_PRIME, p),
new CK_ATTRIBUTE(CKA_SUBPRIME, q),
new CK_ATTRIBUTE(CKA_BASE, g),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PRIVATE_KEY, CKK_DSA, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.privateKey
(session, keyID, "DSA", p.bitLength(), attributes);
} finally {
token.releaseSession(session);
}
}
<T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_SUBPRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
KeySpec spec = new DSAPublicKeySpec(
attributes[0].getBigInteger(),
attributes[1].getBigInteger(),
attributes[2].getBigInteger(),
attributes[3].getBigInteger()
);
return keySpec.cast(spec);
} else { // X.509 handled in superclass
throw new InvalidKeySpecException("Only DSAPublicKeySpec and "
+ "X509EncodedKeySpec supported for DSA public keys");
}
}
<T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_PRIME),
new CK_ATTRIBUTE(CKA_SUBPRIME),
new CK_ATTRIBUTE(CKA_BASE),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
KeySpec spec = new DSAPrivateKeySpec(
attributes[0].getBigInteger(),
attributes[1].getBigInteger(),
attributes[2].getBigInteger(),
attributes[3].getBigInteger()
);
return keySpec.cast(spec);
} else { // PKCS#8 handled in superclass
throw new InvalidKeySpecException("Only DSAPrivateKeySpec "
+ "and PKCS8EncodedKeySpec supported for DSA private keys");
}
}
KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
return KeyFactory.getInstance("DSA", P11Util.getSunProvider());
}
}

View file

@ -0,0 +1,325 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.util.*;
import java.nio.ByteBuffer;
import java.security.*;
import javax.crypto.SecretKey;
import sun.nio.ch.DirectBuffer;
import sun.security.util.MessageDigestSpi2;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* MessageDigest implementation class. This class currently supports
* MD2, MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512.
*
* Note that many digest operations are on fairly small amounts of data
* (less than 100 bytes total). For example, the 2nd hashing in HMAC or
* the PRF in TLS. In order to speed those up, we use some buffering to
* minimize number of the Java->native transitions.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11Digest extends MessageDigestSpi implements Cloneable,
MessageDigestSpi2 {
/* fields initialized, no session acquired */
private final static int S_BLANK = 1;
/* data in buffer, session acquired, but digest not initialized */
private final static int S_BUFFERED = 2;
/* session initialized for digesting */
private final static int S_INIT = 3;
private final static int BUFFER_SIZE = 96;
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id object
private final CK_MECHANISM mechanism;
// length of the digest in bytes
private final int digestLength;
// associated session, if any
private Session session;
// current state, one of S_* above
private int state;
// buffer to reduce number of JNI calls
private byte[] buffer;
// offset into the buffer
private int bufOfs;
P11Digest(Token token, String algorithm, long mechanism) {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = new CK_MECHANISM(mechanism);
switch ((int)mechanism) {
case (int)CKM_MD2:
case (int)CKM_MD5:
digestLength = 16;
break;
case (int)CKM_SHA_1:
digestLength = 20;
break;
case (int)CKM_SHA224:
digestLength = 28;
break;
case (int)CKM_SHA256:
digestLength = 32;
break;
case (int)CKM_SHA384:
digestLength = 48;
break;
case (int)CKM_SHA512:
digestLength = 64;
break;
default:
throw new ProviderException("Unknown mechanism: " + mechanism);
}
buffer = new byte[BUFFER_SIZE];
state = S_BLANK;
}
// see JCA spec
protected int engineGetDigestLength() {
return digestLength;
}
private void fetchSession() {
token.ensureValid();
if (state == S_BLANK) {
try {
session = token.getOpSession();
state = S_BUFFERED;
} catch (PKCS11Exception e) {
throw new ProviderException("No more session available", e);
}
}
}
// see JCA spec
protected void engineReset() {
token.ensureValid();
if (session != null) {
if (state == S_INIT && token.explicitCancel == true) {
session = token.killSession(session);
} else {
session = token.releaseSession(session);
}
}
state = S_BLANK;
bufOfs = 0;
}
// see JCA spec
protected byte[] engineDigest() {
try {
byte[] digest = new byte[digestLength];
int n = engineDigest(digest, 0, digestLength);
return digest;
} catch (DigestException e) {
throw new ProviderException("internal error", e);
}
}
// see JCA spec
protected int engineDigest(byte[] digest, int ofs, int len)
throws DigestException {
if (len < digestLength) {
throw new DigestException("Length must be at least " +
digestLength);
}
fetchSession();
try {
int n;
if (state == S_BUFFERED) {
n = token.p11.C_DigestSingle(session.id(), mechanism, buffer, 0,
bufOfs, digest, ofs, len);
bufOfs = 0;
} else {
if (bufOfs != 0) {
token.p11.C_DigestUpdate(session.id(), 0, buffer, 0,
bufOfs);
bufOfs = 0;
}
n = token.p11.C_DigestFinal(session.id(), digest, ofs, len);
}
if (n != digestLength) {
throw new ProviderException("internal digest length error");
}
return n;
} catch (PKCS11Exception e) {
throw new ProviderException("digest() failed", e);
} finally {
engineReset();
}
}
// see JCA spec
protected void engineUpdate(byte in) {
byte[] temp = { in };
engineUpdate(temp, 0, 1);
}
// see JCA spec
protected void engineUpdate(byte[] in, int ofs, int len) {
if (len <= 0) {
return;
}
fetchSession();
try {
if (state == S_BUFFERED) {
token.p11.C_DigestInit(session.id(), mechanism);
state = S_INIT;
}
if ((bufOfs != 0) && (bufOfs + len > buffer.length)) {
// process the buffered data
token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
bufOfs = 0;
}
if (bufOfs + len > buffer.length) {
// process the new data
token.p11.C_DigestUpdate(session.id(), 0, in, ofs, len);
} else {
// buffer the new data
System.arraycopy(in, ofs, buffer, bufOfs, len);
bufOfs += len;
}
} catch (PKCS11Exception e) {
engineReset();
throw new ProviderException("update() failed", e);
}
}
// Called by SunJSSE via reflection during the SSL 3.0 handshake if
// the master secret is sensitive.
// Note: Change to protected after this method is moved from
// sun.security.util.MessageSpi2 interface to
// java.security.MessageDigestSpi class
public void engineUpdate(SecretKey key) throws InvalidKeyException {
// SunJSSE calls this method only if the key does not have a RAW
// encoding, i.e. if it is sensitive. Therefore, no point in calling
// SecretKeyFactory to try to convert it. Just verify it ourselves.
if (key instanceof P11Key == false) {
throw new InvalidKeyException("Not a P11Key: " + key);
}
P11Key p11Key = (P11Key)key;
if (p11Key.token != token) {
throw new InvalidKeyException("Not a P11Key of this provider: " +
key);
}
fetchSession();
try {
if (state == S_BUFFERED) {
token.p11.C_DigestInit(session.id(), mechanism);
state = S_INIT;
}
if (bufOfs != 0) {
token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
bufOfs = 0;
}
token.p11.C_DigestKey(session.id(), p11Key.keyID);
} catch (PKCS11Exception e) {
engineReset();
throw new ProviderException("update(SecretKey) failed", e);
}
}
// see JCA spec
protected void engineUpdate(ByteBuffer byteBuffer) {
int len = byteBuffer.remaining();
if (len <= 0) {
return;
}
if (byteBuffer instanceof DirectBuffer == false) {
super.engineUpdate(byteBuffer);
return;
}
fetchSession();
long addr = ((DirectBuffer)byteBuffer).address();
int ofs = byteBuffer.position();
try {
if (state == S_BUFFERED) {
token.p11.C_DigestInit(session.id(), mechanism);
state = S_INIT;
}
if (bufOfs != 0) {
token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
bufOfs = 0;
}
token.p11.C_DigestUpdate(session.id(), addr + ofs, null, 0, len);
byteBuffer.position(ofs + len);
} catch (PKCS11Exception e) {
engineReset();
throw new ProviderException("update() failed", e);
}
}
public Object clone() throws CloneNotSupportedException {
P11Digest copy = (P11Digest) super.clone();
copy.buffer = buffer.clone();
try {
if (session != null) {
copy.session = copy.token.getOpSession();
}
if (state == S_INIT) {
byte[] stateValues =
token.p11.C_GetOperationState(session.id());
token.p11.C_SetOperationState(copy.session.id(),
stateValues, 0, 0);
}
} catch (PKCS11Exception e) {
throw (CloneNotSupportedException)
(new CloneNotSupportedException(algorithm).initCause(e));
}
return copy;
}
}

View file

@ -0,0 +1,214 @@
/*
* Copyright (c) 2006, 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 sun.security.pkcs11;
import java.security.*;
import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* KeyAgreement implementation for ECDH.
*
* @author Andreas Sterbenz
* @since 1.6
*/
final class P11ECDHKeyAgreement extends KeyAgreementSpi {
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private final long mechanism;
// private key, if initialized
private P11Key privateKey;
// encoded public point, non-null between doPhase() and generateSecret() only
private byte[] publicValue;
// length of the secret to be derived
private int secretLen;
P11ECDHKeyAgreement(Token token, String algorithm, long mechanism) {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
}
// see JCE spec
protected void engineInit(Key key, SecureRandom random)
throws InvalidKeyException {
if (key instanceof PrivateKey == false) {
throw new InvalidKeyException
("Key must be instance of PrivateKey");
}
privateKey = P11KeyFactory.convertKey(token, key, "EC");
publicValue = null;
}
// see JCE spec
protected void engineInit(Key key, AlgorithmParameterSpec params,
SecureRandom random) throws InvalidKeyException,
InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException
("Parameters not supported");
}
engineInit(key, random);
}
// see JCE spec
protected Key engineDoPhase(Key key, boolean lastPhase)
throws InvalidKeyException, IllegalStateException {
if (privateKey == null) {
throw new IllegalStateException("Not initialized");
}
if (publicValue != null) {
throw new IllegalStateException("Phase already executed");
}
if (lastPhase == false) {
throw new IllegalStateException
("Only two party agreement supported, lastPhase must be true");
}
if (key instanceof ECPublicKey == false) {
throw new InvalidKeyException
("Key must be a PublicKey with algorithm EC");
}
ECPublicKey ecKey = (ECPublicKey)key;
int keyLenBits = ecKey.getParams().getCurve().getField().getFieldSize();
secretLen = (keyLenBits + 7) >> 3;
publicValue = P11ECKeyFactory.getEncodedPublicValue(ecKey);
return null;
}
// see JCE spec
protected byte[] engineGenerateSecret() throws IllegalStateException {
if ((privateKey == null) || (publicValue == null)) {
throw new IllegalStateException("Not initialized correctly");
}
Session session = null;
try {
session = token.getOpSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
};
CK_ECDH1_DERIVE_PARAMS ckParams =
new CK_ECDH1_DERIVE_PARAMS(CKD_NULL, null, publicValue);
attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, ckParams), privateKey.keyID,
attributes);
attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE)
};
token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
byte[] secret = attributes[0].getByteArray();
token.p11.C_DestroyObject(session.id(), keyID);
return secret;
} catch (PKCS11Exception e) {
throw new ProviderException("Could not derive key", e);
} finally {
publicValue = null;
token.releaseSession(session);
}
}
// see JCE spec
protected int engineGenerateSecret(byte[] sharedSecret, int
offset) throws IllegalStateException, ShortBufferException {
if (offset + secretLen > sharedSecret.length) {
throw new ShortBufferException("Need " + secretLen
+ " bytes, only " + (sharedSecret.length - offset) + " available");
}
byte[] secret = engineGenerateSecret();
System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
return secret.length;
}
// see JCE spec
protected SecretKey engineGenerateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException {
if (algorithm == null) {
throw new NoSuchAlgorithmException("Algorithm must not be null");
}
if (algorithm.equals("TlsPremasterSecret") == false) {
throw new NoSuchAlgorithmException
("Only supported for algorithm TlsPremasterSecret");
}
return nativeGenerateSecret(algorithm);
}
private SecretKey nativeGenerateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException {
if ((privateKey == null) || (publicValue == null)) {
throw new IllegalStateException("Not initialized correctly");
}
long keyType = CKK_GENERIC_SECRET;
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
};
CK_ECDH1_DERIVE_PARAMS ckParams =
new CK_ECDH1_DERIVE_PARAMS(CKD_NULL, null, publicValue);
attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, ckParams), privateKey.keyID,
attributes);
CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE_LEN),
};
token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
int keyLen = (int)lenAttributes[0].getLong();
SecretKey key = P11Key.secretKey
(session, keyID, algorithm, keyLen << 3, attributes);
return key;
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not derive key", e);
} finally {
publicValue = null;
token.releaseSession(session);
}
}
}

View file

@ -0,0 +1,333 @@
/*
* Copyright (c) 2006, 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 sun.security.pkcs11;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.DerValue;
import sun.security.util.ECUtil;
/**
* EC KeyFactory implementation.
*
* @author Andreas Sterbenz
* @since 1.6
*/
final class P11ECKeyFactory extends P11KeyFactory {
private static Provider sunECprovider;
private static Provider getSunECProvider() {
if (sunECprovider == null) {
sunECprovider = Security.getProvider("SunEC");
if (sunECprovider == null) {
throw new RuntimeException("Cannot load SunEC provider");
}
}
return sunECprovider;
}
P11ECKeyFactory(Token token, String algorithm) {
super(token, algorithm);
}
static ECParameterSpec getECParameterSpec(String name) {
return ECUtil.getECParameterSpec(getSunECProvider(), name);
}
static ECParameterSpec getECParameterSpec(int keySize) {
return ECUtil.getECParameterSpec(getSunECProvider(), keySize);
}
// Check that spec is a known supported curve and convert it to our
// ECParameterSpec subclass. If not possible, return null.
static ECParameterSpec getECParameterSpec(ECParameterSpec spec) {
return ECUtil.getECParameterSpec(getSunECProvider(), spec);
}
static ECParameterSpec decodeParameters(byte[] params) throws IOException {
return ECUtil.getECParameterSpec(getSunECProvider(), params);
}
static byte[] encodeParameters(ECParameterSpec params) {
return ECUtil.encodeECParameterSpec(getSunECProvider(), params);
}
static ECPoint decodePoint(byte[] encoded, EllipticCurve curve) throws IOException {
return ECUtil.decodePoint(encoded, curve);
}
// Used by ECDH KeyAgreement
static byte[] getEncodedPublicValue(PublicKey key) throws InvalidKeyException {
if (key instanceof ECPublicKey) {
ECPublicKey ecKey = (ECPublicKey)key;
ECPoint w = ecKey.getW();
ECParameterSpec params = ecKey.getParams();
return ECUtil.encodePoint(w, params.getCurve());
} else {
// should never occur
throw new InvalidKeyException
("Key class not yet supported: " + key.getClass().getName());
}
}
PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
try {
if (key instanceof ECPublicKey) {
ECPublicKey ecKey = (ECPublicKey)key;
return generatePublic(
ecKey.getW(),
ecKey.getParams()
);
} else if ("X.509".equals(key.getFormat())) {
// let Sun provider parse for us, then recurse
byte[] encoded = key.getEncoded();
try {
key = ECUtil.decodeX509ECPublicKey(encoded);
} catch (InvalidKeySpecException ikse) {
throw new InvalidKeyException(ikse);
}
return implTranslatePublicKey(key);
} else {
throw new InvalidKeyException("PublicKey must be instance "
+ "of ECPublicKey or have X.509 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create EC public key", e);
}
}
PrivateKey implTranslatePrivateKey(PrivateKey key)
throws InvalidKeyException {
try {
if (key instanceof ECPrivateKey) {
ECPrivateKey ecKey = (ECPrivateKey)key;
return generatePrivate(
ecKey.getS(),
ecKey.getParams()
);
} else if ("PKCS#8".equals(key.getFormat())) {
// let Sun provider parse for us, then recurse
byte[] encoded = key.getEncoded();
try {
key = ECUtil.decodePKCS8ECPrivateKey(encoded);
} catch (InvalidKeySpecException ikse) {
throw new InvalidKeyException(ikse);
}
return implTranslatePrivateKey(key);
} else {
throw new InvalidKeyException("PrivateKey must be instance "
+ "of ECPrivateKey or have PKCS#8 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create EC private key", e);
}
}
// see JCA spec
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof X509EncodedKeySpec) {
try {
byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
PublicKey key = ECUtil.decodeX509ECPublicKey(encoded);
return implTranslatePublicKey(key);
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException
("Could not create EC public key", e);
}
}
if (keySpec instanceof ECPublicKeySpec == false) {
throw new InvalidKeySpecException("Only ECPublicKeySpec and "
+ "X509EncodedKeySpec supported for EC public keys");
}
try {
ECPublicKeySpec ec = (ECPublicKeySpec)keySpec;
return generatePublic(
ec.getW(),
ec.getParams()
);
} catch (PKCS11Exception e) {
throw new InvalidKeySpecException
("Could not create EC public key", e);
}
}
// see JCA spec
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof PKCS8EncodedKeySpec) {
try {
byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
PrivateKey key = ECUtil.decodePKCS8ECPrivateKey(encoded);
return implTranslatePrivateKey(key);
} catch (GeneralSecurityException e) {
throw new InvalidKeySpecException
("Could not create EC private key", e);
}
}
if (keySpec instanceof ECPrivateKeySpec == false) {
throw new InvalidKeySpecException("Only ECPrivateKeySpec and "
+ "PKCS8EncodedKeySpec supported for EC private keys");
}
try {
ECPrivateKeySpec ec = (ECPrivateKeySpec)keySpec;
return generatePrivate(
ec.getS(),
ec.getParams()
);
} catch (PKCS11Exception e) {
throw new InvalidKeySpecException
("Could not create EC private key", e);
}
}
private PublicKey generatePublic(ECPoint point, ECParameterSpec params)
throws PKCS11Exception {
byte[] encodedParams =
ECUtil.encodeECParameterSpec(getSunECProvider(), params);
byte[] encodedPoint =
ECUtil.encodePoint(point, params.getCurve());
// Check whether the X9.63 encoding of an EC point shall be wrapped
// in an ASN.1 OCTET STRING
if (!token.config.getUseEcX963Encoding()) {
try {
encodedPoint =
new DerValue(DerValue.tag_OctetString, encodedPoint)
.toByteArray();
} catch (IOException e) {
throw new
IllegalArgumentException("Could not DER encode point", e);
}
}
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
new CK_ATTRIBUTE(CKA_EC_POINT, encodedPoint),
new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PUBLIC_KEY, CKK_EC, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.publicKey
(session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
} finally {
token.releaseSession(session);
}
}
private PrivateKey generatePrivate(BigInteger s, ECParameterSpec params)
throws PKCS11Exception {
byte[] encodedParams =
ECUtil.encodeECParameterSpec(getSunECProvider(), params);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
new CK_ATTRIBUTE(CKA_VALUE, s),
new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PRIVATE_KEY, CKK_EC, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.privateKey
(session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
} finally {
token.releaseSession(session);
}
}
<T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_EC_POINT),
new CK_ATTRIBUTE(CKA_EC_PARAMS),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
try {
ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
ECPoint point = decodePoint(attributes[0].getByteArray(), params.getCurve());
return keySpec.cast(new ECPublicKeySpec(point, params));
} catch (IOException e) {
throw new InvalidKeySpecException("Could not parse key", e);
}
} else { // X.509 handled in superclass
throw new InvalidKeySpecException("Only ECPublicKeySpec and "
+ "X509EncodedKeySpec supported for EC public keys");
}
}
<T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE),
new CK_ATTRIBUTE(CKA_EC_PARAMS),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
try {
ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
return keySpec.cast(
new ECPrivateKeySpec(attributes[0].getBigInteger(), params));
} catch (IOException e) {
throw new InvalidKeySpecException("Could not parse key", e);
}
} else { // PKCS#8 handled in superclass
throw new InvalidKeySpecException("Only ECPrivateKeySpec "
+ "and PKCS8EncodedKeySpec supported for EC private keys");
}
}
KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
return KeyFactory.getInstance("EC", getSunECProvider());
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,347 @@
/*
* Copyright (c) 2003, 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 sun.security.pkcs11;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.interfaces.*;
import javax.crypto.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.KeyUtil;
/**
* KeyAgreement implementation class. This class currently supports
* DH.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11KeyAgreement extends KeyAgreementSpi {
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private final long mechanism;
// private key, if initialized
private P11Key privateKey;
// other sides public value ("y"), if doPhase() already called
private BigInteger publicValue;
// length of the secret to be derived
private int secretLen;
// KeyAgreement from SunJCE as fallback for > 2 party agreement
private KeyAgreement multiPartyAgreement;
P11KeyAgreement(Token token, String algorithm, long mechanism) {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
}
// see JCE spec
protected void engineInit(Key key, SecureRandom random)
throws InvalidKeyException {
if (key instanceof PrivateKey == false) {
throw new InvalidKeyException
("Key must be instance of PrivateKey");
}
privateKey = P11KeyFactory.convertKey(token, key, algorithm);
publicValue = null;
multiPartyAgreement = null;
}
// see JCE spec
protected void engineInit(Key key, AlgorithmParameterSpec params,
SecureRandom random) throws InvalidKeyException,
InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException
("Parameters not supported");
}
engineInit(key, random);
}
// see JCE spec
protected Key engineDoPhase(Key key, boolean lastPhase)
throws InvalidKeyException, IllegalStateException {
if (privateKey == null) {
throw new IllegalStateException("Not initialized");
}
if (publicValue != null) {
throw new IllegalStateException("Phase already executed");
}
// PKCS#11 only allows key agreement between 2 parties
// JCE allows >= 2 parties. To support that case (for compatibility
// and to pass JCK), fall back to SunJCE in this case.
// NOTE that we initialize using the P11Key, which will fail if it
// is sensitive/unextractable. However, this is not an issue in the
// compatibility configuration, which is all we are targeting here.
if ((multiPartyAgreement != null) || (lastPhase == false)) {
if (multiPartyAgreement == null) {
try {
multiPartyAgreement = KeyAgreement.getInstance
("DH", P11Util.getSunJceProvider());
multiPartyAgreement.init(privateKey);
} catch (NoSuchAlgorithmException e) {
throw new InvalidKeyException
("Could not initialize multi party agreement", e);
}
}
return multiPartyAgreement.doPhase(key, lastPhase);
}
if ((key instanceof PublicKey == false)
|| (key.getAlgorithm().equals(algorithm) == false)) {
throw new InvalidKeyException
("Key must be a PublicKey with algorithm DH");
}
BigInteger p, g, y;
if (key instanceof DHPublicKey) {
DHPublicKey dhKey = (DHPublicKey)key;
// validate the Diffie-Hellman public key
KeyUtil.validate(dhKey);
y = dhKey.getY();
DHParameterSpec params = dhKey.getParams();
p = params.getP();
g = params.getG();
} else {
// normally, DH PublicKeys will always implement DHPublicKey
// just in case not, attempt conversion
P11DHKeyFactory kf = new P11DHKeyFactory(token, "DH");
try {
DHPublicKeySpec spec = kf.engineGetKeySpec(
key, DHPublicKeySpec.class);
// validate the Diffie-Hellman public key
KeyUtil.validate(spec);
y = spec.getY();
p = spec.getP();
g = spec.getG();
} catch (InvalidKeySpecException e) {
throw new InvalidKeyException("Could not obtain key values", e);
}
}
// if parameters of private key are accessible, verify that
// they match parameters of public key
// XXX p and g should always be readable, even if the key is sensitive
if (privateKey instanceof DHPrivateKey) {
DHPrivateKey dhKey = (DHPrivateKey)privateKey;
DHParameterSpec params = dhKey.getParams();
if ((p.equals(params.getP()) == false)
|| (g.equals(params.getG()) == false)) {
throw new InvalidKeyException
("PublicKey DH parameters must match PrivateKey DH parameters");
}
}
publicValue = y;
// length of the secret is length of key
secretLen = (p.bitLength() + 7) >> 3;
return null;
}
// see JCE spec
protected byte[] engineGenerateSecret() throws IllegalStateException {
if (multiPartyAgreement != null) {
byte[] val = multiPartyAgreement.generateSecret();
multiPartyAgreement = null;
return val;
}
if ((privateKey == null) || (publicValue == null)) {
throw new IllegalStateException("Not initialized correctly");
}
Session session = null;
try {
session = token.getOpSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
};
attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
attributes);
attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE)
};
token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
byte[] secret = attributes[0].getByteArray();
token.p11.C_DestroyObject(session.id(), keyID);
// Some vendors, e.g. NSS, trim off the leading 0x00 byte(s) from
// the generated secret. Thus, we need to check the secret length
// and trim/pad it so the returned value has the same length as
// the modulus size
if (secret.length == secretLen) {
return secret;
} else {
if (secret.length > secretLen) {
// Shouldn't happen; but check just in case
throw new ProviderException("generated secret is out-of-range");
}
byte[] newSecret = new byte[secretLen];
System.arraycopy(secret, 0, newSecret, secretLen - secret.length,
secret.length);
return newSecret;
}
} catch (PKCS11Exception e) {
throw new ProviderException("Could not derive key", e);
} finally {
publicValue = null;
token.releaseSession(session);
}
}
// see JCE spec
protected int engineGenerateSecret(byte[] sharedSecret, int
offset) throws IllegalStateException, ShortBufferException {
if (multiPartyAgreement != null) {
int n = multiPartyAgreement.generateSecret(sharedSecret, offset);
multiPartyAgreement = null;
return n;
}
if (offset + secretLen > sharedSecret.length) {
throw new ShortBufferException("Need " + secretLen
+ " bytes, only " + (sharedSecret.length - offset) + " available");
}
byte[] secret = engineGenerateSecret();
System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
return secret.length;
}
// see JCE spec
protected SecretKey engineGenerateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException {
if (multiPartyAgreement != null) {
SecretKey key = multiPartyAgreement.generateSecret(algorithm);
multiPartyAgreement = null;
return key;
}
if (algorithm == null) {
throw new NoSuchAlgorithmException("Algorithm must not be null");
}
if (algorithm.equals("TlsPremasterSecret")) {
// For now, only perform native derivation for TlsPremasterSecret
// as that is required for FIPS compliance.
// For other algorithms, there are unresolved issues regarding
// how this should work in JCE plus a Solaris truncation bug.
// (bug not yet filed).
return nativeGenerateSecret(algorithm);
}
byte[] secret = engineGenerateSecret();
// Maintain compatibility for SunJCE:
// verify secret length is sensible for algorithm / truncate
// return generated key itself if possible
int keyLen;
if (algorithm.equalsIgnoreCase("DES")) {
keyLen = 8;
} else if (algorithm.equalsIgnoreCase("DESede")) {
keyLen = 24;
} else if (algorithm.equalsIgnoreCase("Blowfish")) {
keyLen = Math.min(56, secret.length);
} else if (algorithm.equalsIgnoreCase("TlsPremasterSecret")) {
keyLen = secret.length;
} else {
throw new NoSuchAlgorithmException
("Unknown algorithm " + algorithm);
}
if (secret.length < keyLen) {
throw new InvalidKeyException("Secret too short");
}
if (algorithm.equalsIgnoreCase("DES") ||
algorithm.equalsIgnoreCase("DESede")) {
for (int i = 0; i < keyLen; i+=8) {
P11SecretKeyFactory.fixDESParity(secret, i);
}
}
return new SecretKeySpec(secret, 0, keyLen, algorithm);
}
private SecretKey nativeGenerateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException {
if ((privateKey == null) || (publicValue == null)) {
throw new IllegalStateException("Not initialized correctly");
}
long keyType = CKK_GENERIC_SECRET;
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
};
attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
attributes);
CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE_LEN),
};
token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
int keyLen = (int)lenAttributes[0].getLong();
SecretKey key = P11Key.secretKey
(session, keyID, algorithm, keyLen << 3, attributes);
if ("RAW".equals(key.getFormat())) {
// Workaround for Solaris bug 6318543.
// Strip leading zeroes ourselves if possible (key not sensitive).
// This should be removed once the Solaris fix is available
// as here we always retrieve the CKA_VALUE even for tokens
// that do not have that bug.
byte[] keyBytes = key.getEncoded();
byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
if (keyBytes != newBytes) {
key = new SecretKeySpec(newBytes, algorithm);
}
}
return key;
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not derive key", e);
} finally {
publicValue = null;
token.releaseSession(session);
}
}
}

View file

@ -0,0 +1,154 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.security.*;
import java.security.spec.*;
import sun.security.pkcs11.wrapper.PKCS11Exception;
/**
* KeyFactory base class. Provides common infrastructure for the RSA, DSA,
* and DH implementations.
*
* The subclasses support conversion between keys and keyspecs
* using X.509, PKCS#8, and their individual algorithm specific formats,
* assuming keys are extractable.
*
* @author Andreas Sterbenz
* @since 1.5
*/
abstract class P11KeyFactory extends KeyFactorySpi {
// token instance
final Token token;
// algorithm name, currently one of RSA, DSA, DH
final String algorithm;
P11KeyFactory(Token token, String algorithm) {
super();
this.token = token;
this.algorithm = algorithm;
}
/**
* Convert an arbitrary key of algorithm into a P11Key of token.
* Used by P11Signature.init() and RSACipher.init().
*/
static P11Key convertKey(Token token, Key key, String algorithm)
throws InvalidKeyException {
return (P11Key)token.getKeyFactory(algorithm).engineTranslateKey(key);
}
// see JCA spec
protected final <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if ((key == null) || (keySpec == null)) {
throw new InvalidKeySpecException
("key and keySpec must not be null");
}
// delegate to our Java based providers for PKCS#8 and X.509
if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)
|| X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
try {
return implGetSoftwareFactory().getKeySpec(key, keySpec);
} catch (GeneralSecurityException e) {
throw new InvalidKeySpecException("Could not encode key", e);
}
}
// first translate into a key of this token, if it is not already
P11Key p11Key;
try {
p11Key = (P11Key)engineTranslateKey(key);
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException("Could not convert key", e);
}
Session[] session = new Session[1];
try {
if (p11Key.isPublic()) {
return implGetPublicKeySpec(p11Key, keySpec, session);
} else {
return implGetPrivateKeySpec(p11Key, keySpec, session);
}
} catch (PKCS11Exception e) {
throw new InvalidKeySpecException("Could not generate KeySpec", e);
} finally {
session[0] = token.releaseSession(session[0]);
}
}
// see JCA spec
protected final Key engineTranslateKey(Key key) throws InvalidKeyException {
token.ensureValid();
if (key == null) {
throw new InvalidKeyException("Key must not be null");
}
if (key.getAlgorithm().equals(this.algorithm) == false) {
throw new InvalidKeyException
("Key algorithm must be " + algorithm);
}
if (key instanceof P11Key) {
P11Key p11Key = (P11Key)key;
if (p11Key.token == token) {
// already a key of this token, no need to translate
return key;
}
}
P11Key p11Key = token.privateCache.get(key);
if (p11Key != null) {
return p11Key;
}
if (key instanceof PublicKey) {
PublicKey publicKey = implTranslatePublicKey((PublicKey)key);
token.privateCache.put(key, (P11Key)publicKey);
return publicKey;
} else if (key instanceof PrivateKey) {
PrivateKey privateKey = implTranslatePrivateKey((PrivateKey)key);
token.privateCache.put(key, (P11Key)privateKey);
return privateKey;
} else {
throw new InvalidKeyException
("Key must be instance of PublicKey or PrivateKey");
}
}
abstract <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException;
abstract <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException;
abstract PublicKey implTranslatePublicKey(PublicKey key)
throws InvalidKeyException;
abstract PrivateKey implTranslatePrivateKey(PrivateKey key)
throws InvalidKeyException;
abstract KeyFactory implGetSoftwareFactory() throws GeneralSecurityException;
}

View file

@ -0,0 +1,284 @@
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* KeyGenerator implementation class. This class currently supports
* DES, DESede, AES, ARCFOUR, and Blowfish.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11KeyGenerator extends KeyGeneratorSpi {
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private long mechanism;
// raw key size in bits, e.g. 64 for DES. Always valid.
private int keySize;
// bits of entropy in the key, e.g. 56 for DES. Always valid.
private int significantKeySize;
// keyType (CKK_*), needed for TemplateManager call only.
private long keyType;
// for determining if both 112 and 168 bits of DESede key lengths
// are supported.
private boolean supportBothKeySizes;
/**
* Utility method for checking if the specified key size is valid
* and within the supported range. Return the significant key size
* upon successful validation.
* @param keyGenMech the PKCS#11 key generation mechanism.
* @param keySize the to-be-checked key size for this mechanism.
* @param token token which provides this mechanism.
* @return the significant key size (in bits) corresponding to the
* specified key size.
* @throws InvalidParameterException if the specified key size is invalid.
* @throws ProviderException if this mechanism isn't supported by SunPKCS11
* or underlying native impl.
*/
static int checkKeySize(long keyGenMech, int keySize, Token token)
throws InvalidAlgorithmParameterException, ProviderException {
int sigKeySize;
switch ((int)keyGenMech) {
case (int)CKM_DES_KEY_GEN:
if ((keySize != 64) && (keySize != 56)) {
throw new InvalidAlgorithmParameterException
("DES key length must be 56 bits");
}
sigKeySize = 56;
break;
case (int)CKM_DES2_KEY_GEN:
case (int)CKM_DES3_KEY_GEN:
if ((keySize == 112) || (keySize == 128)) {
sigKeySize = 112;
} else if ((keySize == 168) || (keySize == 192)) {
sigKeySize = 168;
} else {
throw new InvalidAlgorithmParameterException
("DESede key length must be 112, or 168 bits");
}
break;
default:
// Handle all variable-key-length algorithms here
CK_MECHANISM_INFO info = null;
try {
info = token.getMechanismInfo(keyGenMech);
} catch (PKCS11Exception p11e) {
// Should never happen
throw new ProviderException
("Cannot retrieve mechanism info", p11e);
}
if (info == null) {
// XXX Unable to retrieve the supported key length from
// the underlying native impl. Skip the checking for now.
return keySize;
}
// PKCS#11 defines these to be in number of bytes except for
// RC4 which is in bits. However, some PKCS#11 impls still use
// bytes for all mechs, e.g. NSS. We try to detect this
// inconsistency if the minKeySize seems unreasonably small.
int minKeySize = (int)info.ulMinKeySize;
int maxKeySize = (int)info.ulMaxKeySize;
if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) {
minKeySize = (int)info.ulMinKeySize << 3;
maxKeySize = (int)info.ulMaxKeySize << 3;
}
// Explicitly disallow keys shorter than 40-bits for security
if (minKeySize < 40) minKeySize = 40;
if (keySize < minKeySize || keySize > maxKeySize) {
throw new InvalidAlgorithmParameterException
("Key length must be between " + minKeySize +
" and " + maxKeySize + " bits");
}
if (keyGenMech == CKM_AES_KEY_GEN) {
if ((keySize != 128) && (keySize != 192) &&
(keySize != 256)) {
throw new InvalidAlgorithmParameterException
("AES key length must be " + minKeySize +
(maxKeySize >= 192? ", 192":"") +
(maxKeySize >= 256? ", or 256":"") + " bits");
}
}
sigKeySize = keySize;
}
return sigKeySize;
}
P11KeyGenerator(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
if (this.mechanism == CKM_DES3_KEY_GEN) {
/* Given the current lookup order specified in SunPKCS11.java,
if CKM_DES2_KEY_GEN is used to construct this object, it
means that CKM_DES3_KEY_GEN is disabled or unsupported.
*/
supportBothKeySizes =
(token.provider.config.isEnabled(CKM_DES2_KEY_GEN) &&
(token.getMechanismInfo(CKM_DES2_KEY_GEN) != null));
}
setDefaultKeySize();
}
// set default keysize and also initialize keyType
private void setDefaultKeySize() {
switch ((int)mechanism) {
case (int)CKM_DES_KEY_GEN:
keySize = 64;
keyType = CKK_DES;
break;
case (int)CKM_DES2_KEY_GEN:
keySize = 128;
keyType = CKK_DES2;
break;
case (int)CKM_DES3_KEY_GEN:
keySize = 192;
keyType = CKK_DES3;
break;
case (int)CKM_AES_KEY_GEN:
keySize = 128;
keyType = CKK_AES;
break;
case (int)CKM_RC4_KEY_GEN:
keySize = 128;
keyType = CKK_RC4;
break;
case (int)CKM_BLOWFISH_KEY_GEN:
keySize = 128;
keyType = CKK_BLOWFISH;
break;
default:
throw new ProviderException("Unknown mechanism " + mechanism);
}
try {
significantKeySize = checkKeySize(mechanism, keySize, token);
} catch (InvalidAlgorithmParameterException iape) {
throw new ProviderException("Unsupported default key size", iape);
}
}
// see JCE spec
protected void engineInit(SecureRandom random) {
token.ensureValid();
setDefaultKeySize();
}
// see JCE spec
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
throw new InvalidAlgorithmParameterException
("AlgorithmParameterSpec not supported");
}
// see JCE spec
protected void engineInit(int keySize, SecureRandom random) {
token.ensureValid();
int newSignificantKeySize;
try {
newSignificantKeySize = checkKeySize(mechanism, keySize, token);
} catch (InvalidAlgorithmParameterException iape) {
throw (InvalidParameterException)
(new InvalidParameterException().initCause(iape));
}
if ((mechanism == CKM_DES2_KEY_GEN) ||
(mechanism == CKM_DES3_KEY_GEN)) {
long newMechanism = (newSignificantKeySize == 112 ?
CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN);
if (mechanism != newMechanism) {
if (supportBothKeySizes) {
mechanism = newMechanism;
// Adjust keyType to reflect the mechanism change
keyType = (mechanism == CKM_DES2_KEY_GEN ?
CKK_DES2 : CKK_DES3);
} else {
throw new InvalidParameterException
("Only " + significantKeySize +
"-bit DESede is supported");
}
}
}
this.keySize = keySize;
this.significantKeySize = newSignificantKeySize;
}
// see JCE spec
protected SecretKey engineGenerateKey() {
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes;
switch ((int)keyType) {
case (int)CKK_DES:
case (int)CKK_DES2:
case (int)CKK_DES3:
// fixed length, do not specify CKA_VALUE_LEN
attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
};
break;
default:
attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_VALUE_LEN, keySize >> 3),
};
break;
}
attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
long keyID = token.p11.C_GenerateKey
(session.id(), new CK_MECHANISM(mechanism), attributes);
return P11Key.secretKey
(session, keyID, algorithm, significantKeySize, attributes);
} catch (PKCS11Exception e) {
throw new ProviderException("Could not generate key", e);
} finally {
token.releaseSession(session);
}
}
}

View file

@ -0,0 +1,429 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import javax.crypto.spec.DHParameterSpec;
import sun.security.provider.ParameterCache;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.rsa.RSAKeyFactory;
/**
* KeyPairGenerator implementation class. This class currently supports
* RSA, DSA, DH, and EC.
*
* Note that for DSA and DH we rely on the Sun and SunJCE providers to
* obtain the parameters from.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private final long mechanism;
// selected or default key size, always valid
private int keySize;
// parameters specified via init, if any
private AlgorithmParameterSpec params;
// for RSA, selected or default value of public exponent, always valid
private BigInteger rsaPublicExponent = RSAKeyGenParameterSpec.F4;
// the supported keysize range of the native PKCS11 library
// if the value cannot be retrieved or unspecified, -1 is used.
private final int minKeySize;
private final int maxKeySize;
// SecureRandom instance, if specified in init
private SecureRandom random;
P11KeyPairGenerator(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
int minKeyLen = -1;
int maxKeyLen = -1;
try {
CK_MECHANISM_INFO mechInfo = token.getMechanismInfo(mechanism);
if (mechInfo != null) {
minKeyLen = (int) mechInfo.ulMinKeySize;
maxKeyLen = (int) mechInfo.ulMaxKeySize;
}
} catch (PKCS11Exception p11e) {
// Should never happen
throw new ProviderException
("Unexpected error while getting mechanism info", p11e);
}
// set default key sizes and apply our own algorithm-specific limits
// override lower limit to disallow unsecure keys being generated
// override upper limit to deter DOS attack
if (algorithm.equals("EC")) {
keySize = 256;
if ((minKeyLen == -1) || (minKeyLen < 112)) {
minKeyLen = 112;
}
if ((maxKeyLen == -1) || (maxKeyLen > 2048)) {
maxKeyLen = 2048;
}
} else {
if (algorithm.equals("DSA")) {
// keep default keysize at 1024 since larger keysizes may be
// incompatible with SHA1withDSA and SHA-2 Signature algs
// may not be supported by native pkcs11 implementations
keySize = 1024;
} else {
// RSA and DH
keySize = 2048;
}
if ((minKeyLen == -1) || (minKeyLen < 512)) {
minKeyLen = 512;
}
if (algorithm.equals("RSA")) {
if ((maxKeyLen == -1) || (maxKeyLen > 64 * 1024)) {
maxKeyLen = 64 * 1024;
}
}
}
// auto-adjust default keysize in case it's out-of-range
if ((minKeyLen != -1) && (keySize < minKeyLen)) {
keySize = minKeyLen;
}
if ((maxKeyLen != -1) && (keySize > maxKeyLen)) {
keySize = maxKeyLen;
}
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
this.minKeySize = minKeyLen;
this.maxKeySize = maxKeyLen;
initialize(keySize, null);
}
// see JCA spec
@Override
public void initialize(int keySize, SecureRandom random) {
token.ensureValid();
try {
checkKeySize(keySize, null);
} catch (InvalidAlgorithmParameterException e) {
throw new InvalidParameterException(e.getMessage());
}
this.params = null;
if (algorithm.equals("EC")) {
params = P11ECKeyFactory.getECParameterSpec(keySize);
if (params == null) {
throw new InvalidParameterException(
"No EC parameters available for key size "
+ keySize + " bits");
}
}
this.keySize = keySize;
this.random = random;
}
// see JCA spec
@Override
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException {
token.ensureValid();
int tmpKeySize;
if (algorithm.equals("DH")) {
if (params instanceof DHParameterSpec == false) {
throw new InvalidAlgorithmParameterException
("DHParameterSpec required for Diffie-Hellman");
}
DHParameterSpec dhParams = (DHParameterSpec) params;
tmpKeySize = dhParams.getP().bitLength();
checkKeySize(tmpKeySize, dhParams);
// XXX sanity check params
} else if (algorithm.equals("RSA")) {
if (params instanceof RSAKeyGenParameterSpec == false) {
throw new InvalidAlgorithmParameterException
("RSAKeyGenParameterSpec required for RSA");
}
RSAKeyGenParameterSpec rsaParams =
(RSAKeyGenParameterSpec) params;
tmpKeySize = rsaParams.getKeysize();
checkKeySize(tmpKeySize, rsaParams);
// override the supplied params to null
params = null;
this.rsaPublicExponent = rsaParams.getPublicExponent();
// XXX sanity check params
} else if (algorithm.equals("DSA")) {
if (params instanceof DSAParameterSpec == false) {
throw new InvalidAlgorithmParameterException
("DSAParameterSpec required for DSA");
}
DSAParameterSpec dsaParams = (DSAParameterSpec) params;
tmpKeySize = dsaParams.getP().bitLength();
checkKeySize(tmpKeySize, dsaParams);
// XXX sanity check params
} else if (algorithm.equals("EC")) {
ECParameterSpec ecParams;
if (params instanceof ECParameterSpec) {
ecParams = P11ECKeyFactory.getECParameterSpec(
(ECParameterSpec)params);
if (ecParams == null) {
throw new InvalidAlgorithmParameterException
("Unsupported curve: " + params);
}
} else if (params instanceof ECGenParameterSpec) {
String name = ((ECGenParameterSpec) params).getName();
ecParams = P11ECKeyFactory.getECParameterSpec(name);
if (ecParams == null) {
throw new InvalidAlgorithmParameterException
("Unknown curve name: " + name);
}
// override the supplied params with the derived one
params = ecParams;
} else {
throw new InvalidAlgorithmParameterException
("ECParameterSpec or ECGenParameterSpec required for EC");
}
tmpKeySize = ecParams.getCurve().getField().getFieldSize();
checkKeySize(tmpKeySize, ecParams);
} else {
throw new ProviderException("Unknown algorithm: " + algorithm);
}
this.keySize = tmpKeySize;
this.params = params;
this.random = random;
}
private void checkKeySize(int keySize, AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
// check native range first
if ((minKeySize != -1) && (keySize < minKeySize)) {
throw new InvalidAlgorithmParameterException(algorithm +
" key must be at least " + minKeySize + " bits. " +
"The specific key size " + keySize + " is not supported");
}
if ((maxKeySize != -1) && (keySize > maxKeySize)) {
throw new InvalidAlgorithmParameterException(algorithm +
" key must be at most " + maxKeySize + " bits. " +
"The specific key size " + keySize + " is not supported");
}
// check our own algorithm-specific limits also
if (algorithm.equals("EC")) {
if (keySize < 112) {
throw new InvalidAlgorithmParameterException(
"EC key size must be at least 112 bit. " +
"The specific key size " + keySize + " is not supported");
}
if (keySize > 2048) {
// sanity check, nobody really wants keys this large
throw new InvalidAlgorithmParameterException(
"EC key size must be at most 2048 bit. " +
"The specific key size " + keySize + " is not supported");
}
} else {
// RSA, DH, DSA
if (keySize < 512) {
throw new InvalidAlgorithmParameterException(algorithm +
" key size must be at least 512 bit. " +
"The specific key size " + keySize + " is not supported");
}
if (algorithm.equals("RSA")) {
BigInteger tmpExponent = rsaPublicExponent;
if (params != null) {
tmpExponent =
((RSAKeyGenParameterSpec)params).getPublicExponent();
}
try {
// Reuse the checking in SunRsaSign provider.
// If maxKeySize is -1, then replace it with
// Integer.MAX_VALUE to indicate no limit.
RSAKeyFactory.checkKeyLengths(keySize, tmpExponent,
minKeySize,
(maxKeySize==-1? Integer.MAX_VALUE:maxKeySize));
} catch (InvalidKeyException e) {
throw new InvalidAlgorithmParameterException(e);
}
} else if (algorithm.equals("DH")) {
if (params != null) { // initialized with specified parameters
// sanity check, nobody really wants keys this large
if (keySize > 64 * 1024) {
throw new InvalidAlgorithmParameterException(
"DH key size must be at most 65536 bit. " +
"The specific key size " +
keySize + " is not supported");
}
} else { // default parameters will be used.
// Range is based on the values in
// sun.security.provider.ParameterCache class.
if ((keySize > 8192) || (keySize < 512) ||
((keySize & 0x3f) != 0)) {
throw new InvalidAlgorithmParameterException(
"DH key size must be multiple of 64, and can " +
"only range from 512 to 8192 (inclusive). " +
"The specific key size " +
keySize + " is not supported");
}
DHParameterSpec cache =
ParameterCache.getCachedDHParameterSpec(keySize);
// Except 2048 and 3072, not yet support generation of
// parameters bigger than 1024 bits.
if ((cache == null) && (keySize > 1024)) {
throw new InvalidAlgorithmParameterException(
"Unsupported " + keySize +
"-bit DH parameter generation");
}
}
} else {
// this restriction is in the spec for DSA
if ((keySize != 3072) && (keySize != 2048) &&
((keySize > 1024) || ((keySize & 0x3f) != 0))) {
throw new InvalidAlgorithmParameterException(
"DSA key must be multiples of 64 if less than " +
"1024 bits, or 2048, 3072 bits. " +
"The specific key size " +
keySize + " is not supported");
}
}
}
}
// see JCA spec
@Override
public KeyPair generateKeyPair() {
token.ensureValid();
CK_ATTRIBUTE[] publicKeyTemplate;
CK_ATTRIBUTE[] privateKeyTemplate;
long keyType;
if (algorithm.equals("RSA")) {
keyType = CKK_RSA;
publicKeyTemplate = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_MODULUS_BITS, keySize),
new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, rsaPublicExponent),
};
privateKeyTemplate = new CK_ATTRIBUTE[] {
// empty
};
} else if (algorithm.equals("DSA")) {
keyType = CKK_DSA;
DSAParameterSpec dsaParams;
if (params == null) {
try {
dsaParams = ParameterCache.getDSAParameterSpec
(keySize, random);
} catch (GeneralSecurityException e) {
throw new ProviderException
("Could not generate DSA parameters", e);
}
} else {
dsaParams = (DSAParameterSpec)params;
}
publicKeyTemplate = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_PRIME, dsaParams.getP()),
new CK_ATTRIBUTE(CKA_SUBPRIME, dsaParams.getQ()),
new CK_ATTRIBUTE(CKA_BASE, dsaParams.getG()),
};
privateKeyTemplate = new CK_ATTRIBUTE[] {
// empty
};
} else if (algorithm.equals("DH")) {
keyType = CKK_DH;
DHParameterSpec dhParams;
int privateBits;
if (params == null) {
try {
dhParams = ParameterCache.getDHParameterSpec
(keySize, random);
} catch (GeneralSecurityException e) {
throw new ProviderException
("Could not generate DH parameters", e);
}
privateBits = 0;
} else {
dhParams = (DHParameterSpec)params;
privateBits = dhParams.getL();
}
if (privateBits <= 0) {
// XXX find better defaults
privateBits = (keySize >= 1024) ? 768 : 512;
}
publicKeyTemplate = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_PRIME, dhParams.getP()),
new CK_ATTRIBUTE(CKA_BASE, dhParams.getG())
};
privateKeyTemplate = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_VALUE_BITS, privateBits),
};
} else if (algorithm.equals("EC")) {
keyType = CKK_EC;
byte[] encodedParams =
P11ECKeyFactory.encodeParameters((ECParameterSpec)params);
publicKeyTemplate = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
};
privateKeyTemplate = new CK_ATTRIBUTE[] {
// empty
};
} else {
throw new ProviderException("Unknown algorithm: " + algorithm);
}
Session session = null;
try {
session = token.getObjSession();
publicKeyTemplate = token.getAttributes
(O_GENERATE, CKO_PUBLIC_KEY, keyType, publicKeyTemplate);
privateKeyTemplate = token.getAttributes
(O_GENERATE, CKO_PRIVATE_KEY, keyType, privateKeyTemplate);
long[] keyIDs = token.p11.C_GenerateKeyPair
(session.id(), new CK_MECHANISM(mechanism),
publicKeyTemplate, privateKeyTemplate);
PublicKey publicKey = P11Key.publicKey
(session, keyIDs[0], algorithm, keySize, publicKeyTemplate);
PrivateKey privateKey = P11Key.privateKey
(session, keyIDs[1], algorithm, keySize, privateKeyTemplate);
return new KeyPair(publicKey, privateKey);
} catch (PKCS11Exception e) {
throw new ProviderException(e);
} finally {
token.releaseSession(session);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,269 @@
/*
* Copyright (c) 2003, 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 sun.security.pkcs11;
import java.util.*;
import java.nio.ByteBuffer;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.MacSpi;
import sun.nio.ch.DirectBuffer;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* MAC implementation class. This class currently supports HMAC using
* MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 and the SSL3 MAC
* using MD5 and SHA-1.
*
* Note that unlike other classes (e.g. Signature), this does not
* composite various operations if the token only supports part of the
* required functionality. The MAC implementations in SunJCE already
* do exactly that by implementing an MAC on top of MessageDigests. We
* could not do any better than they.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11Mac extends MacSpi {
/* unitialized, all fields except session have arbitrary values */
private final static int S_UNINIT = 1;
/* session initialized, no data processed yet */
private final static int S_RESET = 2;
/* session initialized, data processed */
private final static int S_UPDATE = 3;
/* transitional state after doFinal() before we go to S_UNINIT */
private final static int S_DOFINAL = 4;
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private final long mechanism;
// mechanism object
private final CK_MECHANISM ckMechanism;
// length of the MAC in bytes
private final int macLength;
// key instance used, if operation active
private P11Key p11Key;
// associated session, if any
private Session session;
// state, one of S_* above
private int state;
// one byte buffer for the update(byte) method, initialized on demand
private byte[] oneByte;
P11Mac(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
Long params = null;
switch ((int)mechanism) {
case (int)CKM_MD5_HMAC:
macLength = 16;
break;
case (int)CKM_SHA_1_HMAC:
macLength = 20;
break;
case (int)CKM_SHA224_HMAC:
macLength = 28;
break;
case (int)CKM_SHA256_HMAC:
macLength = 32;
break;
case (int)CKM_SHA384_HMAC:
macLength = 48;
break;
case (int)CKM_SHA512_HMAC:
macLength = 64;
break;
case (int)CKM_SSL3_MD5_MAC:
macLength = 16;
params = Long.valueOf(16);
break;
case (int)CKM_SSL3_SHA1_MAC:
macLength = 20;
params = Long.valueOf(20);
break;
default:
throw new ProviderException("Unknown mechanism: " + mechanism);
}
ckMechanism = new CK_MECHANISM(mechanism, params);
state = S_UNINIT;
initialize();
}
private void ensureInitialized() throws PKCS11Exception {
token.ensureValid();
if (state == S_UNINIT) {
initialize();
}
}
private void cancelOperation() {
token.ensureValid();
if (state == S_UNINIT) {
return;
}
state = S_UNINIT;
if ((session == null) || (token.explicitCancel == false)) {
return;
}
try {
token.p11.C_SignFinal(session.id(), 0);
} catch (PKCS11Exception e) {
throw new ProviderException("Cancel failed", e);
}
}
private void initialize() throws PKCS11Exception {
if (state == S_RESET) {
return;
}
if (session == null) {
session = token.getOpSession();
}
if (p11Key != null) {
token.p11.C_SignInit
(session.id(), ckMechanism, p11Key.keyID);
state = S_RESET;
} else {
state = S_UNINIT;
}
}
// see JCE spec
protected int engineGetMacLength() {
return macLength;
}
// see JCE spec
protected void engineReset() {
// the framework insists on calling reset() after doFinal(),
// but we prefer to take care of reinitialization ourselves
if (state == S_DOFINAL) {
state = S_UNINIT;
return;
}
cancelOperation();
try {
initialize();
} catch (PKCS11Exception e) {
throw new ProviderException("reset() failed, ", e);
}
}
// see JCE spec
protected void engineInit(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException
("Parameters not supported");
}
cancelOperation();
p11Key = P11SecretKeyFactory.convertKey(token, key, algorithm);
try {
initialize();
} catch (PKCS11Exception e) {
throw new InvalidKeyException("init() failed", e);
}
}
// see JCE spec
protected byte[] engineDoFinal() {
try {
ensureInitialized();
byte[] mac = token.p11.C_SignFinal(session.id(), 0);
state = S_DOFINAL;
return mac;
} catch (PKCS11Exception e) {
throw new ProviderException("doFinal() failed", e);
} finally {
session = token.releaseSession(session);
}
}
// see JCE spec
protected void engineUpdate(byte input) {
if (oneByte == null) {
oneByte = new byte[1];
}
oneByte[0] = input;
engineUpdate(oneByte, 0, 1);
}
// see JCE spec
protected void engineUpdate(byte[] b, int ofs, int len) {
try {
ensureInitialized();
token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
state = S_UPDATE;
} catch (PKCS11Exception e) {
throw new ProviderException("update() failed", e);
}
}
// see JCE spec
protected void engineUpdate(ByteBuffer byteBuffer) {
try {
ensureInitialized();
int len = byteBuffer.remaining();
if (len <= 0) {
return;
}
if (byteBuffer instanceof DirectBuffer == false) {
super.engineUpdate(byteBuffer);
return;
}
long addr = ((DirectBuffer)byteBuffer).address();
int ofs = byteBuffer.position();
token.p11.C_SignUpdate(session.id(), addr + ofs, null, 0, len);
byteBuffer.position(ofs + len);
state = S_UPDATE;
} catch (PKCS11Exception e) {
throw new ProviderException("update() failed", e);
}
}
}

View file

@ -0,0 +1,677 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.*;
import java.util.Locale;
import javax.crypto.*;
import javax.crypto.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
import sun.security.util.KeyUtil;
/**
* RSA Cipher implementation class. We currently only support
* PKCS#1 v1.5 padding on top of CKM_RSA_PKCS.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11RSACipher extends CipherSpi {
// minimum length of PKCS#1 v1.5 padding
private final static int PKCS1_MIN_PADDING_LENGTH = 11;
// constant byte[] of length 0
private final static byte[] B0 = new byte[0];
// mode constant for public key encryption
private final static int MODE_ENCRYPT = 1;
// mode constant for private key decryption
private final static int MODE_DECRYPT = 2;
// mode constant for private key encryption (signing)
private final static int MODE_SIGN = 3;
// mode constant for public key decryption (verifying)
private final static int MODE_VERIFY = 4;
// padding type constant for NoPadding
private final static int PAD_NONE = 1;
// padding type constant for PKCS1Padding
private final static int PAD_PKCS1 = 2;
// token instance
private final Token token;
// algorithm name (always "RSA")
private final String algorithm;
// mechanism id
private final long mechanism;
// associated session, if any
private Session session;
// mode, one of MODE_* above
private int mode;
// padding, one of PAD_* above
private int padType;
private byte[] buffer;
private int bufOfs;
// key, if init() was called
private P11Key p11Key;
// flag indicating whether an operation is initialized
private boolean initialized;
// maximum input data size allowed
// for decryption, this is the length of the key
// for encryption, length of the key minus minimum padding length
private int maxInputSize;
// maximum output size. this is the length of the key
private int outputSize;
// cipher parameter for TLS RSA premaster secret
private AlgorithmParameterSpec spec = null;
// the source of randomness
private SecureRandom random;
P11RSACipher(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
this.token = token;
this.algorithm = "RSA";
this.mechanism = mechanism;
}
// modes do not make sense for RSA, but allow ECB
// see JCE spec
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
if (mode.equalsIgnoreCase("ECB") == false) {
throw new NoSuchAlgorithmException("Unsupported mode " + mode);
}
}
protected void engineSetPadding(String padding)
throws NoSuchPaddingException {
String lowerPadding = padding.toLowerCase(Locale.ENGLISH);
if (lowerPadding.equals("pkcs1padding")) {
padType = PAD_PKCS1;
} else if (lowerPadding.equals("nopadding")) {
padType = PAD_NONE;
} else {
throw new NoSuchPaddingException("Unsupported padding " + padding);
}
}
// return 0 as block size, we are not a block cipher
// see JCE spec
protected int engineGetBlockSize() {
return 0;
}
// return the output size
// see JCE spec
protected int engineGetOutputSize(int inputLen) {
return outputSize;
}
// no IV, return null
// see JCE spec
protected byte[] engineGetIV() {
return null;
}
// no parameters, return null
// see JCE spec
protected AlgorithmParameters engineGetParameters() {
return null;
}
// see JCE spec
protected void engineInit(int opmode, Key key, SecureRandom random)
throws InvalidKeyException {
implInit(opmode, key);
}
// see JCE spec
@SuppressWarnings("deprecation")
protected void engineInit(int opmode, Key key,
AlgorithmParameterSpec params, SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
if (params != null) {
if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
throw new InvalidAlgorithmParameterException(
"Parameters not supported");
}
spec = params;
this.random = random; // for TLS RSA premaster secret
}
implInit(opmode, key);
}
// see JCE spec
protected void engineInit(int opmode, Key key, AlgorithmParameters params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException(
"Parameters not supported");
}
implInit(opmode, key);
}
private void implInit(int opmode, Key key) throws InvalidKeyException {
cancelOperation();
p11Key = P11KeyFactory.convertKey(token, key, algorithm);
boolean encrypt;
if (opmode == Cipher.ENCRYPT_MODE) {
encrypt = true;
} else if (opmode == Cipher.DECRYPT_MODE) {
encrypt = false;
} else if (opmode == Cipher.WRAP_MODE) {
if (p11Key.isPublic() == false) {
throw new InvalidKeyException
("Wrap has to be used with public keys");
}
// No further setup needed for C_Wrap(). We'll initialize later if
// we can't use C_Wrap().
return;
} else if (opmode == Cipher.UNWRAP_MODE) {
if (p11Key.isPrivate() == false) {
throw new InvalidKeyException
("Unwrap has to be used with private keys");
}
// No further setup needed for C_Unwrap(). We'll initialize later
// if we can't use C_Unwrap().
return;
} else {
throw new InvalidKeyException("Unsupported mode: " + opmode);
}
if (p11Key.isPublic()) {
mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
} else if (p11Key.isPrivate()) {
mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
} else {
throw new InvalidKeyException("Unknown key type: " + p11Key);
}
int n = (p11Key.length() + 7) >> 3;
outputSize = n;
buffer = new byte[n];
maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
(n - PKCS1_MIN_PADDING_LENGTH) : n);
try {
initialize();
} catch (PKCS11Exception e) {
throw new InvalidKeyException("init() failed", e);
}
}
private void cancelOperation() {
token.ensureValid();
if (initialized == false) {
return;
}
initialized = false;
if ((session == null) || (token.explicitCancel == false)) {
return;
}
if (session.hasObjects() == false) {
session = token.killSession(session);
return;
}
try {
PKCS11 p11 = token.p11;
int inLen = maxInputSize;
int outLen = buffer.length;
switch (mode) {
case MODE_ENCRYPT:
p11.C_Encrypt
(session.id(), buffer, 0, inLen, buffer, 0, outLen);
break;
case MODE_DECRYPT:
p11.C_Decrypt
(session.id(), buffer, 0, inLen, buffer, 0, outLen);
break;
case MODE_SIGN:
byte[] tmpBuffer = new byte[maxInputSize];
p11.C_Sign
(session.id(), tmpBuffer);
break;
case MODE_VERIFY:
p11.C_VerifyRecover
(session.id(), buffer, 0, inLen, buffer, 0, outLen);
break;
default:
throw new ProviderException("internal error");
}
} catch (PKCS11Exception e) {
// XXX ensure this always works, ignore error
}
}
private void ensureInitialized() throws PKCS11Exception {
token.ensureValid();
if (initialized == false) {
initialize();
}
}
private void initialize() throws PKCS11Exception {
if (session == null) {
session = token.getOpSession();
}
PKCS11 p11 = token.p11;
CK_MECHANISM ckMechanism = new CK_MECHANISM(mechanism);
switch (mode) {
case MODE_ENCRYPT:
p11.C_EncryptInit(session.id(), ckMechanism, p11Key.keyID);
break;
case MODE_DECRYPT:
p11.C_DecryptInit(session.id(), ckMechanism, p11Key.keyID);
break;
case MODE_SIGN:
p11.C_SignInit(session.id(), ckMechanism, p11Key.keyID);
break;
case MODE_VERIFY:
p11.C_VerifyRecoverInit(session.id(), ckMechanism, p11Key.keyID);
break;
default:
throw new AssertionError("internal error");
}
bufOfs = 0;
initialized = true;
}
private void implUpdate(byte[] in, int inOfs, int inLen) {
try {
ensureInitialized();
} catch (PKCS11Exception e) {
throw new ProviderException("update() failed", e);
}
if ((inLen == 0) || (in == null)) {
return;
}
if (bufOfs + inLen > maxInputSize) {
bufOfs = maxInputSize + 1;
return;
}
System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
bufOfs += inLen;
}
private int implDoFinal(byte[] out, int outOfs, int outLen)
throws BadPaddingException, IllegalBlockSizeException {
if (bufOfs > maxInputSize) {
throw new IllegalBlockSizeException("Data must not be longer "
+ "than " + maxInputSize + " bytes");
}
try {
ensureInitialized();
PKCS11 p11 = token.p11;
int n;
switch (mode) {
case MODE_ENCRYPT:
n = p11.C_Encrypt
(session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
break;
case MODE_DECRYPT:
n = p11.C_Decrypt
(session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
break;
case MODE_SIGN:
byte[] tmpBuffer = new byte[bufOfs];
System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
if (tmpBuffer.length > outLen) {
throw new BadPaddingException(
"Output buffer (" + outLen + ") is too small to " +
"hold the produced data (" + tmpBuffer.length + ")");
}
System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
n = tmpBuffer.length;
break;
case MODE_VERIFY:
n = p11.C_VerifyRecover
(session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
break;
default:
throw new ProviderException("internal error");
}
return n;
} catch (PKCS11Exception e) {
throw (BadPaddingException)new BadPaddingException
("doFinal() failed").initCause(e);
} finally {
initialized = false;
session = token.releaseSession(session);
}
}
// see JCE spec
protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
implUpdate(in, inOfs, inLen);
return B0;
}
// see JCE spec
protected int engineUpdate(byte[] in, int inOfs, int inLen,
byte[] out, int outOfs) throws ShortBufferException {
implUpdate(in, inOfs, inLen);
return 0;
}
// see JCE spec
protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
throws IllegalBlockSizeException, BadPaddingException {
implUpdate(in, inOfs, inLen);
int n = implDoFinal(buffer, 0, buffer.length);
byte[] out = new byte[n];
System.arraycopy(buffer, 0, out, 0, n);
return out;
}
// see JCE spec
protected int engineDoFinal(byte[] in, int inOfs, int inLen,
byte[] out, int outOfs) throws ShortBufferException,
IllegalBlockSizeException, BadPaddingException {
implUpdate(in, inOfs, inLen);
return implDoFinal(out, outOfs, out.length - outOfs);
}
private byte[] doFinal() throws BadPaddingException,
IllegalBlockSizeException {
byte[] t = new byte[2048];
int n = implDoFinal(t, 0, t.length);
byte[] out = new byte[n];
System.arraycopy(t, 0, out, 0, n);
return out;
}
// see JCE spec
protected byte[] engineWrap(Key key) throws InvalidKeyException,
IllegalBlockSizeException {
String keyAlg = key.getAlgorithm();
P11Key sKey = null;
try {
// The conversion may fail, e.g. trying to wrap an AES key on
// a token that does not support AES, or when the key size is
// not within the range supported by the token.
sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
} catch (InvalidKeyException ike) {
byte[] toBeWrappedKey = key.getEncoded();
if (toBeWrappedKey == null) {
throw new InvalidKeyException
("wrap() failed, no encoding available", ike);
}
// Directly encrypt the key encoding when key conversion failed
implInit(Cipher.ENCRYPT_MODE, p11Key);
implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length);
try {
return doFinal();
} catch (BadPaddingException bpe) {
// should not occur
throw new InvalidKeyException("wrap() failed", bpe);
} finally {
// Restore original mode
implInit(Cipher.WRAP_MODE, p11Key);
}
}
Session s = null;
try {
s = token.getOpSession();
return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism),
p11Key.keyID, sKey.keyID);
} catch (PKCS11Exception e) {
throw new InvalidKeyException("wrap() failed", e);
} finally {
token.releaseSession(s);
}
}
// see JCE spec
@SuppressWarnings("deprecation")
protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
int type) throws InvalidKeyException, NoSuchAlgorithmException {
boolean isTlsRsaPremasterSecret =
algorithm.equals("TlsRsaPremasterSecret");
Exception failover = null;
// Should C_Unwrap be preferred for non-TLS RSA premaster secret?
if (token.supportsRawSecretKeyImport()) {
// XXX implement unwrap using C_Unwrap() for all keys
implInit(Cipher.DECRYPT_MODE, p11Key);
try {
if (wrappedKey.length > maxInputSize) {
throw new InvalidKeyException("Key is too long for unwrapping");
}
byte[] encoded = null;
implUpdate(wrappedKey, 0, wrappedKey.length);
try {
encoded = doFinal();
} catch (BadPaddingException e) {
if (isTlsRsaPremasterSecret) {
failover = e;
} else {
throw new InvalidKeyException("Unwrapping failed", e);
}
} catch (IllegalBlockSizeException e) {
// should not occur, handled with length check above
throw new InvalidKeyException("Unwrapping failed", e);
}
if (isTlsRsaPremasterSecret) {
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
throw new IllegalStateException(
"No TlsRsaPremasterSecretParameterSpec specified");
}
// polish the TLS premaster secret
TlsRsaPremasterSecretParameterSpec psps =
(TlsRsaPremasterSecretParameterSpec)spec;
encoded = KeyUtil.checkTlsPreMasterSecretKey(
psps.getClientVersion(), psps.getServerVersion(),
random, encoded, (failover != null));
}
return ConstructKeys.constructKey(encoded, algorithm, type);
} finally {
// Restore original mode
implInit(Cipher.UNWRAP_MODE, p11Key);
}
} else {
Session s = null;
SecretKey secretKey = null;
try {
try {
s = token.getObjSession();
long keyType = CKK_GENERIC_SECRET;
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
};
attributes = token.getAttributes(
O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
long keyID = token.p11.C_UnwrapKey(s.id(),
new CK_MECHANISM(mechanism), p11Key.keyID,
wrappedKey, attributes);
secretKey = P11Key.secretKey(s, keyID,
algorithm, 48 << 3, attributes);
} catch (PKCS11Exception e) {
if (isTlsRsaPremasterSecret) {
failover = e;
} else {
throw new InvalidKeyException("unwrap() failed", e);
}
}
if (isTlsRsaPremasterSecret) {
TlsRsaPremasterSecretParameterSpec psps =
(TlsRsaPremasterSecretParameterSpec)spec;
// Please use the tricky failover as the parameter so that
// smart compiler won't dispose the unused variable.
secretKey = polishPreMasterSecretKey(token, s,
failover, secretKey,
psps.getClientVersion(), psps.getServerVersion());
}
return secretKey;
} finally {
token.releaseSession(s);
}
}
}
// see JCE spec
protected int engineGetKeySize(Key key) throws InvalidKeyException {
int n = P11KeyFactory.convertKey(token, key, algorithm).length();
return n;
}
private static SecretKey polishPreMasterSecretKey(
Token token, Session session,
Exception failover, SecretKey unwrappedKey,
int clientVersion, int serverVersion) {
SecretKey newKey;
CK_VERSION version = new CK_VERSION(
(clientVersion >>> 8) & 0xFF, clientVersion & 0xFF);
try {
CK_ATTRIBUTE[] attributes = token.getAttributes(
O_GENERATE, CKO_SECRET_KEY,
CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
long keyID = token.p11.C_GenerateKey(session.id(),
new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version),
attributes);
newKey = P11Key.secretKey(session,
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
} catch (PKCS11Exception e) {
throw new ProviderException(
"Could not generate premaster secret", e);
}
return (failover == null) ? unwrappedKey : newKey;
}
}
final class ConstructKeys {
/**
* Construct a public key from its encoding.
*
* @param encodedKey the encoding of a public key.
*
* @param encodedKeyAlgorithm the algorithm the encodedKey is for.
*
* @return a public key constructed from the encodedKey.
*/
private static final PublicKey constructPublicKey(byte[] encodedKey,
String encodedKeyAlgorithm)
throws InvalidKeyException, NoSuchAlgorithmException {
try {
KeyFactory keyFactory =
KeyFactory.getInstance(encodedKeyAlgorithm);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
return keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchAlgorithmException("No installed providers " +
"can create keys for the " +
encodedKeyAlgorithm +
"algorithm", nsae);
} catch (InvalidKeySpecException ike) {
throw new InvalidKeyException("Cannot construct public key", ike);
}
}
/**
* Construct a private key from its encoding.
*
* @param encodedKey the encoding of a private key.
*
* @param encodedKeyAlgorithm the algorithm the wrapped key is for.
*
* @return a private key constructed from the encodedKey.
*/
private static final PrivateKey constructPrivateKey(byte[] encodedKey,
String encodedKeyAlgorithm) throws InvalidKeyException,
NoSuchAlgorithmException {
try {
KeyFactory keyFactory =
KeyFactory.getInstance(encodedKeyAlgorithm);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
return keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException nsae) {
throw new NoSuchAlgorithmException("No installed providers " +
"can create keys for the " +
encodedKeyAlgorithm +
"algorithm", nsae);
} catch (InvalidKeySpecException ike) {
throw new InvalidKeyException("Cannot construct private key", ike);
}
}
/**
* Construct a secret key from its encoding.
*
* @param encodedKey the encoding of a secret key.
*
* @param encodedKeyAlgorithm the algorithm the secret key is for.
*
* @return a secret key constructed from the encodedKey.
*/
private static final SecretKey constructSecretKey(byte[] encodedKey,
String encodedKeyAlgorithm) {
return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
}
static final Key constructKey(byte[] encoding, String keyAlgorithm,
int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
switch (keyType) {
case Cipher.SECRET_KEY:
return constructSecretKey(encoding, keyAlgorithm);
case Cipher.PRIVATE_KEY:
return constructPrivateKey(encoding, keyAlgorithm);
case Cipher.PUBLIC_KEY:
return constructPublicKey(encoding, keyAlgorithm);
default:
throw new InvalidKeyException("Unknown keytype " + keyType);
}
}
}

View file

@ -0,0 +1,325 @@
/*
* Copyright (c) 2003, 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 sun.security.pkcs11;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.rsa.RSAKeyFactory;
/**
* RSA KeyFactory implementation.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11RSAKeyFactory extends P11KeyFactory {
P11RSAKeyFactory(Token token, String algorithm) {
super(token, algorithm);
}
PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
try {
if (key instanceof RSAPublicKey) {
RSAPublicKey rsaKey = (RSAPublicKey)key;
return generatePublic(
rsaKey.getModulus(),
rsaKey.getPublicExponent()
);
} else if ("X.509".equals(key.getFormat())) {
// let SunRsaSign provider parse for us, then recurse
byte[] encoded = key.getEncoded();
key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
return implTranslatePublicKey(key);
} else {
throw new InvalidKeyException("PublicKey must be instance "
+ "of RSAPublicKey or have X.509 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create RSA public key", e);
}
}
PrivateKey implTranslatePrivateKey(PrivateKey key)
throws InvalidKeyException {
try {
if (key instanceof RSAPrivateCrtKey) {
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
return generatePrivate(
rsaKey.getModulus(),
rsaKey.getPublicExponent(),
rsaKey.getPrivateExponent(),
rsaKey.getPrimeP(),
rsaKey.getPrimeQ(),
rsaKey.getPrimeExponentP(),
rsaKey.getPrimeExponentQ(),
rsaKey.getCrtCoefficient()
);
} else if (key instanceof RSAPrivateKey) {
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
return generatePrivate(
rsaKey.getModulus(),
rsaKey.getPrivateExponent()
);
} else if ("PKCS#8".equals(key.getFormat())) {
// let SunRsaSign provider parse for us, then recurse
byte[] encoded = key.getEncoded();
key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
return implTranslatePrivateKey(key);
} else {
throw new InvalidKeyException("Private key must be instance "
+ "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
}
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create RSA private key", e);
}
}
// see JCA spec
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof X509EncodedKeySpec) {
try {
byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
PublicKey key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
return implTranslatePublicKey(key);
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException
("Could not create RSA public key", e);
}
}
if (keySpec instanceof RSAPublicKeySpec == false) {
throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
+ "X509EncodedKeySpec supported for RSA public keys");
}
try {
RSAPublicKeySpec rs = (RSAPublicKeySpec)keySpec;
return generatePublic(
rs.getModulus(),
rs.getPublicExponent()
);
} catch (PKCS11Exception | InvalidKeyException e) {
throw new InvalidKeySpecException
("Could not create RSA public key", e);
}
}
// see JCA spec
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec instanceof PKCS8EncodedKeySpec) {
try {
byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
PrivateKey key =
sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
return implTranslatePrivateKey(key);
} catch (GeneralSecurityException e) {
throw new InvalidKeySpecException
("Could not create RSA private key", e);
}
}
try {
if (keySpec instanceof RSAPrivateCrtKeySpec) {
RSAPrivateCrtKeySpec rs = (RSAPrivateCrtKeySpec)keySpec;
return generatePrivate(
rs.getModulus(),
rs.getPublicExponent(),
rs.getPrivateExponent(),
rs.getPrimeP(),
rs.getPrimeQ(),
rs.getPrimeExponentP(),
rs.getPrimeExponentQ(),
rs.getCrtCoefficient()
);
} else if (keySpec instanceof RSAPrivateKeySpec) {
RSAPrivateKeySpec rs = (RSAPrivateKeySpec)keySpec;
return generatePrivate(
rs.getModulus(),
rs.getPrivateExponent()
);
} else {
throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
+ "and PKCS8EncodedKeySpec supported for RSA private keys");
}
} catch (PKCS11Exception | InvalidKeyException e) {
throw new InvalidKeySpecException
("Could not create RSA private key", e);
}
}
private PublicKey generatePublic(BigInteger n, BigInteger e)
throws PKCS11Exception, InvalidKeyException {
RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
new CK_ATTRIBUTE(CKA_MODULUS, n),
new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PUBLIC_KEY, CKK_RSA, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.publicKey
(session, keyID, "RSA", n.bitLength(), attributes);
} finally {
token.releaseSession(session);
}
}
private PrivateKey generatePrivate(BigInteger n, BigInteger d)
throws PKCS11Exception, InvalidKeyException {
RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
new CK_ATTRIBUTE(CKA_MODULUS, n),
new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.privateKey
(session, keyID, "RSA", n.bitLength(), attributes);
} finally {
token.releaseSession(session);
}
}
private PrivateKey generatePrivate(BigInteger n, BigInteger e,
BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
BigInteger qe, BigInteger coeff) throws PKCS11Exception,
InvalidKeyException {
RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
new CK_ATTRIBUTE(CKA_MODULUS, n),
new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
new CK_ATTRIBUTE(CKA_PRIME_1, p),
new CK_ATTRIBUTE(CKA_PRIME_2, q),
new CK_ATTRIBUTE(CKA_EXPONENT_1, pe),
new CK_ATTRIBUTE(CKA_EXPONENT_2, qe),
new CK_ATTRIBUTE(CKA_COEFFICIENT, coeff),
};
attributes = token.getAttributes
(O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
Session session = null;
try {
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
return P11Key.privateKey
(session, keyID, "RSA", n.bitLength(), attributes);
} finally {
token.releaseSession(session);
}
}
<T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_MODULUS),
new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
KeySpec spec = new RSAPublicKeySpec(
attributes[0].getBigInteger(),
attributes[1].getBigInteger()
);
return keySpec.cast(spec);
} else { // X.509 handled in superclass
throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
+ "X509EncodedKeySpec supported for RSA public keys");
}
}
<T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
Session[] session) throws PKCS11Exception, InvalidKeySpecException {
if (RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_MODULUS),
new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
new CK_ATTRIBUTE(CKA_PRIME_1),
new CK_ATTRIBUTE(CKA_PRIME_2),
new CK_ATTRIBUTE(CKA_EXPONENT_1),
new CK_ATTRIBUTE(CKA_EXPONENT_2),
new CK_ATTRIBUTE(CKA_COEFFICIENT),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
KeySpec spec = new RSAPrivateCrtKeySpec(
attributes[0].getBigInteger(),
attributes[1].getBigInteger(),
attributes[2].getBigInteger(),
attributes[3].getBigInteger(),
attributes[4].getBigInteger(),
attributes[5].getBigInteger(),
attributes[6].getBigInteger(),
attributes[7].getBigInteger()
);
return keySpec.cast(spec);
} else if (RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
session[0] = token.getObjSession();
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_MODULUS),
new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
};
token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
KeySpec spec = new RSAPrivateKeySpec(
attributes[0].getBigInteger(),
attributes[1].getBigInteger()
);
return keySpec.cast(spec);
} else { // PKCS#8 handled in superclass
throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
+ "and PKCS8EncodedKeySpec supported for RSA private keys");
}
}
KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
return KeyFactory.getInstance("RSA", P11Util.getSunRsaSignProvider());
}
}

View file

@ -0,0 +1,358 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.util.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* SecretKeyFactory implementation class. This class currently supports
* DES, DESede, AES, ARCFOUR, and Blowfish.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11SecretKeyFactory extends SecretKeyFactorySpi {
// token instance
private final Token token;
// algorithm name
private final String algorithm;
P11SecretKeyFactory(Token token, String algorithm) {
super();
this.token = token;
this.algorithm = algorithm;
}
private static final Map<String,Long> keyTypes;
static {
keyTypes = new HashMap<String,Long>();
addKeyType("RC4", CKK_RC4);
addKeyType("ARCFOUR", CKK_RC4);
addKeyType("DES", CKK_DES);
addKeyType("DESede", CKK_DES3);
addKeyType("AES", CKK_AES);
addKeyType("Blowfish", CKK_BLOWFISH);
// we don't implement RC2 or IDEA, but we want to be able to generate
// keys for those SSL/TLS ciphersuites.
addKeyType("RC2", CKK_RC2);
addKeyType("IDEA", CKK_IDEA);
addKeyType("TlsPremasterSecret", PCKK_TLSPREMASTER);
addKeyType("TlsRsaPremasterSecret", PCKK_TLSRSAPREMASTER);
addKeyType("TlsMasterSecret", PCKK_TLSMASTER);
addKeyType("Generic", CKK_GENERIC_SECRET);
}
private static void addKeyType(String name, long id) {
Long l = Long.valueOf(id);
keyTypes.put(name, l);
keyTypes.put(name.toUpperCase(Locale.ENGLISH), l);
}
static long getKeyType(String algorithm) {
Long l = keyTypes.get(algorithm);
if (l == null) {
algorithm = algorithm.toUpperCase(Locale.ENGLISH);
l = keyTypes.get(algorithm);
if (l == null) {
if (algorithm.startsWith("HMAC")) {
return PCKK_HMAC;
} else if (algorithm.startsWith("SSLMAC")) {
return PCKK_SSLMAC;
}
}
}
return (l != null) ? l.longValue() : -1;
}
/**
* Convert an arbitrary key of algorithm into a P11Key of provider.
* Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init().
*/
static P11Key convertKey(Token token, Key key, String algo)
throws InvalidKeyException {
return convertKey(token, key, algo, null);
}
/**
* Convert an arbitrary key of algorithm w/ custom attributes into a
* P11Key of provider.
* Used in P11KeyStore.storeSkey.
*/
static P11Key convertKey(Token token, Key key, String algo,
CK_ATTRIBUTE[] extraAttrs)
throws InvalidKeyException {
token.ensureValid();
if (key == null) {
throw new InvalidKeyException("Key must not be null");
}
if (key instanceof SecretKey == false) {
throw new InvalidKeyException("Key must be a SecretKey");
}
long algoType;
if (algo == null) {
algo = key.getAlgorithm();
algoType = getKeyType(algo);
} else {
algoType = getKeyType(algo);
long keyAlgorithmType = getKeyType(key.getAlgorithm());
if (algoType != keyAlgorithmType) {
if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) {
// ignore key algorithm for MACs
} else {
throw new InvalidKeyException
("Key algorithm must be " + algo);
}
}
}
if (key instanceof P11Key) {
P11Key p11Key = (P11Key)key;
if (p11Key.token == token) {
if (extraAttrs != null) {
Session session = null;
try {
session = token.getObjSession();
long newKeyID = token.p11.C_CopyObject(session.id(),
p11Key.keyID, extraAttrs);
p11Key = (P11Key) (P11Key.secretKey(session,
newKeyID, p11Key.algorithm, p11Key.keyLength,
extraAttrs));
} catch (PKCS11Exception p11e) {
throw new InvalidKeyException
("Cannot duplicate the PKCS11 key", p11e);
} finally {
token.releaseSession(session);
}
}
return p11Key;
}
}
P11Key p11Key = token.secretCache.get(key);
if (p11Key != null) {
return p11Key;
}
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
throw new InvalidKeyException("Encoded format must be RAW");
}
byte[] encoded = key.getEncoded();
p11Key = createKey(token, encoded, algo, algoType, extraAttrs);
token.secretCache.put(key, p11Key);
return p11Key;
}
static void fixDESParity(byte[] key, int offset) {
for (int i = 0; i < 8; i++) {
int b = key[offset] & 0xfe;
b |= (Integer.bitCount(b) & 1) ^ 1;
key[offset++] = (byte)b;
}
}
private static P11Key createKey(Token token, byte[] encoded,
String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs)
throws InvalidKeyException {
int n = encoded.length << 3;
int keyLength = n;
try {
switch ((int)keyType) {
case (int)CKK_DES:
keyLength =
P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token);
fixDESParity(encoded, 0);
break;
case (int)CKK_DES3:
keyLength =
P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token);
fixDESParity(encoded, 0);
fixDESParity(encoded, 8);
if (keyLength == 112) {
keyType = CKK_DES2;
} else {
keyType = CKK_DES3;
fixDESParity(encoded, 16);
}
break;
case (int)CKK_AES:
keyLength =
P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token);
break;
case (int)CKK_RC4:
keyLength =
P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token);
break;
case (int)CKK_BLOWFISH:
keyLength =
P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n,
token);
break;
case (int)CKK_GENERIC_SECRET:
case (int)PCKK_TLSPREMASTER:
case (int)PCKK_TLSRSAPREMASTER:
case (int)PCKK_TLSMASTER:
keyType = CKK_GENERIC_SECRET;
break;
case (int)PCKK_SSLMAC:
case (int)PCKK_HMAC:
if (n == 0) {
throw new InvalidKeyException
("MAC keys must not be empty");
}
keyType = CKK_GENERIC_SECRET;
break;
default:
throw new InvalidKeyException("Unknown algorithm " +
algorithm);
}
} catch (InvalidAlgorithmParameterException iape) {
throw new InvalidKeyException("Invalid key for " + algorithm,
iape);
} catch (ProviderException pe) {
throw new InvalidKeyException("Could not create key", pe);
}
Session session = null;
try {
CK_ATTRIBUTE[] attributes;
if (extraAttrs != null) {
attributes = new CK_ATTRIBUTE[3 + extraAttrs.length];
System.arraycopy(extraAttrs, 0, attributes, 3,
extraAttrs.length);
} else {
attributes = new CK_ATTRIBUTE[3];
}
attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
attributes = token.getAttributes
(O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
session = token.getObjSession();
long keyID = token.p11.C_CreateObject(session.id(), attributes);
P11Key p11Key = (P11Key)P11Key.secretKey
(session, keyID, algorithm, keyLength, attributes);
return p11Key;
} catch (PKCS11Exception e) {
throw new InvalidKeyException("Could not create key", e);
} finally {
token.releaseSession(session);
}
}
// see JCE spec
protected SecretKey engineGenerateSecret(KeySpec keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if (keySpec == null) {
throw new InvalidKeySpecException("KeySpec must not be null");
}
if (keySpec instanceof SecretKeySpec) {
try {
Key key = convertKey(token, (SecretKey)keySpec, algorithm);
return (SecretKey)key;
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException(e);
}
} else if (algorithm.equalsIgnoreCase("DES")) {
if (keySpec instanceof DESKeySpec) {
byte[] keyBytes = ((DESKeySpec)keySpec).getKey();
keySpec = new SecretKeySpec(keyBytes, "DES");
return engineGenerateSecret(keySpec);
}
} else if (algorithm.equalsIgnoreCase("DESede")) {
if (keySpec instanceof DESedeKeySpec) {
byte[] keyBytes = ((DESedeKeySpec)keySpec).getKey();
keySpec = new SecretKeySpec(keyBytes, "DESede");
return engineGenerateSecret(keySpec);
}
}
throw new InvalidKeySpecException
("Unsupported spec: " + keySpec.getClass().getName());
}
private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException {
try {
key = engineTranslateKey(key);
if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
throw new InvalidKeySpecException
("Could not obtain key bytes");
}
byte[] k = key.getEncoded();
return k;
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException(e);
}
}
// see JCE spec
protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec)
throws InvalidKeySpecException {
token.ensureValid();
if ((key == null) || (keySpec == null)) {
throw new InvalidKeySpecException
("key and keySpec must not be null");
}
if (SecretKeySpec.class.isAssignableFrom(keySpec)) {
return new SecretKeySpec(getKeyBytes(key), algorithm);
} else if (algorithm.equalsIgnoreCase("DES")) {
try {
if (DESKeySpec.class.isAssignableFrom(keySpec)) {
return new DESKeySpec(getKeyBytes(key));
}
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException(e);
}
} else if (algorithm.equalsIgnoreCase("DESede")) {
try {
if (DESedeKeySpec.class.isAssignableFrom(keySpec)) {
return new DESedeKeySpec(getKeyBytes(key));
}
} catch (InvalidKeyException e) {
throw new InvalidKeySpecException(e);
}
}
throw new InvalidKeySpecException
("Unsupported spec: " + keySpec.getName());
}
// see JCE spec
protected SecretKey engineTranslateKey(SecretKey key)
throws InvalidKeyException {
return (SecretKey)convertKey(token, key, algorithm);
}
}

View file

@ -0,0 +1,200 @@
/*
* Copyright (c) 2003, 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 sun.security.pkcs11;
import java.io.*;
import java.security.*;
import sun.security.pkcs11.wrapper.*;
/**
* SecureRandom implementation class. Some tokens support only
* C_GenerateRandom() and not C_SeedRandom(). In order not to lose an
* application specified seed, we create a SHA1PRNG that we mix with in that
* case.
*
* Note that since SecureRandom is thread safe, we only need one
* instance per PKCS#11 token instance. It is created on demand and cached
* in the SunPKCS11 class.
*
* Also note that we obtain the PKCS#11 session on demand, no need to tie one
* up.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11SecureRandom extends SecureRandomSpi {
private static final long serialVersionUID = -8939510236124553291L;
// token instance
private final Token token;
// PRNG for mixing, non-null if active (i.e. setSeed() has been called)
private volatile SecureRandom mixRandom;
// buffer, if mixing is used
private byte[] mixBuffer;
// bytes remaining in mixBuffer, if mixing is used
private int buffered;
/*
* we buffer data internally for efficiency but limit the lifetime
* to avoid using stale bits.
*/
// lifetime in ms, currently 100 ms (0.1 s)
private static final long MAX_IBUFFER_TIME = 100;
// size of the internal buffer
private static final int IBUFFER_SIZE = 32;
// internal buffer for the random bits
private transient byte[] iBuffer = new byte[IBUFFER_SIZE];
// number of bytes remain in iBuffer
private transient int ibuffered = 0;
// time that data was read into iBuffer
private transient long lastRead = 0L;
P11SecureRandom(Token token) {
this.token = token;
}
// see JCA spec
@Override
protected synchronized void engineSetSeed(byte[] seed) {
if (seed == null) {
throw new NullPointerException("seed must not be null");
}
Session session = null;
try {
session = token.getOpSession();
token.p11.C_SeedRandom(session.id(), seed);
} catch (PKCS11Exception e) {
// cannot set seed
// let a SHA1PRNG use that seed instead
SecureRandom random = mixRandom;
if (random != null) {
random.setSeed(seed);
} else {
try {
mixBuffer = new byte[20];
random = SecureRandom.getInstance("SHA1PRNG");
// initialize object before assigning to class field
random.setSeed(seed);
mixRandom = random;
} catch (NoSuchAlgorithmException ee) {
throw new ProviderException(ee);
}
}
} finally {
token.releaseSession(session);
}
}
// see JCA spec
@Override
protected void engineNextBytes(byte[] bytes) {
if ((bytes == null) || (bytes.length == 0)) {
return;
}
if (bytes.length <= IBUFFER_SIZE) {
int ofs = 0;
synchronized (iBuffer) {
while (ofs < bytes.length) {
long time = System.currentTimeMillis();
// refill the internal buffer if empty or stale
if ((ibuffered == 0) ||
!(time - lastRead < MAX_IBUFFER_TIME)) {
lastRead = time;
implNextBytes(iBuffer);
ibuffered = IBUFFER_SIZE;
}
// copy the buffered bytes into 'bytes'
while ((ofs < bytes.length) && (ibuffered > 0)) {
bytes[ofs++] = iBuffer[IBUFFER_SIZE - ibuffered--];
}
}
}
} else {
// avoid using the buffer - just fill bytes directly
implNextBytes(bytes);
}
}
// see JCA spec
@Override
protected byte[] engineGenerateSeed(int numBytes) {
byte[] b = new byte[numBytes];
engineNextBytes(b);
return b;
}
private void mix(byte[] b) {
SecureRandom random = mixRandom;
if (random == null) {
// avoid mixing if setSeed() has never been called
return;
}
synchronized (this) {
int ofs = 0;
int len = b.length;
while (len-- > 0) {
if (buffered == 0) {
random.nextBytes(mixBuffer);
buffered = mixBuffer.length;
}
b[ofs++] ^= mixBuffer[mixBuffer.length - buffered];
buffered--;
}
}
}
// fill up the specified buffer with random bytes, and mix them
private void implNextBytes(byte[] bytes) {
Session session = null;
try {
session = token.getOpSession();
token.p11.C_GenerateRandom(session.id(), bytes);
mix(bytes);
} catch (PKCS11Exception e) {
throw new ProviderException("nextBytes() failed", e);
} finally {
token.releaseSession(session);
}
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
// assign default values to non-null transient fields
iBuffer = new byte[IBUFFER_SIZE];
ibuffered = 0;
lastRead = 0L;
}
}

View file

@ -0,0 +1,833 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.*;
import java.security.interfaces.*;
import sun.nio.ch.DirectBuffer;
import sun.security.util.*;
import sun.security.x509.AlgorithmId;
import sun.security.rsa.RSASignature;
import sun.security.rsa.RSAPadding;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.KeyUtil;
/**
* Signature implementation class. This class currently supports the
* following algorithms:
*
* . DSA
* . NONEwithDSA (RawDSA)
* . SHA1withDSA
* . NONEwithDSAinP1363Format (RawDSAinP1363Format)
* . SHA1withDSAinP1363Format
* . RSA:
* . MD2withRSA
* . MD5withRSA
* . SHA1withRSA
* . SHA224withRSA
* . SHA256withRSA
* . SHA384withRSA
* . SHA512withRSA
* . ECDSA
* . NONEwithECDSA
* . SHA1withECDSA
* . SHA224withECDSA
* . SHA256withECDSA
* . SHA384withECDSA
* . SHA512withECDSA
* . NONEwithECDSAinP1363Format
* . SHA1withECDSAinP1363Format
* . SHA224withECDSAinP1363Format
* . SHA256withECDSAinP1363Format
* . SHA384withECDSAinP1363Format
* . SHA512withECDSAinP1363Format
*
* Note that the underlying PKCS#11 token may support complete signature
* algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just
* implement the signature algorithm without hashing (e.g. CKM_DSA, CKM_PKCS),
* or it may only implement the raw public key operation (CKM_RSA_X_509).
* This class uses what is available and adds whatever extra processing
* is needed.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class P11Signature extends SignatureSpi {
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// name of the key algorithm, currently either RSA or DSA
private final String keyAlgorithm;
// mechanism id
private final long mechanism;
// digest algorithm OID, if we encode RSA signature ourselves
private final ObjectIdentifier digestOID;
// type, one of T_* below
private final int type;
// key instance used, if init*() was called
private P11Key p11Key;
// message digest, if we do the digesting ourselves
private final MessageDigest md;
// associated session, if any
private Session session;
// mode, one of M_* below
private int mode;
// flag indicating whether an operation is initialized
private boolean initialized;
// buffer, for update(byte) or DSA
private final byte[] buffer;
// total number of bytes processed in current operation
private int bytesProcessed;
// The format, to be used for DSA and ECDSA signatures.
// If true, the IEEE P1363 format will be used, the concatenation of
// r and s. If false (default), the signature will be formatted as a
// DER-encoded ASN.1 sequence of r and s.
private boolean p1363Format = false;
// constant for signing mode
private final static int M_SIGN = 1;
// constant for verification mode
private final static int M_VERIFY = 2;
// constant for type digesting, we do the hashing ourselves
private final static int T_DIGEST = 1;
// constant for type update, token does everything
private final static int T_UPDATE = 2;
// constant for type raw, used with RawDSA and NONEwithECDSA only
private final static int T_RAW = 3;
// XXX PKCS#11 v2.20 says "should not be longer than 1024 bits",
// but this is a little arbitrary
private final static int RAW_ECDSA_MAX = 128;
P11Signature(Token token, String algorithm, long mechanism)
throws NoSuchAlgorithmException, PKCS11Exception {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
byte[] buffer = null;
ObjectIdentifier digestOID = null;
MessageDigest md = null;
switch ((int)mechanism) {
case (int)CKM_MD2_RSA_PKCS:
case (int)CKM_MD5_RSA_PKCS:
case (int)CKM_SHA1_RSA_PKCS:
case (int)CKM_SHA224_RSA_PKCS:
case (int)CKM_SHA256_RSA_PKCS:
case (int)CKM_SHA384_RSA_PKCS:
case (int)CKM_SHA512_RSA_PKCS:
keyAlgorithm = "RSA";
type = T_UPDATE;
buffer = new byte[1];
break;
case (int)CKM_DSA_SHA1:
keyAlgorithm = "DSA";
type = T_UPDATE;
buffer = new byte[1];
break;
case (int)CKM_ECDSA_SHA1:
keyAlgorithm = "EC";
type = T_UPDATE;
buffer = new byte[1];
break;
case (int)CKM_DSA:
keyAlgorithm = "DSA";
if (algorithm.equals("DSA") ||
algorithm.equals("DSAinP1363Format")) {
type = T_DIGEST;
md = MessageDigest.getInstance("SHA-1");
} else if (algorithm.equals("RawDSA") ||
algorithm.equals("RawDSAinP1363Format")) {
type = T_RAW;
buffer = new byte[20];
} else {
throw new ProviderException(algorithm);
}
break;
case (int)CKM_ECDSA:
keyAlgorithm = "EC";
if (algorithm.equals("NONEwithECDSA") ||
algorithm.equals("NONEwithECDSAinP1363Format")) {
type = T_RAW;
buffer = new byte[RAW_ECDSA_MAX];
} else {
String digestAlg;
if (algorithm.equals("SHA1withECDSA") ||
algorithm.equals("SHA1withECDSAinP1363Format")) {
digestAlg = "SHA-1";
} else if (algorithm.equals("SHA224withECDSA") ||
algorithm.equals("SHA224withECDSAinP1363Format")) {
digestAlg = "SHA-224";
} else if (algorithm.equals("SHA256withECDSA") ||
algorithm.equals("SHA256withECDSAinP1363Format")) {
digestAlg = "SHA-256";
} else if (algorithm.equals("SHA384withECDSA") ||
algorithm.equals("SHA384withECDSAinP1363Format")) {
digestAlg = "SHA-384";
} else if (algorithm.equals("SHA512withECDSA") ||
algorithm.equals("SHA512withECDSAinP1363Format")) {
digestAlg = "SHA-512";
} else {
throw new ProviderException(algorithm);
}
type = T_DIGEST;
md = MessageDigest.getInstance(digestAlg);
}
break;
case (int)CKM_RSA_PKCS:
case (int)CKM_RSA_X_509:
keyAlgorithm = "RSA";
type = T_DIGEST;
if (algorithm.equals("MD5withRSA")) {
md = MessageDigest.getInstance("MD5");
digestOID = AlgorithmId.MD5_oid;
} else if (algorithm.equals("SHA1withRSA")) {
md = MessageDigest.getInstance("SHA-1");
digestOID = AlgorithmId.SHA_oid;
} else if (algorithm.equals("MD2withRSA")) {
md = MessageDigest.getInstance("MD2");
digestOID = AlgorithmId.MD2_oid;
} else if (algorithm.equals("SHA224withRSA")) {
md = MessageDigest.getInstance("SHA-224");
digestOID = AlgorithmId.SHA224_oid;
} else if (algorithm.equals("SHA256withRSA")) {
md = MessageDigest.getInstance("SHA-256");
digestOID = AlgorithmId.SHA256_oid;
} else if (algorithm.equals("SHA384withRSA")) {
md = MessageDigest.getInstance("SHA-384");
digestOID = AlgorithmId.SHA384_oid;
} else if (algorithm.equals("SHA512withRSA")) {
md = MessageDigest.getInstance("SHA-512");
digestOID = AlgorithmId.SHA512_oid;
} else {
throw new ProviderException("Unknown signature: " + algorithm);
}
break;
default:
throw new ProviderException("Unknown mechanism: " + mechanism);
}
this.buffer = buffer;
this.digestOID = digestOID;
this.md = md;
if (algorithm.endsWith("inP1363Format")) {
this.p1363Format = true;
}
}
private void ensureInitialized() {
token.ensureValid();
if (initialized == false) {
initialize();
}
}
private void cancelOperation() {
token.ensureValid();
if (initialized == false) {
return;
}
initialized = false;
if ((session == null) || (token.explicitCancel == false)) {
return;
}
if (session.hasObjects() == false) {
session = token.killSession(session);
return;
}
// "cancel" operation by finishing it
// XXX make sure all this always works correctly
if (mode == M_SIGN) {
try {
if (type == T_UPDATE) {
token.p11.C_SignFinal(session.id(), 0);
} else {
byte[] digest;
if (type == T_DIGEST) {
digest = md.digest();
} else { // T_RAW
digest = buffer;
}
token.p11.C_Sign(session.id(), digest);
}
} catch (PKCS11Exception e) {
throw new ProviderException("cancel failed", e);
}
} else { // M_VERIFY
try {
byte[] signature;
if (keyAlgorithm.equals("DSA")) {
signature = new byte[40];
} else {
signature = new byte[(p11Key.length() + 7) >> 3];
}
if (type == T_UPDATE) {
token.p11.C_VerifyFinal(session.id(), signature);
} else {
byte[] digest;
if (type == T_DIGEST) {
digest = md.digest();
} else { // T_RAW
digest = buffer;
}
token.p11.C_Verify(session.id(), digest, signature);
}
} catch (PKCS11Exception e) {
// will fail since the signature is incorrect
// XXX check error code
}
}
}
// assumes current state is initialized == false
private void initialize() {
try {
if (session == null) {
session = token.getOpSession();
}
if (mode == M_SIGN) {
token.p11.C_SignInit(session.id(),
new CK_MECHANISM(mechanism), p11Key.keyID);
} else {
token.p11.C_VerifyInit(session.id(),
new CK_MECHANISM(mechanism), p11Key.keyID);
}
initialized = true;
} catch (PKCS11Exception e) {
throw new ProviderException("Initialization failed", e);
}
if (bytesProcessed != 0) {
bytesProcessed = 0;
if (md != null) {
md.reset();
}
}
}
private void checkKeySize(String keyAlgo, Key key)
throws InvalidKeyException {
CK_MECHANISM_INFO mechInfo = null;
try {
mechInfo = token.getMechanismInfo(mechanism);
} catch (PKCS11Exception e) {
// should not happen, ignore for now.
}
if (mechInfo == null) {
// skip the check if no native info available
return;
}
int minKeySize = (int) mechInfo.ulMinKeySize;
int maxKeySize = (int) mechInfo.ulMaxKeySize;
// need to override the MAX keysize for SHA1withDSA
if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
maxKeySize = 1024;
}
int keySize = 0;
if (key instanceof P11Key) {
keySize = ((P11Key) key).length();
} else {
if (keyAlgo.equals("RSA")) {
keySize = ((RSAKey) key).getModulus().bitLength();
} else if (keyAlgo.equals("DSA")) {
keySize = ((DSAKey) key).getParams().getP().bitLength();
} else if (keyAlgo.equals("EC")) {
keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
} else {
throw new ProviderException("Error: unsupported algo " + keyAlgo);
}
}
if ((minKeySize != -1) && (keySize < minKeySize)) {
throw new InvalidKeyException(keyAlgo +
" key must be at least " + minKeySize + " bits");
}
if ((maxKeySize != -1) && (keySize > maxKeySize)) {
throw new InvalidKeyException(keyAlgo +
" key must be at most " + maxKeySize + " bits");
}
if (keyAlgo.equals("RSA")) {
checkRSAKeyLength(keySize);
}
}
private void checkRSAKeyLength(int len) throws InvalidKeyException {
RSAPadding padding;
try {
padding = RSAPadding.getInstance
(RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
} catch (InvalidAlgorithmParameterException iape) {
throw new InvalidKeyException(iape.getMessage());
}
int maxDataSize = padding.getMaxDataSize();
int encodedLength;
if (algorithm.equals("MD5withRSA") ||
algorithm.equals("MD2withRSA")) {
encodedLength = 34;
} else if (algorithm.equals("SHA1withRSA")) {
encodedLength = 35;
} else if (algorithm.equals("SHA224withRSA")) {
encodedLength = 47;
} else if (algorithm.equals("SHA256withRSA")) {
encodedLength = 51;
} else if (algorithm.equals("SHA384withRSA")) {
encodedLength = 67;
} else if (algorithm.equals("SHA512withRSA")) {
encodedLength = 83;
} else {
throw new ProviderException("Unknown signature algo: " + algorithm);
}
if (encodedLength > maxDataSize) {
throw new InvalidKeyException
("Key is too short for this signature algorithm");
}
}
// see JCA spec
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException {
if (publicKey == null) {
throw new InvalidKeyException("Key must not be null");
}
// Need to check key length whenever a new key is set
if (publicKey != p11Key) {
checkKeySize(keyAlgorithm, publicKey);
}
cancelOperation();
mode = M_VERIFY;
p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
initialize();
}
// see JCA spec
protected void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException {
if (privateKey == null) {
throw new InvalidKeyException("Key must not be null");
}
// Need to check RSA key length whenever a new key is set
if (privateKey != p11Key) {
checkKeySize(keyAlgorithm, privateKey);
}
cancelOperation();
mode = M_SIGN;
p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
initialize();
}
// see JCA spec
protected void engineUpdate(byte b) throws SignatureException {
ensureInitialized();
switch (type) {
case T_UPDATE:
buffer[0] = b;
engineUpdate(buffer, 0, 1);
break;
case T_DIGEST:
md.update(b);
bytesProcessed++;
break;
case T_RAW:
if (bytesProcessed >= buffer.length) {
bytesProcessed = buffer.length + 1;
return;
}
buffer[bytesProcessed++] = b;
break;
default:
throw new ProviderException("Internal error");
}
}
// see JCA spec
protected void engineUpdate(byte[] b, int ofs, int len)
throws SignatureException {
ensureInitialized();
if (len == 0) {
return;
}
switch (type) {
case T_UPDATE:
try {
if (mode == M_SIGN) {
token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
} else {
token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
}
bytesProcessed += len;
} catch (PKCS11Exception e) {
throw new ProviderException(e);
}
break;
case T_DIGEST:
md.update(b, ofs, len);
bytesProcessed += len;
break;
case T_RAW:
if (bytesProcessed + len > buffer.length) {
bytesProcessed = buffer.length + 1;
return;
}
System.arraycopy(b, ofs, buffer, bytesProcessed, len);
bytesProcessed += len;
break;
default:
throw new ProviderException("Internal error");
}
}
// see JCA spec
protected void engineUpdate(ByteBuffer byteBuffer) {
ensureInitialized();
int len = byteBuffer.remaining();
if (len <= 0) {
return;
}
switch (type) {
case T_UPDATE:
if (byteBuffer instanceof DirectBuffer == false) {
// cannot do better than default impl
super.engineUpdate(byteBuffer);
return;
}
long addr = ((DirectBuffer)byteBuffer).address();
int ofs = byteBuffer.position();
try {
if (mode == M_SIGN) {
token.p11.C_SignUpdate
(session.id(), addr + ofs, null, 0, len);
} else {
token.p11.C_VerifyUpdate
(session.id(), addr + ofs, null, 0, len);
}
bytesProcessed += len;
byteBuffer.position(ofs + len);
} catch (PKCS11Exception e) {
throw new ProviderException("Update failed", e);
}
break;
case T_DIGEST:
md.update(byteBuffer);
bytesProcessed += len;
break;
case T_RAW:
if (bytesProcessed + len > buffer.length) {
bytesProcessed = buffer.length + 1;
return;
}
byteBuffer.get(buffer, bytesProcessed, len);
bytesProcessed += len;
break;
default:
throw new ProviderException("Internal error");
}
}
// see JCA spec
protected byte[] engineSign() throws SignatureException {
ensureInitialized();
try {
byte[] signature;
if (type == T_UPDATE) {
int len = keyAlgorithm.equals("DSA") ? 40 : 0;
signature = token.p11.C_SignFinal(session.id(), len);
} else {
byte[] digest;
if (type == T_DIGEST) {
digest = md.digest();
} else { // T_RAW
if (mechanism == CKM_DSA) {
if (bytesProcessed != buffer.length) {
throw new SignatureException
("Data for RawDSA must be exactly 20 bytes long");
}
digest = buffer;
} else { // CKM_ECDSA
if (bytesProcessed > buffer.length) {
throw new SignatureException("Data for NONEwithECDSA"
+ " must be at most " + RAW_ECDSA_MAX + " bytes long");
}
digest = new byte[bytesProcessed];
System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
}
}
if (keyAlgorithm.equals("RSA") == false) {
// DSA and ECDSA
signature = token.p11.C_Sign(session.id(), digest);
} else { // RSA
byte[] data = encodeSignature(digest);
if (mechanism == CKM_RSA_X_509) {
data = pkcs1Pad(data);
}
signature = token.p11.C_Sign(session.id(), data);
}
}
if (keyAlgorithm.equals("RSA")) {
return signature;
} else {
if (p1363Format) {
return signature;
} else {
return dsaToASN1(signature);
}
}
} catch (PKCS11Exception pe) {
throw new ProviderException(pe);
} catch (SignatureException | ProviderException e) {
cancelOperation();
throw e;
} finally {
initialized = false;
session = token.releaseSession(session);
}
}
// see JCA spec
protected boolean engineVerify(byte[] signature) throws SignatureException {
ensureInitialized();
try {
if (!p1363Format) {
if (keyAlgorithm.equals("DSA")) {
signature = asn1ToDSA(signature);
} else if (keyAlgorithm.equals("EC")) {
signature = asn1ToECDSA(signature);
}
}
if (type == T_UPDATE) {
token.p11.C_VerifyFinal(session.id(), signature);
} else {
byte[] digest;
if (type == T_DIGEST) {
digest = md.digest();
} else { // T_RAW
if (mechanism == CKM_DSA) {
if (bytesProcessed != buffer.length) {
throw new SignatureException
("Data for RawDSA must be exactly 20 bytes long");
}
digest = buffer;
} else {
if (bytesProcessed > buffer.length) {
throw new SignatureException("Data for NONEwithECDSA"
+ " must be at most " + RAW_ECDSA_MAX + " bytes long");
}
digest = new byte[bytesProcessed];
System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
}
}
if (keyAlgorithm.equals("RSA") == false) {
// DSA and ECDSA
token.p11.C_Verify(session.id(), digest, signature);
} else { // RSA
byte[] data = encodeSignature(digest);
if (mechanism == CKM_RSA_X_509) {
data = pkcs1Pad(data);
}
token.p11.C_Verify(session.id(), data, signature);
}
}
return true;
} catch (PKCS11Exception pe) {
long errorCode = pe.getErrorCode();
if (errorCode == CKR_SIGNATURE_INVALID) {
return false;
}
if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
// return false rather than throwing an exception
return false;
}
// ECF bug?
if (errorCode == CKR_DATA_LEN_RANGE) {
return false;
}
throw new ProviderException(pe);
} catch (SignatureException | ProviderException e) {
cancelOperation();
throw e;
} finally {
initialized = false;
session = token.releaseSession(session);
}
}
private byte[] pkcs1Pad(byte[] data) {
try {
int len = (p11Key.length() + 7) >> 3;
RSAPadding padding = RSAPadding.getInstance
(RSAPadding.PAD_BLOCKTYPE_1, len);
byte[] padded = padding.pad(data);
return padded;
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
}
}
private byte[] encodeSignature(byte[] digest) throws SignatureException {
try {
return RSASignature.encodeSignature(digestOID, digest);
} catch (IOException e) {
throw new SignatureException("Invalid encoding", e);
}
}
// private static byte[] decodeSignature(byte[] signature) throws IOException {
// return RSASignature.decodeSignature(digestOID, signature);
// }
// For DSA and ECDSA signatures, PKCS#11 represents them as a simple
// byte array that contains the concatenation of r and s.
// For DSA, r and s are always exactly 20 bytes long.
// For ECDSA, r and s are of variable length, but we know that each
// occupies half of the array.
private static byte[] dsaToASN1(byte[] signature) {
int n = signature.length >> 1;
BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
try {
DerOutputStream outseq = new DerOutputStream(100);
outseq.putInteger(r);
outseq.putInteger(s);
DerValue result = new DerValue(DerValue.tag_Sequence,
outseq.toByteArray());
return result.toByteArray();
} catch (java.io.IOException e) {
throw new RuntimeException("Internal error", e);
}
}
private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {
try {
// Enforce strict DER checking for signatures
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
DerValue[] values = in.getSequence(2);
// check number of components in the read sequence
// and trailing data
if ((values.length != 2) || (in.available() != 0)) {
throw new IOException("Invalid encoding for signature");
}
BigInteger r = values[0].getPositiveBigInteger();
BigInteger s = values[1].getPositiveBigInteger();
byte[] br = toByteArray(r, 20);
byte[] bs = toByteArray(s, 20);
if ((br == null) || (bs == null)) {
throw new SignatureException("Out of range value for R or S");
}
return P11Util.concat(br, bs);
} catch (SignatureException e) {
throw e;
} catch (Exception e) {
throw new SignatureException("Invalid encoding for signature", e);
}
}
private byte[] asn1ToECDSA(byte[] sig) throws SignatureException {
try {
// Enforce strict DER checking for signatures
DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
DerValue[] values = in.getSequence(2);
// check number of components in the read sequence
// and trailing data
if ((values.length != 2) || (in.available() != 0)) {
throw new IOException("Invalid encoding for signature");
}
BigInteger r = values[0].getPositiveBigInteger();
BigInteger s = values[1].getPositiveBigInteger();
// trim leading zeroes
byte[] br = KeyUtil.trimZeroes(r.toByteArray());
byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
int k = Math.max(br.length, bs.length);
// r and s each occupy half the array
byte[] res = new byte[k << 1];
System.arraycopy(br, 0, res, k - br.length, br.length);
System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
return res;
} catch (Exception e) {
throw new SignatureException("Invalid encoding for signature", e);
}
}
private static byte[] toByteArray(BigInteger bi, int len) {
byte[] b = bi.toByteArray();
int n = b.length;
if (n == len) {
return b;
}
if ((n == len + 1) && (b[0] == 0)) {
byte[] t = new byte[len];
System.arraycopy(b, 1, t, 0, len);
return t;
}
if (n > len) {
return null;
}
// must be smaller
byte[] t = new byte[len];
System.arraycopy(b, 0, t, (len - n), n);
return t;
}
// see JCA spec
@SuppressWarnings("deprecation")
protected void engineSetParameter(String param, Object value)
throws InvalidParameterException {
throw new UnsupportedOperationException("setParameter() not supported");
}
// see JCA spec
@SuppressWarnings("deprecation")
protected Object engineGetParameter(String param)
throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported");
}
}

View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.util.*;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import javax.crypto.spec.*;
import sun.security.internal.spec.*;
import sun.security.internal.interfaces.TlsMasterSecret;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* KeyGenerator to calculate the SSL/TLS key material (cipher keys and ivs,
* mac keys) from the master secret.
*
* @author Andreas Sterbenz
* @since 1.6
*/
public final class P11TlsKeyMaterialGenerator extends KeyGeneratorSpi {
private final static String MSG = "TlsKeyMaterialGenerator must be "
+ "initialized using a TlsKeyMaterialParameterSpec";
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private long mechanism;
// parameter spec
@SuppressWarnings("deprecation")
private TlsKeyMaterialParameterSpec spec;
// master secret as a P11Key
private P11Key p11Key;
// whether SSLv3 is supported
private final boolean supportSSLv3;
P11TlsKeyMaterialGenerator(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
// Given the current lookup order specified in SunPKCS11.java,
// if CKM_SSL3_KEY_AND_MAC_DERIVE is not used to construct this object,
// it means that this mech is disabled or unsupported.
this.supportSSLv3 = (mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE);
}
protected void engineInit(SecureRandom random) {
throw new InvalidParameterException(MSG);
}
@SuppressWarnings("deprecation")
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (params instanceof TlsKeyMaterialParameterSpec == false) {
throw new InvalidAlgorithmParameterException(MSG);
}
TlsKeyMaterialParameterSpec spec = (TlsKeyMaterialParameterSpec)params;
int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
(version > 0x0302)) {
throw new InvalidAlgorithmParameterException
("Only" + (supportSSLv3? " SSL 3.0,": "") +
" TLS 1.0, and TLS 1.1 are supported (0x" +
Integer.toHexString(version) + ")");
}
try {
p11Key = P11SecretKeyFactory.convertKey
(token, spec.getMasterSecret(), "TlsMasterSecret");
} catch (InvalidKeyException e) {
throw new InvalidAlgorithmParameterException("init() failed", e);
}
this.spec = spec;
this.mechanism = (version == 0x0300)?
CKM_SSL3_KEY_AND_MAC_DERIVE : CKM_TLS_KEY_AND_MAC_DERIVE;
}
protected void engineInit(int keysize, SecureRandom random) {
throw new InvalidParameterException(MSG);
}
@SuppressWarnings("deprecation")
protected SecretKey engineGenerateKey() {
if (spec == null) {
throw new IllegalStateException
("TlsKeyMaterialGenerator must be initialized");
}
int macBits = spec.getMacKeyLength() << 3;
int ivBits = spec.getIvLength() << 3;
int expandedKeyBits = spec.getExpandedCipherKeyLength() << 3;
int keyBits = spec.getCipherKeyLength() << 3;
boolean isExportable;
if (expandedKeyBits != 0) {
isExportable = true;
} else {
isExportable = false;
expandedKeyBits = keyBits;
}
CK_SSL3_RANDOM_DATA random = new CK_SSL3_RANDOM_DATA
(spec.getClientRandom(), spec.getServerRandom());
CK_SSL3_KEY_MAT_PARAMS params = new CK_SSL3_KEY_MAT_PARAMS
(macBits, keyBits, ivBits, isExportable, random);
String cipherAlgorithm = spec.getCipherAlgorithm();
long keyType = P11SecretKeyFactory.getKeyType(cipherAlgorithm);
if (keyType < 0) {
if (keyBits != 0) {
throw new ProviderException
("Unknown algorithm: " + spec.getCipherAlgorithm());
} else {
// NULL encryption ciphersuites
keyType = CKK_GENERIC_SECRET;
}
}
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes;
if (keyBits != 0) {
attributes = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
new CK_ATTRIBUTE(CKA_VALUE_LEN, expandedKeyBits >> 3),
};
} else {
// ciphersuites with NULL ciphers
attributes = new CK_ATTRIBUTE[0];
}
attributes = token.getAttributes
(O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
// the returned keyID is a dummy, ignore
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
CK_SSL3_KEY_MAT_OUT out = params.pReturnedKeyMaterial;
// Note that the MAC keys do not inherit all attributes from the
// template, but they do inherit the sensitive/extractable/token
// flags, which is all P11Key cares about.
SecretKey clientMacKey, serverMacKey;
// The MAC size may be zero for GCM mode.
//
// PKCS11 does not support GCM mode as the author made the comment,
// so the macBits is unlikely to be zero. It's only a place holder.
if (macBits != 0) {
clientMacKey = P11Key.secretKey
(session, out.hClientMacSecret, "MAC", macBits, attributes);
serverMacKey = P11Key.secretKey
(session, out.hServerMacSecret, "MAC", macBits, attributes);
} else {
clientMacKey = null;
serverMacKey = null;
}
SecretKey clientCipherKey, serverCipherKey;
if (keyBits != 0) {
clientCipherKey = P11Key.secretKey(session, out.hClientKey,
cipherAlgorithm, expandedKeyBits, attributes);
serverCipherKey = P11Key.secretKey(session, out.hServerKey,
cipherAlgorithm, expandedKeyBits, attributes);
} else {
clientCipherKey = null;
serverCipherKey = null;
}
IvParameterSpec clientIv = (out.pIVClient == null)
? null : new IvParameterSpec(out.pIVClient);
IvParameterSpec serverIv = (out.pIVServer == null)
? null : new IvParameterSpec(out.pIVServer);
return new TlsKeyMaterialSpec(clientMacKey, serverMacKey,
clientCipherKey, clientIv, serverCipherKey, serverIv);
} catch (Exception e) {
throw new ProviderException("Could not generate key", e);
} finally {
token.releaseSession(session);
}
}
}

View file

@ -0,0 +1,169 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import javax.crypto.spec.*;
import sun.security.internal.spec.TlsMasterSecretParameterSpec;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* KeyGenerator for the SSL/TLS master secret.
*
* @author Andreas Sterbenz
* @since 1.6
*/
public final class P11TlsMasterSecretGenerator extends KeyGeneratorSpi {
private final static String MSG = "TlsMasterSecretGenerator must be "
+ "initialized using a TlsMasterSecretParameterSpec";
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private long mechanism;
@SuppressWarnings("deprecation")
private TlsMasterSecretParameterSpec spec;
private P11Key p11Key;
CK_VERSION ckVersion;
// whether SSLv3 is supported
private final boolean supportSSLv3;
P11TlsMasterSecretGenerator(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
// Given the current lookup order specified in SunPKCS11.java, if
// CKM_SSL3_MASTER_KEY_DERIVE is not used to construct this object,
// it means that this mech is disabled or unsupported.
supportSSLv3 = (mechanism == CKM_SSL3_MASTER_KEY_DERIVE);
}
protected void engineInit(SecureRandom random) {
throw new InvalidParameterException(MSG);
}
@SuppressWarnings("deprecation")
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (params instanceof TlsMasterSecretParameterSpec == false) {
throw new InvalidAlgorithmParameterException(MSG);
}
TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params;
int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
(version > 0x0302)) {
throw new InvalidAlgorithmParameterException
("Only" + (supportSSLv3? " SSL 3.0,": "") +
" TLS 1.0, and TLS 1.1 are supported (0x" +
Integer.toHexString(version) + ")");
}
SecretKey key = spec.getPremasterSecret();
// algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret,
// but we omit the check
try {
p11Key = P11SecretKeyFactory.convertKey(token, key, null);
} catch (InvalidKeyException e) {
throw new InvalidAlgorithmParameterException("init() failed", e);
}
this.spec = spec;
if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) {
mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE
: CKM_TLS_MASTER_KEY_DERIVE;
ckVersion = new CK_VERSION(0, 0);
} else {
// Note: we use DH for all non-RSA premaster secrets. That includes
// Kerberos. That should not be a problem because master secret
// calculation is always a straightforward application of the
// TLS PRF (or the SSL equivalent).
// The only thing special about RSA master secret calculation is
// that it extracts the version numbers from the premaster secret.
mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE_DH
: CKM_TLS_MASTER_KEY_DERIVE_DH;
ckVersion = null;
}
}
protected void engineInit(int keysize, SecureRandom random) {
throw new InvalidParameterException(MSG);
}
protected SecretKey engineGenerateKey() {
if (spec == null) {
throw new IllegalStateException
("TlsMasterSecretGenerator must be initialized");
}
byte[] clientRandom = spec.getClientRandom();
byte[] serverRandom = spec.getServerRandom();
CK_SSL3_RANDOM_DATA random =
new CK_SSL3_RANDOM_DATA(clientRandom, serverRandom);
CK_SSL3_MASTER_KEY_DERIVE_PARAMS params =
new CK_SSL3_MASTER_KEY_DERIVE_PARAMS(random, ckVersion);
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = token.getAttributes(O_GENERATE,
CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
int major, minor;
if (params.pVersion == null) {
major = -1;
minor = -1;
} else {
major = params.pVersion.major;
minor = params.pVersion.minor;
}
SecretKey key = P11Key.masterSecretKey(session, keyID,
"TlsMasterSecret", 48 << 3, attributes, major, minor);
return key;
} catch (Exception e) {
throw new ProviderException("Could not generate key", e);
} finally {
token.releaseSession(session);
}
}
}

View file

@ -0,0 +1,169 @@
/*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import javax.crypto.spec.*;
import sun.security.internal.spec.TlsPrfParameterSpec;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* KeyGenerator for the TLS PRF. Note that although the PRF is used in a number
* of places during the handshake, this class is usually only used to calculate
* the Finished messages. The reason is that for those other uses more specific
* PKCS#11 mechanisms have been defined (CKM_SSL3_MASTER_KEY_DERIVE, etc.).
*
* <p>This class supports the CKM_TLS_PRF mechanism from PKCS#11 v2.20 and
* the older NSS private mechanism.
*
* @author Andreas Sterbenz
* @since 1.6
*/
final class P11TlsPrfGenerator extends KeyGeneratorSpi {
private final static String MSG =
"TlsPrfGenerator must be initialized using a TlsPrfParameterSpec";
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private final long mechanism;
@SuppressWarnings("deprecation")
private TlsPrfParameterSpec spec;
private P11Key p11Key;
P11TlsPrfGenerator(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
}
protected void engineInit(SecureRandom random) {
throw new InvalidParameterException(MSG);
}
@SuppressWarnings("deprecation")
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (params instanceof TlsPrfParameterSpec == false) {
throw new InvalidAlgorithmParameterException(MSG);
}
this.spec = (TlsPrfParameterSpec)params;
SecretKey key = spec.getSecret();
if (key == null) {
key = NULL_KEY;
}
try {
p11Key = P11SecretKeyFactory.convertKey(token, key, null);
} catch (InvalidKeyException e) {
throw new InvalidAlgorithmParameterException("init() failed", e);
}
}
// SecretKeySpec does not allow zero length keys, so we define our
// own class.
//
// As an anonymous class cannot make any guarantees about serialization
// compatibility, it is nonsensical for an anonymous class to define a
// serialVersionUID. Suppress warnings relative to missing serialVersionUID
// field in the anonymous subclass of serializable SecretKey.
@SuppressWarnings("serial")
private static final SecretKey NULL_KEY = new SecretKey() {
public byte[] getEncoded() {
return new byte[0];
}
public String getFormat() {
return "RAW";
}
public String getAlgorithm() {
return "Generic";
}
};
protected void engineInit(int keysize, SecureRandom random) {
throw new InvalidParameterException(MSG);
}
protected SecretKey engineGenerateKey() {
if (spec == null) {
throw new IllegalStateException("TlsPrfGenerator must be initialized");
}
byte[] label = P11Util.getBytesUTF8(spec.getLabel());
byte[] seed = spec.getSeed();
if (mechanism == CKM_NSS_TLS_PRF_GENERAL) {
Session session = null;
try {
session = token.getOpSession();
token.p11.C_SignInit
(session.id(), new CK_MECHANISM(mechanism), p11Key.keyID);
token.p11.C_SignUpdate(session.id(), 0, label, 0, label.length);
token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length);
byte[] out = token.p11.C_SignFinal
(session.id(), spec.getOutputLength());
return new SecretKeySpec(out, "TlsPrf");
} catch (PKCS11Exception e) {
throw new ProviderException("Could not calculate PRF", e);
} finally {
token.releaseSession(session);
}
}
// mechanism == CKM_TLS_PRF
byte[] out = new byte[spec.getOutputLength()];
CK_TLS_PRF_PARAMS params = new CK_TLS_PRF_PARAMS(seed, label, out);
Session session = null;
try {
session = token.getOpSession();
long keyID = token.p11.C_DeriveKey(session.id(),
new CK_MECHANISM(mechanism, params), p11Key.keyID, null);
// ignore keyID, returned PRF bytes are in 'out'
return new SecretKeySpec(out, "TlsPrf");
} catch (PKCS11Exception e) {
throw new ProviderException("Could not calculate PRF", e);
} finally {
token.releaseSession(session);
}
}
}

View file

@ -0,0 +1,137 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.*;
import javax.crypto.spec.*;
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
import static sun.security.pkcs11.TemplateManager.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* KeyGenerator for the SSL/TLS RSA premaster secret.
*
* @author Andreas Sterbenz
* @since 1.6
*/
final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
private final static String MSG = "TlsRsaPremasterSecretGenerator must be "
+ "initialized using a TlsRsaPremasterSecretParameterSpec";
// token instance
private final Token token;
// algorithm name
private final String algorithm;
// mechanism id
private long mechanism;
@SuppressWarnings("deprecation")
private TlsRsaPremasterSecretParameterSpec spec;
// whether SSLv3 is supported
private final boolean supportSSLv3;
P11TlsRsaPremasterSecretGenerator(Token token, String algorithm, long mechanism)
throws PKCS11Exception {
super();
this.token = token;
this.algorithm = algorithm;
this.mechanism = mechanism;
// Given the current lookup order specified in SunPKCS11.java,
// if CKM_SSL3_PRE_MASTER_KEY_GEN is not used to construct this object,
// it means that this mech is disabled or unsupported.
this.supportSSLv3 = (mechanism == CKM_SSL3_PRE_MASTER_KEY_GEN);
}
protected void engineInit(SecureRandom random) {
throw new InvalidParameterException(MSG);
}
@SuppressWarnings("deprecation")
protected void engineInit(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
throw new InvalidAlgorithmParameterException(MSG);
}
TlsRsaPremasterSecretParameterSpec spec =
(TlsRsaPremasterSecretParameterSpec) params;
int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
(version > 0x0302)) {
throw new InvalidAlgorithmParameterException
("Only" + (supportSSLv3? " SSL 3.0,": "") +
" TLS 1.0, and TLS 1.1 are supported (0x" +
Integer.toHexString(version) + ")");
}
this.spec = spec;
}
protected void engineInit(int keysize, SecureRandom random) {
throw new InvalidParameterException(MSG);
}
// Only can be used in client side to generate TLS RSA premaster secret.
protected SecretKey engineGenerateKey() {
if (spec == null) {
throw new IllegalStateException
("TlsRsaPremasterSecretGenerator must be initialized");
}
CK_VERSION version = new CK_VERSION(
spec.getMajorVersion(), spec.getMinorVersion());
Session session = null;
try {
session = token.getObjSession();
CK_ATTRIBUTE[] attributes = token.getAttributes(
O_GENERATE, CKO_SECRET_KEY,
CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
long keyID = token.p11.C_GenerateKey(session.id(),
new CK_MECHANISM(mechanism, version), attributes);
SecretKey key = P11Key.secretKey(session,
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
return key;
} catch (PKCS11Exception e) {
throw new ProviderException(
"Could not generate premaster secret", e);
} finally {
token.releaseSession(session);
}
}
}

View file

@ -0,0 +1,182 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.math.BigInteger;
import java.security.*;
/**
* Collection of static utility methods.
*
* @author Andreas Sterbenz
* @since 1.5
*/
public final class P11Util {
private static Object LOCK = new Object();
private static volatile Provider sun, sunRsaSign, sunJce;
private P11Util() {
// empty
}
static Provider getSunProvider() {
Provider p = sun;
if (p == null) {
synchronized (LOCK) {
p = getProvider
(sun, "SUN", "sun.security.provider.Sun");
sun = p;
}
}
return p;
}
static Provider getSunRsaSignProvider() {
Provider p = sunRsaSign;
if (p == null) {
synchronized (LOCK) {
p = getProvider
(sunRsaSign, "SunRsaSign", "sun.security.rsa.SunRsaSign");
sunRsaSign = p;
}
}
return p;
}
static Provider getSunJceProvider() {
Provider p = sunJce;
if (p == null) {
synchronized (LOCK) {
p = getProvider
(sunJce, "SunJCE", "com.sun.crypto.provider.SunJCE");
sunJce = p;
}
}
return p;
}
private static Provider getProvider(Provider p, String providerName,
String className) {
if (p != null) {
return p;
}
p = Security.getProvider(providerName);
if (p == null) {
try {
@SuppressWarnings("deprecation")
Object o = Class.forName(className).newInstance();
p = (Provider)o;
} catch (Exception e) {
throw new ProviderException
("Could not find provider " + providerName, e);
}
}
return p;
}
static byte[] convert(byte[] input, int offset, int len) {
if ((offset == 0) && (len == input.length)) {
return input;
} else {
byte[] t = new byte[len];
System.arraycopy(input, offset, t, 0, len);
return t;
}
}
static byte[] subarray(byte[] b, int ofs, int len) {
byte[] out = new byte[len];
System.arraycopy(b, ofs, out, 0, len);
return out;
}
static byte[] concat(byte[] b1, byte[] b2) {
byte[] b = new byte[b1.length + b2.length];
System.arraycopy(b1, 0, b, 0, b1.length);
System.arraycopy(b2, 0, b, b1.length, b2.length);
return b;
}
static long[] concat(long[] b1, long[] b2) {
if (b1.length == 0) {
return b2;
}
long[] b = new long[b1.length + b2.length];
System.arraycopy(b1, 0, b, 0, b1.length);
System.arraycopy(b2, 0, b, b1.length, b2.length);
return b;
}
public static byte[] getMagnitude(BigInteger bi) {
byte[] b = bi.toByteArray();
if ((b.length > 1) && (b[0] == 0)) {
int n = b.length - 1;
byte[] newarray = new byte[n];
System.arraycopy(b, 1, newarray, 0, n);
b = newarray;
}
return b;
}
static byte[] getBytesUTF8(String s) {
try {
return s.getBytes("UTF8");
} catch (java.io.UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
static byte[] sha1(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(data);
return md.digest();
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
}
}
private final static char[] hexDigits = "0123456789abcdef".toCharArray();
static String toString(byte[] b) {
if (b == null) {
return "(null)";
}
StringBuilder sb = new StringBuilder(b.length * 3);
for (int i = 0; i < b.length; i++) {
int k = b[i] & 0xff;
if (i != 0) {
sb.append(':');
}
sb.append(hexDigits[k >>> 4]);
sb.append(hexDigits[k & 0xf]);
}
return sb.toString();
}
}

View file

@ -0,0 +1,787 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.io.*;
import java.util.*;
import java.security.*;
import java.security.KeyStore.*;
import java.security.cert.X509Certificate;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* The Secmod class defines the interface to the native NSS
* library and the configuration information it stores in its
* secmod.db file.
*
* <p>Example code:
* <pre>
* Secmod secmod = Secmod.getInstance();
* if (secmod.isInitialized() == false) {
* secmod.initialize("/home/myself/.mozilla");
* }
*
* Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider();
* KeyStore ks = KeyStore.getInstance("PKCS11", p);
* ks.load(null, password);
* </pre>
*
* @since 1.6
* @author Andreas Sterbenz
*/
public final class Secmod {
private final static boolean DEBUG = false;
private final static Secmod INSTANCE;
static {
sun.security.pkcs11.wrapper.PKCS11.loadNative();
INSTANCE = new Secmod();
}
private final static String NSS_LIB_NAME = "nss3";
private final static String SOFTTOKEN_LIB_NAME = "softokn3";
private final static String TRUST_LIB_NAME = "nssckbi";
// handle to be passed to the native code, 0 means not initialized
private long nssHandle;
// whether this is a supported version of NSS
private boolean supported;
// list of the modules
private List<Module> modules;
private String configDir;
private String nssLibDir;
private Secmod() {
// empty
}
/**
* Return the singleton Secmod instance.
*/
public static Secmod getInstance() {
return INSTANCE;
}
private boolean isLoaded() {
if (nssHandle == 0) {
nssHandle = nssGetLibraryHandle(System.mapLibraryName(NSS_LIB_NAME));
if (nssHandle != 0) {
fetchVersions();
}
}
return (nssHandle != 0);
}
private void fetchVersions() {
supported = nssVersionCheck(nssHandle, "3.7");
}
/**
* Test whether this Secmod has been initialized. Returns true
* if NSS has been initialized using either the initialize() method
* or by directly calling the native NSS APIs. The latter may be
* the case if the current process contains components that use
* NSS directly.
*
* @throws IOException if an incompatible version of NSS
* has been loaded
*/
public synchronized boolean isInitialized() throws IOException {
// NSS does not allow us to check if it is initialized already
// assume that if it is loaded it is also initialized
if (isLoaded() == false) {
return false;
}
if (supported == false) {
throw new IOException
("An incompatible version of NSS is already loaded, "
+ "3.7 or later required");
}
return true;
}
String getConfigDir() {
return configDir;
}
String getLibDir() {
return nssLibDir;
}
/**
* Initialize this Secmod.
*
* @param configDir the directory containing the NSS configuration
* files such as secmod.db
* @param nssLibDir the directory containing the NSS libraries
* (libnss3.so or nss3.dll) or null if the library is on
* the system default shared library path
*
* @throws IOException if NSS has already been initialized,
* the specified directories are invalid, or initialization
* fails for any other reason
*/
public void initialize(String configDir, String nssLibDir)
throws IOException {
initialize(DbMode.READ_WRITE, configDir, nssLibDir, false);
}
public void initialize(DbMode dbMode, String configDir, String nssLibDir)
throws IOException {
initialize(dbMode, configDir, nssLibDir, false);
}
public synchronized void initialize(DbMode dbMode, String configDir,
String nssLibDir, boolean nssOptimizeSpace) throws IOException {
if (isInitialized()) {
throw new IOException("NSS is already initialized");
}
if (dbMode == null) {
throw new NullPointerException();
}
if ((dbMode != DbMode.NO_DB) && (configDir == null)) {
throw new NullPointerException();
}
String platformLibName = System.mapLibraryName("nss3");
String platformPath;
if (nssLibDir == null) {
platformPath = platformLibName;
} else {
File base = new File(nssLibDir);
if (base.isDirectory() == false) {
throw new IOException("nssLibDir must be a directory:" + nssLibDir);
}
File platformFile = new File(base, platformLibName);
if (platformFile.isFile() == false) {
throw new FileNotFoundException(platformFile.getPath());
}
platformPath = platformFile.getPath();
}
if (configDir != null) {
File configBase = new File(configDir);
if (configBase.isDirectory() == false ) {
throw new IOException("configDir must be a directory: " + configDir);
}
File secmodFile = new File(configBase, "secmod.db");
if (secmodFile.isFile() == false) {
throw new FileNotFoundException(secmodFile.getPath());
}
}
if (DEBUG) System.out.println("lib: " + platformPath);
nssHandle = nssLoadLibrary(platformPath);
if (DEBUG) System.out.println("handle: " + nssHandle);
fetchVersions();
if (supported == false) {
throw new IOException
("The specified version of NSS is incompatible, "
+ "3.7 or later required");
}
if (DEBUG) System.out.println("dir: " + configDir);
boolean initok = nssInitialize(dbMode.functionName, nssHandle,
configDir, nssOptimizeSpace);
if (DEBUG) System.out.println("init: " + initok);
if (initok == false) {
throw new IOException("NSS initialization failed");
}
this.configDir = configDir;
this.nssLibDir = nssLibDir;
}
/**
* Return an immutable list of all available modules.
*
* @throws IllegalStateException if this Secmod is misconfigured
* or not initialized
*/
public synchronized List<Module> getModules() {
try {
if (isInitialized() == false) {
throw new IllegalStateException("NSS not initialized");
}
} catch (IOException e) {
// IOException if misconfigured
throw new IllegalStateException(e);
}
if (modules == null) {
@SuppressWarnings("unchecked")
List<Module> modules = (List<Module>)nssGetModuleList(nssHandle,
nssLibDir);
this.modules = Collections.unmodifiableList(modules);
}
return modules;
}
private static byte[] getDigest(X509Certificate cert, String algorithm) {
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
return md.digest(cert.getEncoded());
} catch (GeneralSecurityException e) {
throw new ProviderException(e);
}
}
boolean isTrusted(X509Certificate cert, TrustType trustType) {
Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
TrustAttributes attr = getModuleTrust(ModuleType.KEYSTORE, bytes);
if (attr == null) {
attr = getModuleTrust(ModuleType.FIPS, bytes);
if (attr == null) {
attr = getModuleTrust(ModuleType.TRUSTANCHOR, bytes);
}
}
return (attr == null) ? false : attr.isTrusted(trustType);
}
private TrustAttributes getModuleTrust(ModuleType type, Bytes bytes) {
Module module = getModule(type);
TrustAttributes t = (module == null) ? null : module.getTrust(bytes);
return t;
}
/**
* Constants describing the different types of NSS modules.
* For this API, NSS modules are classified as either one
* of the internal modules delivered as part of NSS or
* as an external module provided by a 3rd party.
*/
public static enum ModuleType {
/**
* The NSS Softtoken crypto module. This is the first
* slot of the softtoken object.
* This module provides
* implementations for cryptographic algorithms but no KeyStore.
*/
CRYPTO,
/**
* The NSS Softtoken KeyStore module. This is the second
* slot of the softtoken object.
* This module provides
* implementations for cryptographic algorithms (after login)
* and the KeyStore.
*/
KEYSTORE,
/**
* The NSS Softtoken module in FIPS mode. Note that in FIPS mode the
* softtoken presents only one slot, not separate CRYPTO and KEYSTORE
* slots as in non-FIPS mode.
*/
FIPS,
/**
* The NSS builtin trust anchor module. This is the
* NSSCKBI object. It provides no crypto functions.
*/
TRUSTANCHOR,
/**
* An external module.
*/
EXTERNAL,
}
/**
* Returns the first module of the specified type. If no such
* module exists, this method returns null.
*
* @throws IllegalStateException if this Secmod is misconfigured
* or not initialized
*/
public Module getModule(ModuleType type) {
for (Module module : getModules()) {
if (module.getType() == type) {
return module;
}
}
return null;
}
static final String TEMPLATE_EXTERNAL =
"library = %s\n"
+ "name = \"%s\"\n"
+ "slotListIndex = %d\n";
static final String TEMPLATE_TRUSTANCHOR =
"library = %s\n"
+ "name = \"NSS Trust Anchors\"\n"
+ "slotListIndex = 0\n"
+ "enabledMechanisms = { KeyStore }\n"
+ "nssUseSecmodTrust = true\n";
static final String TEMPLATE_CRYPTO =
"library = %s\n"
+ "name = \"NSS SoftToken Crypto\"\n"
+ "slotListIndex = 0\n"
+ "disabledMechanisms = { KeyStore }\n";
static final String TEMPLATE_KEYSTORE =
"library = %s\n"
+ "name = \"NSS SoftToken KeyStore\"\n"
+ "slotListIndex = 1\n"
+ "nssUseSecmodTrust = true\n";
static final String TEMPLATE_FIPS =
"library = %s\n"
+ "name = \"NSS FIPS SoftToken\"\n"
+ "slotListIndex = 0\n"
+ "nssUseSecmodTrust = true\n";
/**
* A representation of one PKCS#11 slot in a PKCS#11 module.
*/
public static final class Module {
// path of the native library
final String libraryName;
// descriptive name used by NSS
final String commonName;
final int slot;
final ModuleType type;
private String config;
private SunPKCS11 provider;
// trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only
private Map<Bytes,TrustAttributes> trust;
Module(String libraryDir, String libraryName, String commonName,
boolean fips, int slot) {
ModuleType type;
if ((libraryName == null) || (libraryName.length() == 0)) {
// must be softtoken
libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME);
if (fips == false) {
type = (slot == 0) ? ModuleType.CRYPTO : ModuleType.KEYSTORE;
} else {
type = ModuleType.FIPS;
if (slot != 0) {
throw new RuntimeException
("Slot index should be 0 for FIPS slot");
}
}
} else {
if (libraryName.endsWith(System.mapLibraryName(TRUST_LIB_NAME))
|| commonName.equals("Builtin Roots Module")) {
type = ModuleType.TRUSTANCHOR;
} else {
type = ModuleType.EXTERNAL;
}
if (fips) {
throw new RuntimeException("FIPS flag set for non-internal "
+ "module: " + libraryName + ", " + commonName);
}
}
// On Ubuntu the libsoftokn3 library is located in a subdirectory
// of the system libraries directory. (Since Ubuntu 11.04.)
File libraryFile = new File(libraryDir, libraryName);
if (!libraryFile.isFile()) {
File failover = new File(libraryDir, "nss/" + libraryName);
if (failover.isFile()) {
libraryFile = failover;
}
}
this.libraryName = libraryFile.getPath();
this.commonName = commonName;
this.slot = slot;
this.type = type;
initConfiguration();
}
private void initConfiguration() {
switch (type) {
case EXTERNAL:
config = String.format(TEMPLATE_EXTERNAL, libraryName,
commonName + " " + slot, slot);
break;
case CRYPTO:
config = String.format(TEMPLATE_CRYPTO, libraryName);
break;
case KEYSTORE:
config = String.format(TEMPLATE_KEYSTORE, libraryName);
break;
case FIPS:
config = String.format(TEMPLATE_FIPS, libraryName);
break;
case TRUSTANCHOR:
config = String.format(TEMPLATE_TRUSTANCHOR, libraryName);
break;
default:
throw new RuntimeException("Unknown module type: " + type);
}
}
/**
* Get the configuration for this module. This is a string
* in the SunPKCS11 configuration format. It can be
* customized with additional options and then made
* current using the setConfiguration() method.
*/
@Deprecated
public synchronized String getConfiguration() {
return config;
}
/**
* Set the configuration for this module.
*
* @throws IllegalStateException if the associated provider
* instance has already been created.
*/
@Deprecated
public synchronized void setConfiguration(String config) {
if (provider != null) {
throw new IllegalStateException("Provider instance already created");
}
this.config = config;
}
/**
* Return the pathname of the native library that implements
* this module. For example, /usr/lib/libpkcs11.so.
*/
public String getLibraryName() {
return libraryName;
}
/**
* Returns the type of this module.
*/
public ModuleType getType() {
return type;
}
/**
* Returns the provider instance that is associated with this
* module. The first call to this method creates the provider
* instance.
*/
@Deprecated
public synchronized Provider getProvider() {
if (provider == null) {
provider = newProvider();
}
return provider;
}
synchronized boolean hasInitializedProvider() {
return provider != null;
}
void setProvider(SunPKCS11 p) {
if (provider != null) {
throw new ProviderException("Secmod provider already initialized");
}
provider = p;
}
private SunPKCS11 newProvider() {
try {
return new SunPKCS11(new Config("--" + config));
} catch (Exception e) {
// XXX
throw new ProviderException(e);
}
}
synchronized void setTrust(Token token, X509Certificate cert) {
Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
TrustAttributes attr = getTrust(bytes);
if (attr == null) {
attr = new TrustAttributes(token, cert, bytes, CKT_NETSCAPE_TRUSTED_DELEGATOR);
trust.put(bytes, attr);
} else {
// does it already have the correct trust settings?
if (attr.isTrusted(TrustType.ALL) == false) {
// XXX not yet implemented
throw new ProviderException("Cannot change existing trust attributes");
}
}
}
TrustAttributes getTrust(Bytes hash) {
if (trust == null) {
// If provider is not set, create a temporary provider to
// retrieve the trust information. This can happen if we need
// to get the trust information for the trustanchor module
// because we need to look for user customized settings in the
// keystore module (which may not have a provider created yet).
// Creating a temporary provider and then dropping it on the
// floor immediately is flawed, but it's the best we can do
// for now.
synchronized (this) {
SunPKCS11 p = provider;
if (p == null) {
p = newProvider();
}
try {
trust = Secmod.getTrust(p);
} catch (PKCS11Exception e) {
throw new RuntimeException(e);
}
}
}
return trust.get(hash);
}
public String toString() {
return
commonName + " (" + type + ", " + libraryName + ", slot " + slot + ")";
}
}
/**
* Constants representing NSS trust categories.
*/
public static enum TrustType {
/** Trusted for all purposes */
ALL,
/** Trusted for SSL client authentication */
CLIENT_AUTH,
/** Trusted for SSL server authentication */
SERVER_AUTH,
/** Trusted for code signing */
CODE_SIGNING,
/** Trusted for email protection */
EMAIL_PROTECTION,
}
public static enum DbMode {
READ_WRITE("NSS_InitReadWrite"),
READ_ONLY ("NSS_Init"),
NO_DB ("NSS_NoDB_Init");
final String functionName;
DbMode(String functionName) {
this.functionName = functionName;
}
}
/**
* A LoadStoreParameter for use with the NSS Softtoken or
* NSS TrustAnchor KeyStores.
* <p>
* It allows the set of trusted certificates that are returned by
* the KeyStore to be specified.
*/
public static final class KeyStoreLoadParameter implements LoadStoreParameter {
final TrustType trustType;
final ProtectionParameter protection;
public KeyStoreLoadParameter(TrustType trustType, char[] password) {
this(trustType, new PasswordProtection(password));
}
public KeyStoreLoadParameter(TrustType trustType, ProtectionParameter prot) {
if (trustType == null) {
throw new NullPointerException("trustType must not be null");
}
this.trustType = trustType;
this.protection = prot;
}
public ProtectionParameter getProtectionParameter() {
return protection;
}
public TrustType getTrustType() {
return trustType;
}
}
static class TrustAttributes {
final long handle;
final long clientAuth, serverAuth, codeSigning, emailProtection;
final byte[] shaHash;
TrustAttributes(Token token, X509Certificate cert, Bytes bytes, long trustValue) {
Session session = null;
try {
session = token.getOpSession();
// XXX use KeyStore TrustType settings to determine which
// attributes to set
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_TOKEN, true),
new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH, trustValue),
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING, trustValue),
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, trustValue),
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH, trustValue),
new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH, bytes.b),
new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_MD5_HASH, getDigest(cert, "MD5")),
new CK_ATTRIBUTE(CKA_ISSUER, cert.getIssuerX500Principal().getEncoded()),
new CK_ATTRIBUTE(CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray()),
// XXX per PKCS#11 spec, the serial number should be in ASN.1
};
handle = token.p11.C_CreateObject(session.id(), attrs);
shaHash = bytes.b;
clientAuth = trustValue;
serverAuth = trustValue;
codeSigning = trustValue;
emailProtection = trustValue;
} catch (PKCS11Exception e) {
throw new ProviderException("Could not create trust object", e);
} finally {
token.releaseSession(session);
}
}
TrustAttributes(Token token, Session session, long handle)
throws PKCS11Exception {
this.handle = handle;
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH),
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING),
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION),
new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH),
};
token.p11.C_GetAttributeValue(session.id(), handle, attrs);
serverAuth = attrs[0].getLong();
codeSigning = attrs[1].getLong();
emailProtection = attrs[2].getLong();
shaHash = attrs[3].getByteArray();
attrs = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH),
};
long c;
try {
token.p11.C_GetAttributeValue(session.id(), handle, attrs);
c = attrs[0].getLong();
} catch (PKCS11Exception e) {
// trust anchor module does not support this attribute
c = serverAuth;
}
clientAuth = c;
}
Bytes getHash() {
return new Bytes(shaHash);
}
boolean isTrusted(TrustType type) {
switch (type) {
case CLIENT_AUTH:
return isTrusted(clientAuth);
case SERVER_AUTH:
return isTrusted(serverAuth);
case CODE_SIGNING:
return isTrusted(codeSigning);
case EMAIL_PROTECTION:
return isTrusted(emailProtection);
case ALL:
return isTrusted(TrustType.CLIENT_AUTH)
&& isTrusted(TrustType.SERVER_AUTH)
&& isTrusted(TrustType.CODE_SIGNING)
&& isTrusted(TrustType.EMAIL_PROTECTION);
default:
return false;
}
}
private boolean isTrusted(long l) {
// XXX CKT_TRUSTED?
return (l == CKT_NETSCAPE_TRUSTED_DELEGATOR);
}
}
private static class Bytes {
final byte[] b;
Bytes(byte[] b) {
this.b = b;
}
public int hashCode() {
return Arrays.hashCode(b);
}
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o instanceof Bytes == false) {
return false;
}
Bytes other = (Bytes)o;
return Arrays.equals(this.b, other.b);
}
}
private static Map<Bytes,TrustAttributes> getTrust(SunPKCS11 provider)
throws PKCS11Exception {
Map<Bytes,TrustAttributes> trustMap = new HashMap<Bytes,TrustAttributes>();
Token token = provider.getToken();
Session session = null;
boolean exceptionOccurred = true;
try {
session = token.getOpSession();
int MAX_NUM = 8192;
CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
};
token.p11.C_FindObjectsInit(session.id(), attrs);
long[] handles = token.p11.C_FindObjects(session.id(), MAX_NUM);
token.p11.C_FindObjectsFinal(session.id());
if (DEBUG) System.out.println("handles: " + handles.length);
for (long handle : handles) {
try {
TrustAttributes trust = new TrustAttributes(token, session, handle);
trustMap.put(trust.getHash(), trust);
} catch (PKCS11Exception e) {
// skip put on pkcs11 error
}
}
exceptionOccurred = false;
} finally {
if (exceptionOccurred) {
token.killSession(session);
} else {
token.releaseSession(session);
}
}
return trustMap;
}
private static native long nssGetLibraryHandle(String libraryName);
private static native long nssLoadLibrary(String name) throws IOException;
private static native boolean nssVersionCheck(long handle, String minVersion);
private static native boolean nssInitialize(String functionName, long handle, String configDir, boolean nssOptimizeSpace);
private static native Object nssGetModuleList(long handle, String libDir);
}

View file

@ -0,0 +1,189 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.lang.ref.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.security.*;
import sun.security.pkcs11.wrapper.*;
/**
* A session object. Sessions are obtained via the SessionManager,
* see there for details. Most code will only ever need one method in
* this class, the id() method to obtain the session id.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class Session implements Comparable<Session> {
// time after which to close idle sessions, in milliseconds (3 minutes)
private final static long MAX_IDLE_TIME = 3 * 60 * 1000;
// token instance
final Token token;
// session id
private final long id;
// number of objects created within this session
private final AtomicInteger createdObjects;
// time this session was last used
// not synchronized/volatile for performance, so may be unreliable
// this could lead to idle sessions being closed early, but that is harmless
private long lastAccess;
private final SessionRef sessionRef;
Session(Token token, long id) {
this.token = token;
this.id = id;
createdObjects = new AtomicInteger();
id();
sessionRef = new SessionRef(this, id, token);
}
public int compareTo(Session other) {
if (this.lastAccess == other.lastAccess) {
return 0;
} else {
return (this.lastAccess < other.lastAccess) ? -1 : 1;
}
}
boolean isLive(long currentTime) {
return currentTime - lastAccess < MAX_IDLE_TIME;
}
long idInternal() {
return id;
}
long id() {
if (token.isPresent(this.id) == false) {
throw new ProviderException("Token has been removed");
}
lastAccess = System.currentTimeMillis();
return id;
}
void addObject() {
int n = createdObjects.incrementAndGet();
// XXX update statistics in session manager if n == 1
}
void removeObject() {
int n = createdObjects.decrementAndGet();
if (n == 0) {
token.sessionManager.demoteObjSession(this);
} else if (n < 0) {
throw new ProviderException("Internal error: objects created " + n);
}
}
boolean hasObjects() {
return createdObjects.get() != 0;
}
void close() {
if (hasObjects()) {
throw new ProviderException(
"Internal error: close session with active objects");
}
sessionRef.dispose();
}
}
/*
* NOTE: Use PhantomReference here and not WeakReference
* otherwise the sessions maybe closed before other objects
* which are still being finalized.
*/
final class SessionRef extends PhantomReference<Session>
implements Comparable<SessionRef> {
private static ReferenceQueue<Session> refQueue =
new ReferenceQueue<Session>();
private static Set<SessionRef> refList =
Collections.synchronizedSortedSet(new TreeSet<SessionRef>());
static ReferenceQueue<Session> referenceQueue() {
return refQueue;
}
static int totalCount() {
return refList.size();
}
private static void drainRefQueueBounded() {
while (true) {
SessionRef next = (SessionRef) refQueue.poll();
if (next == null) break;
next.dispose();
}
}
// handle to the native session
private long id;
private Token token;
SessionRef(Session session, long id, Token token) {
super(session, refQueue);
this.id = id;
this.token = token;
refList.add(this);
// TBD: run at some interval and not every time?
drainRefQueueBounded();
}
void dispose() {
refList.remove(this);
try {
if (token.isPresent(id)) {
token.p11.C_CloseSession(id);
}
} catch (PKCS11Exception e1) {
// ignore
} catch (ProviderException e2) {
// ignore
} finally {
this.clear();
}
}
public int compareTo(SessionRef other) {
if (this.id == other.id) {
return 0;
} else {
return (this.id < other.id) ? -1 : 1;
}
}
}

View file

@ -0,0 +1,296 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.util.*;
import java.security.ProviderException;
import sun.security.util.Debug;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Session manager. There is one session manager object per PKCS#11
* provider. It allows code to checkout a session, release it
* back to the pool, or force it to be closed.
*
* The session manager pools sessions to minimize the number of
* C_OpenSession() and C_CloseSession() that have to be made. It
* maintains two pools: one for "object" sessions and one for
* "operation" sessions.
*
* The reason for this separation is how PKCS#11 deals with session objects.
* It defines that when a session is closed, all objects created within
* that session are destroyed. In other words, we may never close a session
* while a Key created it in is still in use. We would like to keep the
* number of such sessions low. Note that we occasionally want to explicitly
* close a session, see P11Signature.
*
* NOTE that sessions obtained from this class SHOULD be returned using
* either releaseSession() or closeSession() using a finally block when
* not needed anymore. Otherwise, they will be left for cleanup via the
* PhantomReference mechanism when GC kicks in, but it's best not to rely
* on that since GC may not run timely enough since the native PKCS11 library
* is also consuming memory.
*
* Note that sessions are automatically closed when they are not used for a
* period of time, see Session.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class SessionManager {
private final static int DEFAULT_MAX_SESSIONS = 32;
private final static Debug debug = Debug.getInstance("pkcs11");
// token instance
private final Token token;
// maximum number of sessions to open with this token
private final int maxSessions;
// total number of active sessions
private AtomicInteger activeSessions = new AtomicInteger();
// pool of available object sessions
private final Pool objSessions;
// pool of available operation sessions
private final Pool opSessions;
// maximum number of active sessions during this invocation, for debugging
private int maxActiveSessions;
private Object maxActiveSessionsLock;
// flags to use in the C_OpenSession() call
private final long openSessionFlags;
SessionManager(Token token) {
long n;
if (token.isWriteProtected()) {
openSessionFlags = CKF_SERIAL_SESSION;
n = token.tokenInfo.ulMaxSessionCount;
} else {
openSessionFlags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
n = token.tokenInfo.ulMaxRwSessionCount;
}
if (n == CK_EFFECTIVELY_INFINITE) {
n = Integer.MAX_VALUE;
} else if ((n == CK_UNAVAILABLE_INFORMATION) || (n < 0)) {
// choose an arbitrary concrete value
n = DEFAULT_MAX_SESSIONS;
}
maxSessions = (int)Math.min(n, Integer.MAX_VALUE);
this.token = token;
this.objSessions = new Pool(this, true);
this.opSessions = new Pool(this, false);
if (debug != null) {
maxActiveSessionsLock = new Object();
}
}
// returns whether only a fairly low number of sessions are
// supported by this token.
boolean lowMaxSessions() {
return (maxSessions <= DEFAULT_MAX_SESSIONS);
}
Session getObjSession() throws PKCS11Exception {
Session session = objSessions.poll();
if (session != null) {
return ensureValid(session);
}
session = opSessions.poll();
if (session != null) {
return ensureValid(session);
}
session = openSession();
return ensureValid(session);
}
Session getOpSession() throws PKCS11Exception {
Session session = opSessions.poll();
if (session != null) {
return ensureValid(session);
}
// create a new session rather than re-using an obj session
// that avoids potential expensive cancels() for Signatures & RSACipher
if (maxSessions == Integer.MAX_VALUE ||
activeSessions.get() < maxSessions) {
session = openSession();
return ensureValid(session);
}
session = objSessions.poll();
if (session != null) {
return ensureValid(session);
}
throw new ProviderException("Could not obtain session");
}
private Session ensureValid(Session session) {
session.id();
return session;
}
Session killSession(Session session) {
if ((session == null) || (token.isValid() == false)) {
return null;
}
if (debug != null) {
String location = new Exception().getStackTrace()[2].toString();
System.out.println("Killing session (" + location + ") active: "
+ activeSessions.get());
}
closeSession(session);
return null;
}
Session releaseSession(Session session) {
if ((session == null) || (token.isValid() == false)) {
return null;
}
if (session.hasObjects()) {
objSessions.release(session);
} else {
opSessions.release(session);
}
return null;
}
void demoteObjSession(Session session) {
if (token.isValid() == false) {
return;
}
if (debug != null) {
System.out.println("Demoting session, active: " +
activeSessions.get());
}
boolean present = objSessions.remove(session);
if (present == false) {
// session is currently in use
// will be added to correct pool on release, nothing to do now
return;
}
opSessions.release(session);
}
private Session openSession() throws PKCS11Exception {
if ((maxSessions != Integer.MAX_VALUE) &&
(activeSessions.get() >= maxSessions)) {
throw new ProviderException("No more sessions available");
}
long id = token.p11.C_OpenSession
(token.provider.slotID, openSessionFlags, null, null);
Session session = new Session(token, id);
activeSessions.incrementAndGet();
if (debug != null) {
synchronized(maxActiveSessionsLock) {
if (activeSessions.get() > maxActiveSessions) {
maxActiveSessions = activeSessions.get();
if (maxActiveSessions % 10 == 0) {
System.out.println("Open sessions: " + maxActiveSessions);
}
}
}
}
return session;
}
private void closeSession(Session session) {
session.close();
activeSessions.decrementAndGet();
}
public static final class Pool {
private final SessionManager mgr;
private final AbstractQueue<Session> pool;
private final int SESSION_MAX = 5;
// Object session pools can contain unlimited sessions.
// Operation session pools are limited and enforced by the queue.
Pool(SessionManager mgr, boolean obj) {
this.mgr = mgr;
if (obj) {
pool = new LinkedBlockingQueue<Session>();
} else {
pool = new LinkedBlockingQueue<Session>(SESSION_MAX);
}
}
boolean remove(Session session) {
return pool.remove(session);
}
Session poll() {
return pool.poll();
}
void release(Session session) {
// Object session pools never return false, only Operation ones
if (!pool.offer(session)) {
mgr.closeSession(session);
free();
}
}
// Free any old operation session if this queue is full
void free() {
int n = SESSION_MAX;
int i = 0;
Session oldestSession;
long time = System.currentTimeMillis();
// Check if the session head is too old and continue through pool
// until only one is left.
do {
oldestSession = pool.peek();
if (oldestSession == null || oldestSession.isLive(time) ||
!pool.remove(oldestSession)) {
break;
}
i++;
mgr.closeSession(oldestSession);
} while ((n - i) > 1);
if (debug != null) {
System.out.println("Closing " + i + " idle sessions, active: "
+ mgr.activeSessions);
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,241 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11;
import java.util.*;
import java.util.concurrent.*;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* TemplateManager class.
*
* Not all PKCS#11 tokens are created equal. One token may require that one
* value is specified when creating a certain type of object. Another token
* may require a different value. Yet another token may only work if the
* attribute is not specified at all.
*
* In order to allow an application to work unmodified with all those
* different tokens, the SunPKCS11 provider makes the attributes that are
* specified and their value configurable. Hence, only the SunPKCS11
* configuration file has to be tweaked at deployment time to allow all
* existing applications to be used.
*
* The template manager is responsible for reading the attribute configuration
* information and to make it available to the various internal components
* of the SunPKCS11 provider.
*
* @author Andreas Sterbenz
* @since 1.5
*/
final class TemplateManager {
private final static boolean DEBUG = false;
// constant for any operation (either O_IMPORT or O_GENERATE)
final static String O_ANY = "*";
// constant for operation create ("importing" existing key material)
final static String O_IMPORT = "import";
// constant for operation generate (generating new key material)
final static String O_GENERATE = "generate";
private static class KeyAndTemplate {
final TemplateKey key;
final Template template;
KeyAndTemplate(TemplateKey key, Template template) {
this.key = key;
this.template = template;
}
}
// primitive templates contains the individual template configuration
// entries from the configuration file
private final List<KeyAndTemplate> primitiveTemplates;
// composite templates is a cache of the exact configuration template for
// each specific TemplateKey (no wildcards). the entries are created
// on demand during first use by compositing all applicable
// primitive template entries. the result is then stored in this map
// for performance
private final Map<TemplateKey,Template> compositeTemplates;
TemplateManager() {
primitiveTemplates = new ArrayList<KeyAndTemplate>();
compositeTemplates = new ConcurrentHashMap<TemplateKey,Template>();
}
// add a template. Called by Config.
void addTemplate(String op, long objectClass, long keyAlgorithm,
CK_ATTRIBUTE[] attrs) {
TemplateKey key = new TemplateKey(op, objectClass, keyAlgorithm);
Template template = new Template(attrs);
if (DEBUG) {
System.out.println("Adding " + key + " -> " + template);
}
primitiveTemplates.add(new KeyAndTemplate(key, template));
}
private Template getTemplate(TemplateKey key) {
Template template = compositeTemplates.get(key);
if (template == null) {
template = buildCompositeTemplate(key);
compositeTemplates.put(key, template);
}
return template;
}
// Get the attributes for the requested op and combine them with attrs.
// This is the method called by the implementation to obtain the
// attributes.
CK_ATTRIBUTE[] getAttributes(String op, long type, long alg,
CK_ATTRIBUTE[] attrs) {
TemplateKey key = new TemplateKey(op, type, alg);
Template template = getTemplate(key);
CK_ATTRIBUTE[] newAttrs = template.getAttributes(attrs);
if (DEBUG) {
System.out.println(key + " -> " + Arrays.asList(newAttrs));
}
return newAttrs;
}
// build a composite template for the given key
private Template buildCompositeTemplate(TemplateKey key) {
Template comp = new Template();
// iterate through primitive templates and add all that apply
for (KeyAndTemplate entry : primitiveTemplates) {
if (entry.key.appliesTo(key)) {
comp.add(entry.template);
}
}
return comp;
}
/**
* Nested class representing a template identifier.
*/
private static final class TemplateKey {
final String operation;
final long keyType;
final long keyAlgorithm;
TemplateKey(String operation, long keyType, long keyAlgorithm) {
this.operation = operation;
this.keyType = keyType;
this.keyAlgorithm = keyAlgorithm;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof TemplateKey == false) {
return false;
}
TemplateKey other = (TemplateKey)obj;
boolean match = this.operation.equals(other.operation)
&& (this.keyType == other.keyType)
&& (this.keyAlgorithm == other.keyAlgorithm);
return match;
}
public int hashCode() {
return operation.hashCode() + (int)keyType + (int)keyAlgorithm;
}
boolean appliesTo(TemplateKey key) {
if (operation.equals(O_ANY) || operation.equals(key.operation)) {
if ((keyType == PCKO_ANY) || (keyType == key.keyType)) {
if ((keyAlgorithm == PCKK_ANY)
|| (keyAlgorithm == key.keyAlgorithm)) {
return true;
}
}
}
return false;
}
public String toString() {
return "(" + operation + ","
+ Functions.getObjectClassName(keyType)
+ "," + Functions.getKeyName(keyAlgorithm) + ")";
}
}
/**
* Nested class representing template attributes.
*/
private static final class Template {
private final static CK_ATTRIBUTE[] A0 = new CK_ATTRIBUTE[0];
private CK_ATTRIBUTE[] attributes;
Template() {
attributes = A0;
}
Template(CK_ATTRIBUTE[] attributes) {
this.attributes = attributes;
}
void add(Template template) {
attributes = getAttributes(template.attributes);
}
CK_ATTRIBUTE[] getAttributes(CK_ATTRIBUTE[] attrs) {
return combine(attributes, attrs);
}
/**
* Combine two sets of attributes. The second set has precedence
* over the first and overrides its settings.
*/
private static CK_ATTRIBUTE[] combine(CK_ATTRIBUTE[] attrs1,
CK_ATTRIBUTE[] attrs2) {
List<CK_ATTRIBUTE> attrs = new ArrayList<CK_ATTRIBUTE>();
for (CK_ATTRIBUTE attr : attrs1) {
if (attr.pValue != null) {
attrs.add(attr);
}
}
for (CK_ATTRIBUTE attr2 : attrs2) {
long type = attr2.type;
for (CK_ATTRIBUTE attr1 : attrs1) {
if (attr1.type == type) {
attrs.remove(attr1);
}
}
if (attr2.pValue != null) {
attrs.add(attr2);
}
}
return attrs.toArray(A0);
}
public String toString() {
return Arrays.asList(attributes).toString();
}
}
}

View file

@ -0,0 +1,450 @@
/*
* Copyright (c) 2003, 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 sun.security.pkcs11;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.io.*;
import java.lang.ref.*;
import java.security.*;
import javax.security.auth.login.LoginException;
import sun.security.jca.JCAUtil;
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.TemplateManager.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* PKCS#11 token.
*
* @author Andreas Sterbenz
* @since 1.5
*/
class Token implements Serializable {
// need to be serializable to allow SecureRandom to be serialized
private static final long serialVersionUID = 2541527649100571747L;
// how often to check if the token is still present (in ms)
// this is different from checking if a token has been inserted,
// that is done in SunPKCS11. Currently 50 ms.
private final static long CHECK_INTERVAL = 50;
final SunPKCS11 provider;
final PKCS11 p11;
final Config config;
final CK_TOKEN_INFO tokenInfo;
// session manager to pool sessions
final SessionManager sessionManager;
// template manager to customize the attributes used when creating objects
private final TemplateManager templateManager;
// flag indicating whether we need to explicitly cancel operations
// we started on the token. If false, we assume operations are
// automatically cancelled once we start another one
final boolean explicitCancel;
// translation cache for secret keys
final KeyCache secretCache;
// translation cache for asymmetric keys (public and private)
final KeyCache privateCache;
// cached instances of the various key factories, initialized on demand
private volatile P11KeyFactory rsaFactory, dsaFactory, dhFactory, ecFactory;
// table which maps mechanisms to the corresponding cached
// MechanismInfo objects
private final Map<Long, CK_MECHANISM_INFO> mechInfoMap;
// single SecureRandomSpi instance we use per token
// initialized on demand (if supported)
private volatile P11SecureRandom secureRandom;
// single KeyStoreSpi instance we use per provider
// initialized on demand
private volatile P11KeyStore keyStore;
// whether this token is a removable token
private final boolean removable;
// for removable tokens: whether this token is valid or has been removed
private volatile boolean valid;
// for removable tokens: time last checked for token presence
private long lastPresentCheck;
// unique token id, used for serialization only
private byte[] tokenId;
// flag indicating whether the token is write protected
private boolean writeProtected;
// flag indicating whether we are logged in
private volatile boolean loggedIn;
// time we last checked login status
private long lastLoginCheck;
// mutex for token-present-check
private final static Object CHECK_LOCK = new Object();
// object for indicating unsupported mechanism in 'mechInfoMap'
private final static CK_MECHANISM_INFO INVALID_MECH =
new CK_MECHANISM_INFO(0, 0, 0);
// flag indicating whether the token supports raw secret key material import
private Boolean supportsRawSecretKeyImport;
Token(SunPKCS11 provider) throws PKCS11Exception {
this.provider = provider;
this.removable = provider.removable;
this.valid = true;
p11 = provider.p11;
config = provider.config;
tokenInfo = p11.C_GetTokenInfo(provider.slotID);
writeProtected = (tokenInfo.flags & CKF_WRITE_PROTECTED) != 0;
// create session manager and open a test session
SessionManager sessionManager;
try {
sessionManager = new SessionManager(this);
Session s = sessionManager.getOpSession();
sessionManager.releaseSession(s);
} catch (PKCS11Exception e) {
if (writeProtected) {
throw e;
}
// token might not permit RW sessions even though
// CKF_WRITE_PROTECTED is not set
writeProtected = true;
sessionManager = new SessionManager(this);
Session s = sessionManager.getOpSession();
sessionManager.releaseSession(s);
}
this.sessionManager = sessionManager;
secretCache = new KeyCache();
privateCache = new KeyCache();
templateManager = config.getTemplateManager();
explicitCancel = config.getExplicitCancel();
mechInfoMap =
new ConcurrentHashMap<Long, CK_MECHANISM_INFO>(10);
}
boolean isWriteProtected() {
return writeProtected;
}
// return whether the token supports raw secret key material import
boolean supportsRawSecretKeyImport() {
if (supportsRawSecretKeyImport == null) {
SecureRandom random = JCAUtil.getSecureRandom();
byte[] encoded = new byte[48];
random.nextBytes(encoded);
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[3];
attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET);
attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
Session session = null;
try {
attributes = getAttributes(O_IMPORT,
CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
session = getObjSession();
long keyID = p11.C_CreateObject(session.id(), attributes);
supportsRawSecretKeyImport = Boolean.TRUE;
} catch (PKCS11Exception e) {
supportsRawSecretKeyImport = Boolean.FALSE;
} finally {
releaseSession(session);
}
}
return supportsRawSecretKeyImport;
}
// return whether we are logged in
// uses cached result if current. session is optional and may be null
boolean isLoggedIn(Session session) throws PKCS11Exception {
// volatile load first
boolean loggedIn = this.loggedIn;
long time = System.currentTimeMillis();
if (time - lastLoginCheck > CHECK_INTERVAL) {
loggedIn = isLoggedInNow(session);
lastLoginCheck = time;
}
return loggedIn;
}
// return whether we are logged in now
// does not use cache
boolean isLoggedInNow(Session session) throws PKCS11Exception {
boolean allocSession = (session == null);
try {
if (allocSession) {
session = getOpSession();
}
CK_SESSION_INFO info = p11.C_GetSessionInfo(session.id());
boolean loggedIn = (info.state == CKS_RO_USER_FUNCTIONS) ||
(info.state == CKS_RW_USER_FUNCTIONS);
this.loggedIn = loggedIn;
return loggedIn;
} finally {
if (allocSession) {
releaseSession(session);
}
}
}
// ensure that we are logged in
// call provider.login() if not
void ensureLoggedIn(Session session) throws PKCS11Exception, LoginException {
if (isLoggedIn(session) == false) {
provider.login(null, null);
}
}
// return whether this token object is valid (i.e. token not removed)
// returns value from last check, does not perform new check
boolean isValid() {
if (removable == false) {
return true;
}
return valid;
}
void ensureValid() {
if (isValid() == false) {
throw new ProviderException("Token has been removed");
}
}
// return whether a token is present (i.e. token not removed)
// returns cached value if current, otherwise performs new check
boolean isPresent(long sessionID) {
if (removable == false) {
return true;
}
if (valid == false) {
return false;
}
long time = System.currentTimeMillis();
if ((time - lastPresentCheck) >= CHECK_INTERVAL) {
synchronized (CHECK_LOCK) {
if ((time - lastPresentCheck) >= CHECK_INTERVAL) {
boolean ok = false;
try {
// check if token still present
CK_SLOT_INFO slotInfo =
provider.p11.C_GetSlotInfo(provider.slotID);
if ((slotInfo.flags & CKF_TOKEN_PRESENT) != 0) {
// if the token has been removed and re-inserted,
// the token should return an error
CK_SESSION_INFO sessInfo =
provider.p11.C_GetSessionInfo
(sessionID);
ok = true;
}
} catch (PKCS11Exception e) {
// empty
}
valid = ok;
lastPresentCheck = System.currentTimeMillis();
if (ok == false) {
destroy();
}
}
}
}
return valid;
}
void destroy() {
valid = false;
provider.uninitToken(this);
}
Session getObjSession() throws PKCS11Exception {
return sessionManager.getObjSession();
}
Session getOpSession() throws PKCS11Exception {
return sessionManager.getOpSession();
}
Session releaseSession(Session session) {
return sessionManager.releaseSession(session);
}
Session killSession(Session session) {
return sessionManager.killSession(session);
}
CK_ATTRIBUTE[] getAttributes(String op, long type, long alg,
CK_ATTRIBUTE[] attrs) throws PKCS11Exception {
CK_ATTRIBUTE[] newAttrs =
templateManager.getAttributes(op, type, alg, attrs);
for (CK_ATTRIBUTE attr : newAttrs) {
if (attr.type == CKA_TOKEN) {
if (attr.getBoolean()) {
try {
ensureLoggedIn(null);
} catch (LoginException e) {
throw new ProviderException("Login failed", e);
}
}
// break once we have found a CKA_TOKEN attribute
break;
}
}
return newAttrs;
}
P11KeyFactory getKeyFactory(String algorithm) {
P11KeyFactory f;
if (algorithm.equals("RSA")) {
f = rsaFactory;
if (f == null) {
f = new P11RSAKeyFactory(this, algorithm);
rsaFactory = f;
}
} else if (algorithm.equals("DSA")) {
f = dsaFactory;
if (f == null) {
f = new P11DSAKeyFactory(this, algorithm);
dsaFactory = f;
}
} else if (algorithm.equals("DH")) {
f = dhFactory;
if (f == null) {
f = new P11DHKeyFactory(this, algorithm);
dhFactory = f;
}
} else if (algorithm.equals("EC")) {
f = ecFactory;
if (f == null) {
f = new P11ECKeyFactory(this, algorithm);
ecFactory = f;
}
} else {
throw new ProviderException("Unknown algorithm " + algorithm);
}
return f;
}
P11SecureRandom getRandom() {
if (secureRandom == null) {
secureRandom = new P11SecureRandom(this);
}
return secureRandom;
}
P11KeyStore getKeyStore() {
if (keyStore == null) {
keyStore = new P11KeyStore(this);
}
return keyStore;
}
CK_MECHANISM_INFO getMechanismInfo(long mechanism) throws PKCS11Exception {
CK_MECHANISM_INFO result = mechInfoMap.get(mechanism);
if (result == null) {
try {
result = p11.C_GetMechanismInfo(provider.slotID,
mechanism);
mechInfoMap.put(mechanism, result);
} catch (PKCS11Exception e) {
if (e.getErrorCode() != PKCS11Constants.CKR_MECHANISM_INVALID) {
throw e;
} else {
mechInfoMap.put(mechanism, INVALID_MECH);
}
}
} else if (result == INVALID_MECH) {
result = null;
}
return result;
}
private synchronized byte[] getTokenId() {
if (tokenId == null) {
SecureRandom random = JCAUtil.getSecureRandom();
tokenId = new byte[20];
random.nextBytes(tokenId);
serializedTokens.add(new WeakReference<Token>(this));
}
return tokenId;
}
// list of all tokens that have been serialized within this VM
// NOTE that elements are never removed from this list
// the assumption is that the number of tokens that are serialized
// is relatively small
private static final List<Reference<Token>> serializedTokens =
new ArrayList<Reference<Token>>();
private Object writeReplace() throws ObjectStreamException {
if (isValid() == false) {
throw new NotSerializableException("Token has been removed");
}
return new TokenRep(this);
}
// serialized representation of a token
// tokens can only be de-serialized within the same VM invocation
// and if the token has not been removed in the meantime
private static class TokenRep implements Serializable {
private static final long serialVersionUID = 3503721168218219807L;
private final byte[] tokenId;
TokenRep(Token token) {
tokenId = token.getTokenId();
}
private Object readResolve() throws ObjectStreamException {
for (Reference<Token> tokenRef : serializedTokens) {
Token token = tokenRef.get();
if ((token != null) && token.isValid()) {
if (Arrays.equals(token.getTokenId(), tokenId)) {
return token;
}
}
}
throw new NotSerializableException("Could not find token");
}
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11.wrapper;
/**
* This class represents the necessary parameters required by
* the CKM_AES_CTR mechanism as defined in CK_AES_CTR_PARAMS structure.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_AES_CTR_PARAMS {
* CK_ULONG ulCounterBits;
* CK_BYTE cb[16];
* } CK_AES_CTR_PARAMS;
* </PRE>
*
* @author Yu-Ching Valerie Peng
* @since 1.7
*/
public class CK_AES_CTR_PARAMS {
private final long ulCounterBits;
private final byte[] cb;
public CK_AES_CTR_PARAMS(byte[] cb) {
ulCounterBits = 128;
this.cb = cb.clone();
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("ulCounterBits: ");
sb.append(ulCounterBits);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("cb: ");
sb.append(Functions.toHexString(cb));
return sb.toString();
}
}

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
import java.math.BigInteger;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* class CK_ATTRIBUTE includes the type, value and length of an attribute.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_ATTRIBUTE {&nbsp;&nbsp;
* CK_ATTRIBUTE_TYPE type;&nbsp;&nbsp;
* CK_VOID_PTR pValue;&nbsp;&nbsp;
* CK_ULONG ulValueLen;
* } CK_ATTRIBUTE;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_ATTRIBUTE {
// common attributes
// NOTE that CK_ATTRIBUTE is a mutable classes but these attributes
// *MUST NEVER* be modified, e.g. by using them in a
// C_GetAttributeValue() call!
public final static CK_ATTRIBUTE TOKEN_FALSE =
new CK_ATTRIBUTE(CKA_TOKEN, false);
public final static CK_ATTRIBUTE SENSITIVE_FALSE =
new CK_ATTRIBUTE(CKA_SENSITIVE, false);
public final static CK_ATTRIBUTE EXTRACTABLE_TRUE =
new CK_ATTRIBUTE(CKA_EXTRACTABLE, true);
public final static CK_ATTRIBUTE ENCRYPT_TRUE =
new CK_ATTRIBUTE(CKA_ENCRYPT, true);
public final static CK_ATTRIBUTE DECRYPT_TRUE =
new CK_ATTRIBUTE(CKA_DECRYPT, true);
public final static CK_ATTRIBUTE WRAP_TRUE =
new CK_ATTRIBUTE(CKA_WRAP, true);
public final static CK_ATTRIBUTE UNWRAP_TRUE =
new CK_ATTRIBUTE(CKA_UNWRAP, true);
public final static CK_ATTRIBUTE SIGN_TRUE =
new CK_ATTRIBUTE(CKA_SIGN, true);
public final static CK_ATTRIBUTE VERIFY_TRUE =
new CK_ATTRIBUTE(CKA_VERIFY, true);
public final static CK_ATTRIBUTE SIGN_RECOVER_TRUE =
new CK_ATTRIBUTE(CKA_SIGN_RECOVER, true);
public final static CK_ATTRIBUTE VERIFY_RECOVER_TRUE =
new CK_ATTRIBUTE(CKA_VERIFY_RECOVER, true);
public final static CK_ATTRIBUTE DERIVE_TRUE =
new CK_ATTRIBUTE(CKA_DERIVE, true);
public final static CK_ATTRIBUTE ENCRYPT_NULL =
new CK_ATTRIBUTE(CKA_ENCRYPT);
public final static CK_ATTRIBUTE DECRYPT_NULL =
new CK_ATTRIBUTE(CKA_DECRYPT);
public final static CK_ATTRIBUTE WRAP_NULL =
new CK_ATTRIBUTE(CKA_WRAP);
public final static CK_ATTRIBUTE UNWRAP_NULL =
new CK_ATTRIBUTE(CKA_UNWRAP);
public CK_ATTRIBUTE() {
// empty
}
public CK_ATTRIBUTE(long type) {
this.type = type;
}
public CK_ATTRIBUTE(long type, Object pValue) {
this.type = type;
this.pValue = pValue;
}
public CK_ATTRIBUTE(long type, boolean value) {
this.type = type;
this.pValue = Boolean.valueOf(value);
}
public CK_ATTRIBUTE(long type, long value) {
this.type = type;
this.pValue = Long.valueOf(value);
}
public CK_ATTRIBUTE(long type, BigInteger value) {
this.type = type;
this.pValue = sun.security.pkcs11.P11Util.getMagnitude(value);
}
public BigInteger getBigInteger() {
if (pValue instanceof byte[] == false) {
throw new RuntimeException("Not a byte[]");
}
return new BigInteger(1, (byte[])pValue);
}
public boolean getBoolean() {
if (pValue instanceof Boolean == false) {
throw new RuntimeException
("Not a Boolean: " + pValue.getClass().getName());
}
return ((Boolean)pValue).booleanValue();
}
public char[] getCharArray() {
if (pValue instanceof char[] == false) {
throw new RuntimeException("Not a char[]");
}
return (char[])pValue;
}
public byte[] getByteArray() {
if (pValue instanceof byte[] == false) {
throw new RuntimeException("Not a byte[]");
}
return (byte[])pValue;
}
public long getLong() {
if (pValue instanceof Long == false) {
throw new RuntimeException
("Not a Long: " + pValue.getClass().getName());
}
return ((Long)pValue).longValue();
}
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ATTRIBUTE_TYPE type;
* </PRE>
*/
public long type;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VOID_PTR pValue;
* CK_ULONG ulValueLen;
* </PRE>
*/
public Object pValue;
/**
* Returns the string representation of CK_ATTRIBUTE.
*
* @return the string representation of CK_ATTRIBUTE
*/
public String toString() {
String prefix = Functions.getAttributeName(type) + " = ";
if (type == CKA_CLASS) {
return prefix + Functions.getObjectClassName(getLong());
} else if (type == CKA_KEY_TYPE) {
return prefix + Functions.getKeyName(getLong());
} else {
String s;
if (pValue instanceof char[]) {
s = new String((char[])pValue);
} else if (pValue instanceof byte[]) {
s = Functions.toHexString((byte[])pValue);
} else {
s = String.valueOf(pValue);
}
return prefix + s;
}
}
}

View file

@ -0,0 +1,68 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* interface CK_CREATEMUTEX.
*
* @author Karl Scheibelhofer &lt;Karl.Scheibelhofer@iaik.at&gt;
* @author Martin Schlaeffer &lt;schlaeff@sbox.tugraz.at&gt;
*/
public interface CK_CREATEMUTEX {
/**
* Method CK_CREATEMUTEX
*
* @return The mutex (lock) object.
* @exception PKCS11Exception
*/
public Object CK_CREATEMUTEX() throws PKCS11Exception;
}

View file

@ -0,0 +1,120 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_C_INITIALIZE_ARGS contains the optional arguments for the
* C_Initialize function.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_C_INITIALIZE_ARGS {&nbsp;&nbsp;
* CK_CREATEMUTEX CreateMutex;&nbsp;&nbsp;
* CK_DESTROYMUTEX DestroyMutex;&nbsp;&nbsp;
* CK_LOCKMUTEX LockMutex;&nbsp;&nbsp;
* CK_UNLOCKMUTEX UnlockMutex;&nbsp;&nbsp;
* CK_FLAGS flags;&nbsp;&nbsp;
* CK_VOID_PTR pReserved;&nbsp;&nbsp;
* } CK_C_INITIALIZE_ARGS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_C_INITIALIZE_ARGS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_CREATEMUTEX CreateMutex;
* </PRE>
*/
public CK_CREATEMUTEX CreateMutex;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_DESTROYMUTEX DestroyMutex;
* </PRE>
*/
public CK_DESTROYMUTEX DestroyMutex;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_LOCKMUTEX LockMutex;
* </PRE>
*/
public CK_LOCKMUTEX LockMutex;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_UNLOCKMUTEX UnlockMutex;
* </PRE>
*/
public CK_UNLOCKMUTEX UnlockMutex;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_FLAGS flags;
* </PRE>
*/
public long flags;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VOID_PTR pReserved;
* </PRE>
*/
public Object pReserved;
}

View file

@ -0,0 +1,137 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class .<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_DATE {&nbsp;&nbsp;
* CK_CHAR year[4];&nbsp;&nbsp;
* CK_CHAR month[2];&nbsp;&nbsp;
* CK_CHAR day[2];&nbsp;&nbsp;
* } CK_DATE;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_DATE implements Cloneable {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR year[4]; - the year ("1900" - "9999")
* </PRE>
*/
public char[] year; /* the year ("1900" - "9999") */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR month[2]; - the month ("01" - "12")
* </PRE>
*/
public char[] month; /* the month ("01" - "12") */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR day[2]; - the day ("01" - "31")
* </PRE>
*/
public char[] day; /* the day ("01" - "31") */
public CK_DATE(char[] year, char[] month, char[] day) {
this.year = year;
this.month = month;
this.day = day;
}
/**
* Create a (deep) clone of this object.
*
* @return A clone of this object.
*/
public Object clone() {
CK_DATE copy = null;
try {
copy = (CK_DATE) super.clone();
} catch (CloneNotSupportedException cnse) {
// re-throw as RuntimeException
throw (RuntimeException)
(new RuntimeException("Clone error").initCause(cnse));
}
copy.year = this.year.clone();
copy.month = this.month.clone();
copy.day = this.day.clone();
return copy;
}
/**
* Returns the string representation of CK_DATE.
*
* @return the string representation of CK_DATE
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(new String(day));
sb.append('.');
sb.append(new String(month));
sb.append('.');
sb.append(new String(year));
sb.append(" (DD.MM.YYYY)");
return sb.toString();
}
}

View file

@ -0,0 +1,68 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* interface CK_DESTROYMUTEX.<p>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public interface CK_DESTROYMUTEX {
/**
* Method CK_DESTROYMUTEX
*
* @param pMutex The mutex (lock) object.
* @exception PKCS11Exception
*/
public void CK_DESTROYMUTEX(Object pMutex) throws PKCS11Exception;
}

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_ECDH1_DERIVE_PARAMS provides the parameters to the
* CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_ECDH1_DERIVE_PARAMS {
* CK_EC_KDF_TYPE kdf;
* CK_ULONG ulSharedDataLen;
* CK_BYTE_PTR pSharedData;
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* } CK_ECDH1_DERIVE_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
public class CK_ECDH1_DERIVE_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_EC_KDF_TYPE kdf;
* </PRE>
*/
public long kdf;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulSharedDataLen;
* CK_BYTE_PTR pSharedData;
* </PRE>
*/
public byte[] pSharedData;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* </PRE>
*/
public byte[] pPublicData;
public CK_ECDH1_DERIVE_PARAMS(long kdf, byte[] pSharedData, byte[] pPublicData) {
this.kdf = kdf;
this.pSharedData = pSharedData;
this.pPublicData = pPublicData;
}
/**
* Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
*
* @return the string representation of CK_PKCS5_PBKD2_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("kdf: 0x");
sb.append(Functions.toFullHexString(kdf));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSharedDataLen: ");
sb.append(pSharedData.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSharedData: ");
sb.append(Functions.toHexString(pSharedData));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicDataLen: ");
sb.append(pPublicData.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicData: ");
sb.append(Functions.toHexString(pPublicData));
//buffer.append(Constants.NEWLINE);
return sb.toString();
}
}

View file

@ -0,0 +1,181 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_ECDH2_DERIVE_PARAMS provides the parameters to the
* CKM_ECMQV_DERIVE mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_ECDH2_DERIVE_PARAMS {
* CK_EC_KDF_TYPE kdf;
* CK_ULONG ulSharedDataLen;
* CK_BYTE_PTR pSharedData;
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* CK_ULONG ulPrivateDataLen;
* CK_OBJECT_HANDLE hPrivateData;
* CK_ULONG ulPublicDataLen2;
* CK_BYTE_PTR pPublicData2;
* } CK_ECDH2_DERIVE_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
public class CK_ECDH2_DERIVE_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_EC_KDF_TYPE kdf;
* </PRE>
*/
public long kdf;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulSharedDataLen;
* CK_BYTE_PTR pSharedData;
* </PRE>
*/
public byte[] pSharedData;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* </PRE>
*/
public byte[] pPublicData;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPrivateDataLen;
* </PRE>
*/
public long ulPrivateDataLen;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_OBJECT_HANDLE hPrivateData;
* </PRE>
*/
public long hPrivateData;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPublicDataLen2;
* CK_BYTE_PTR pPublicData2;
* </PRE>
*/
public byte[] pPublicData2;
/**
* Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
*
* @return the string representation of CK_PKCS5_PBKD2_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("kdf: 0x");
sb.append(Functions.toFullHexString(kdf));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSharedDataLen: ");
sb.append(pSharedData.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSharedData: ");
sb.append(Functions.toHexString(pSharedData));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicDataLen: ");
sb.append(pPublicData.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicData: ");
sb.append(Functions.toHexString(pPublicData));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulPrivateDataLen: ");
sb.append(ulPrivateDataLen);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("hPrivateData: ");
sb.append(hPrivateData);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicDataLen2: ");
sb.append(pPublicData2.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicData2: ");
sb.append(Functions.toHexString(pPublicData2));
//buffer.append(Constants.NEWLINE);
return sb.toString();
}
}

View file

@ -0,0 +1,164 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_INFO provides general information about Cryptoki.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_INFO {&nbsp;&nbsp;
* CK_VERSION cryptokiVersion;&nbsp;&nbsp;
* CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
* CK_FLAGS flags;&nbsp;&nbsp;
* CK_UTF8CHAR libraryDescription[32];&nbsp;&nbsp;
* CK_VERSION libraryVersion;&nbsp;&nbsp;
* } CK_INFO;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_INFO {
/**
* Cryptoki interface version number<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_VERSION cryptokiVersion;
* </PRE>
*/
public CK_VERSION cryptokiVersion;
/**
* ID of the Cryptoki library manufacturer. must be blank
* padded - only the first 32 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_UTF8CHAR manufacturerID[32];
* </PRE>
*/
public char[] manufacturerID;
/**
* bit flags reserved for future versions. must be zero<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_FLAGS flags;
* </PRE>
*/
public long flags;
/* libraryDescription and libraryVersion are new for v2.0 */
/**
* must be blank padded - only the first 32 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_UTF8CHAR libraryDescription[32];
* </PRE>
*/
public char[] libraryDescription;
/**
* Cryptoki library version number<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_VERSION libraryVersion;
* </PRE>
*/
public CK_VERSION libraryVersion;
public CK_INFO(CK_VERSION cryptoVer, char[] vendor, long flags,
char[] libDesc, CK_VERSION libVer) {
this.cryptokiVersion = cryptoVer;
this.manufacturerID = vendor;
this.flags = flags;
this.libraryDescription = libDesc;
this.libraryVersion = libVer;
}
/**
* Returns the string representation of CK_INFO.
*
* @return the string representation of CK_INFO
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("cryptokiVersion: ");
sb.append(cryptokiVersion.toString());
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("manufacturerID: ");
sb.append(new String(manufacturerID));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("flags: ");
sb.append(Functions.toBinaryString(flags));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("libraryDescription: ");
sb.append(new String(libraryDescription));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("libraryVersion: ");
sb.append(libraryVersion.toString());
//buffer.append(Constants.NEWLINE);
return sb.toString() ;
}
}

View file

@ -0,0 +1,68 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* interface CK_LOCKMUTEX<p>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public interface CK_LOCKMUTEX {
/**
* Method CK_LOCKMUTEX
*
* @param pMutex The mutex (lock) object to lock.
* @exception PKCS11Exception
*/
public void CK_LOCKMUTEX(Object pMutex) throws PKCS11Exception;
}

View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
import java.math.BigInteger;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* class CK_MECHANISM specifies a particular mechanism and any parameters it
* requires.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_MECHANISM {&nbsp;&nbsp;
* CK_MECHANISM_TYPE mechanism;&nbsp;&nbsp;
* CK_VOID_PTR pParameter;&nbsp;&nbsp;
* CK_ULONG ulParameterLen;&nbsp;&nbsp;
* } CK_MECHANISM;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_MECHANISM {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_MECHANISM_TYPE mechanism;
* </PRE>
*/
public long mechanism;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VOID_PTR pParameter;
* CK_ULONG ulParameterLen;
* </PRE>
*/
public Object pParameter;
public CK_MECHANISM() {
// empty
}
public CK_MECHANISM(long mechanism) {
this.mechanism = mechanism;
}
// We don't have a (long,Object) constructor to force type checking.
// This makes sure we don't accidentally pass a class that the native
// code cannot handle.
public CK_MECHANISM(long mechanism, byte[] pParameter) {
init(mechanism, pParameter);
}
public CK_MECHANISM(long mechanism, BigInteger b) {
init(mechanism, sun.security.pkcs11.P11Util.getMagnitude(b));
}
public CK_MECHANISM(long mechanism, CK_VERSION version) {
init(mechanism, version);
}
public CK_MECHANISM(long mechanism, CK_SSL3_MASTER_KEY_DERIVE_PARAMS params) {
init(mechanism, params);
}
public CK_MECHANISM(long mechanism, CK_SSL3_KEY_MAT_PARAMS params) {
init(mechanism, params);
}
public CK_MECHANISM(long mechanism, CK_TLS_PRF_PARAMS params) {
init(mechanism, params);
}
public CK_MECHANISM(long mechanism, CK_ECDH1_DERIVE_PARAMS params) {
init(mechanism, params);
}
public CK_MECHANISM(long mechanism, Long params) {
init(mechanism, params);
}
public CK_MECHANISM(long mechanism, CK_AES_CTR_PARAMS params) {
init(mechanism, params);
}
private void init(long mechanism, Object pParameter) {
this.mechanism = mechanism;
this.pParameter = pParameter;
}
/**
* Returns the string representation of CK_MECHANISM.
*
* @return the string representation of CK_MECHANISM
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("mechanism: ");
sb.append(mechanism);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pParameter: ");
sb.append(pParameter.toString());
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulParameterLen: ??");
//buffer.append(pParameter.length);
//buffer.append(Constants.NEWLINE);
return sb.toString() ;
}
}

View file

@ -0,0 +1,127 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_MECHANISM_INFO provides information about a particular mechanism.
* <p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_MECHANISM_INFO {&nbsp;&nbsp;
* CK_ULONG ulMinKeySize;&nbsp;&nbsp;
* CK_ULONG ulMaxKeySize;&nbsp;&nbsp;
* CK_FLAGS flags;&nbsp;&nbsp;
* } CK_MECHANISM_INFO;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_MECHANISM_INFO {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulMinKeySize;
* </PRE>
*/
public long ulMinKeySize;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulMaxKeySize;
* </PRE>
*/
public long ulMaxKeySize;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_FLAGS flags;
* </PRE>
*/
public long flags;
public CK_MECHANISM_INFO(long minKeySize, long maxKeySize,
long flags) {
this.ulMinKeySize = minKeySize;
this.ulMaxKeySize = maxKeySize;
this.flags = flags;
}
/**
* Returns the string representation of CK_MECHANISM_INFO.
*
* @return the string representation of CK_MECHANISM_INFO
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("ulMinKeySize: ");
sb.append(String.valueOf(ulMinKeySize));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulMaxKeySize: ");
sb.append(String.valueOf(ulMaxKeySize));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("flags: ");
sb.append(String.valueOf(flags));
sb.append(" = ");
sb.append(Functions.mechanismInfoFlagsToString(flags));
//buffer.append(Constants.NEWLINE);
return sb.toString() ;
}
}

View file

@ -0,0 +1,70 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* interface CK_NOTIFY.<p>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public interface CK_NOTIFY {
/**
* Method CK_NOTIFY
*
* @param hSession
* @param event
* @param pApplication
* @exception PKCS11Exception
*/
public void CK_NOTIFY(long hSession, long event, Object pApplication) throws PKCS11Exception;
}

View file

@ -0,0 +1,147 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_PBE_PARAMS provides all of the necessary information required byte
* the CKM_PBE mechanisms and the CKM_PBA_SHA1_WITH_SHA1_HMAC mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_PBE_PARAMS {
* CK_CHAR_PTR pInitVector;
* CK_CHAR_PTR pPassword;
* CK_ULONG ulPasswordLen;
* CK_CHAR_PTR pSalt;
* CK_ULONG ulSaltLen;
* CK_ULONG ulIteration;
* } CK_PBE_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_PBE_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR_PTR pInitVector;
* </PRE>
*/
public char[] pInitVector;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR_PTR pPassword;
* CK_ULONG ulPasswordLen;
* </PRE>
*/
public char[] pPassword;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR_PTR pSalt
* CK_ULONG ulSaltLen;
* </PRE>
*/
public char[] pSalt;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulIteration;
* </PRE>
*/
public long ulIteration;
/**
* Returns the string representation of CK_PBE_PARAMS.
*
* @return the string representation of CK_PBE_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("pInitVector: ");
sb.append(pInitVector);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulPasswordLen: ");
sb.append(pPassword.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPassword: ");
sb.append(pPassword);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulSaltLen: ");
sb.append(pSalt.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSalt: ");
sb.append(pSalt);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulIteration: ");
sb.append(ulIteration);
//buffer.append(Constants.NEWLINE);
return sb.toString();
}
}

View file

@ -0,0 +1,161 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_PKCS5_PBKD2_PARAMS provides the parameters to the CKM_PKCS5_PBKD2
* mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_PKCS5_PBKD2_PARAMS {
* CK_PKCS5_PBKD2_SALT_SOURCE_TYPE saltSource;
* CK_VOID_PTR pSaltSourceData;
* CK_ULONG ulSaltSourceDataLen;
* CK_ULONG iterations;
* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
* CK_VOID_PTR pPrfData;
* CK_ULONG ulPrfDataLen;
* } CK_PKCS5_PBKD2_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_PKCS5_PBKD2_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
* </PRE>
*/
public long saltSource;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VOID_PTR pSaltSourceData;
* CK_ULONG ulSaltSourceDataLen;
* </PRE>
*/
public byte[] pSaltSourceData;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG iterations;
* </PRE>
*/
public long iterations;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
* </PRE>
*/
public long prf;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VOID_PTR pPrfData;
* CK_ULONG ulPrfDataLen;
* </PRE>
*/
public byte[] pPrfData;
/**
* Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
*
* @return the string representation of CK_PKCS5_PBKD2_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("saltSource: ");
sb.append(saltSource);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSaltSourceData: ");
sb.append(Functions.toHexString(pSaltSourceData));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulSaltSourceDataLen: ");
sb.append(pSaltSourceData.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("iterations: ");
sb.append(iterations);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("prf: ");
sb.append(prf);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPrfData: ");
sb.append(Functions.toHexString(pPrfData));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulPrfDataLen: ");
sb.append(pPrfData.length);
//buffer.append(Constants.NEWLINE);
return sb.toString();
}
}

View file

@ -0,0 +1,143 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
* CKM_RSA_PKCS_OAEP mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_RSA_PKCS_OAEP_PARAMS {
* CK_MECHANISM_TYPE hashAlg;
* CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
* CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
* CK_VOID_PTR pSourceData;
* CK_ULONG ulSourceDataLen;
* } CK_RSA_PKCS_OAEP_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_RSA_PKCS_OAEP_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_MECHANISM_TYPE hashAlg;
* </PRE>
*/
public long hashAlg;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
* </PRE>
*/
public long mgf;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
* </PRE>
*/
public long source;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VOID_PTR pSourceData;
* CK_ULONG ulSourceDataLen;
* </PRE>
*/
public byte[] pSourceData;
//CK_ULONG ulSourceDataLen;
// ulSourceDataLen == pSourceData.length
/**
* Returns the string representation of CK_RSA_PKCS_OAEP_PARAMS.
*
* @return the string representation of CK_RSA_PKCS_OAEP_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("hashAlg: ");
sb.append(hashAlg);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("mgf: ");
sb.append(mgf);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("source: ");
sb.append(source);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSourceData: ");
sb.append(pSourceData.toString());
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pSourceDataLen: ");
sb.append(Functions.toHexString(pSourceData));
//buffer.append(Constants.NEWLINE);
return sb.toString() ;
}
}

View file

@ -0,0 +1,118 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_RSA_PKCS_PSS_PARAMS provides the parameters to the CKM_RSA_PKCS_OAEP
* mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_RSA_PKCS_PSS_PARAMS {
* CK_MECHANISM_TYPE hashAlg;
* CK_RSA_PKCS_MGF_TYPE mgf;
* CK_ULONG sLen;
* } CK_RSA_PKCS_PSS_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
public class CK_RSA_PKCS_PSS_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_MECHANISM_TYPE hashAlg;
* </PRE>
*/
public long hashAlg;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_RSA_PKCS_MGF_TYPE mgf;
* </PRE>
*/
public long mgf;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG sLen;
* </PRE>
*/
public long sLen;
/**
* Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
*
* @return the string representation of CK_PKCS5_PBKD2_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("hashAlg: 0x");
sb.append(Functions.toFullHexString(hashAlg));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("mgf: 0x");
sb.append(Functions.toFullHexString(mgf));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("sLen: ");
sb.append(sLen);
//buffer.append(Constants.NEWLINE);
return sb.toString();
}
}

View file

@ -0,0 +1,142 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_SESSION_INFO provides information about a session.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_SESSION_INFO {&nbsp;&nbsp;
* CK_SLOT_ID slotID;&nbsp;&nbsp;
* CK_STATE state;&nbsp;&nbsp;
* CK_FLAGS flags;&nbsp;&nbsp;
* CK_ULONG ulDeviceError;&nbsp;&nbsp;
* } CK_SESSION_INFO;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_SESSION_INFO {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_SLOT_ID slotID;
* </PRE>
*/
public long slotID;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_STATE state;
* </PRE>
*/
public long state;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_FLAGS flags;
* </PRE>
*/
public long flags; /* see below */
/* ulDeviceError was changed from CK_USHORT to CK_ULONG for
* v2.0 */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulDeviceError;
* </PRE>
*/
public long ulDeviceError; /* device-dependent error code */
public CK_SESSION_INFO(long slotID, long state,
long flags, long ulDeviceError) {
this.slotID = slotID;
this.state = state;
this.flags = flags;
this.ulDeviceError = ulDeviceError;
}
/**
* Returns the string representation of CK_SESSION_INFO.
*
* @return the string representation of CK_SESSION_INFO
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("slotID: ");
sb.append(String.valueOf(slotID));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("state: ");
sb.append(Functions.sessionStateToString(state));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("flags: ");
sb.append(Functions.sessionInfoFlagsToString(flags));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulDeviceError: ");
sb.append(Functions.toHexString(ulDeviceError));
//buffer.append(Constants.NEWLINE);
return sb.toString() ;
}
}

View file

@ -0,0 +1,163 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_SLOT_INFO provides information about a slot.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_SLOT_INFO {&nbsp;&nbsp;
* CK_UTF8CHAR slotDescription[64];&nbsp;&nbsp;
* CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
* CK_FLAGS flags;&nbsp;&nbsp;
* CK_VERSION hardwareVersion;&nbsp;&nbsp;
* CK_VERSION firmwareVersion;&nbsp;&nbsp;
* } CK_SLOT_INFO;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_SLOT_INFO {
/* slotDescription and manufacturerID have been changed from
* CK_CHAR to CK_UTF8CHAR for v2.11. */
/**
* must be blank padded and only the first 64 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_UTF8CHAR slotDescription[64];
* </PRE>
*/
public char[] slotDescription;
/**
* must be blank padded and only the first 32 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_UTF8CHAR manufacturerID[32];
* </PRE>
*/
public char[] manufacturerID;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_FLAGS flags;
* </PRE>
*/
public long flags;
/* hardwareVersion and firmwareVersion are new for v2.0 */
/**
* version of hardware<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_VERSION hardwareVersion;
* </PRE>
*/
public CK_VERSION hardwareVersion;
/**
* version of firmware<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_VERSION firmwareVersion;
* </PRE>
*/
public CK_VERSION firmwareVersion;
public CK_SLOT_INFO(char[] slotDesc, char[] vendor,
long flags, CK_VERSION hwVer, CK_VERSION fwVer) {
this.slotDescription = slotDesc;
this.manufacturerID = vendor;
this.flags = flags;
this.hardwareVersion = hwVer;
this.firmwareVersion = fwVer;
}
/**
* Returns the string representation of CK_SLOT_INFO.
*
* @return the string representation of CK_SLOT_INFO
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("slotDescription: ");
sb.append(new String(slotDescription));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("manufacturerID: ");
sb.append(new String(manufacturerID));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("flags: ");
sb.append(Functions.slotInfoFlagsToString(flags));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("hardwareVersion: ");
sb.append(hardwareVersion.toString());
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("firmwareVersion: ");
sb.append(firmwareVersion.toString());
//buffer.append(Constants.NEWLINE);
return sb.toString() ;
}
}

View file

@ -0,0 +1,162 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_SSL3_KEY_MAT_OUT contains the resulting key handles and
* initialization vectors after performing a C_DeriveKey function with the
* CKM_SSL3_KEY_AND_MAC_DERIVE mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_SSL3_KEY_MAT_OUT {
* CK_OBJECT_HANDLE hClientMacSecret;
* CK_OBJECT_HANDLE hServerMacSecret;
* CK_OBJECT_HANDLE hClientKey;
* CK_OBJECT_HANDLE hServerKey;
* CK_BYTE_PTR pIVClient;
* CK_BYTE_PTR pIVServer;
* } CK_SSL3_KEY_MAT_OUT;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_SSL3_KEY_MAT_OUT{
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_OBJECT_HANDLE hClientMacSecret;
* </PRE>
*/
public long hClientMacSecret;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_OBJECT_HANDLE hServerMacSecret;
* </PRE>
*/
public long hServerMacSecret;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_OBJECT_HANDLE hClientKey;
* </PRE>
*/
public long hClientKey;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_OBJECT_HANDLE hServerKey;
* </PRE>
*/
public long hServerKey;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_BYTE_PTR pIVClient;
* </PRE>
*/
public byte[] pIVClient;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_BYTE_PTR pIVServer;
* </PRE>
*/
public byte[] pIVServer;
/**
* Returns the string representation of CK_SSL3_KEY_MAT_OUT.
*
* @return the string representation of CK_SSL3_KEY_MAT_OUT
*/
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(Constants.INDENT);
buffer.append("hClientMacSecret: ");
buffer.append(hClientMacSecret);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("hServerMacSecret: ");
buffer.append(hServerMacSecret);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("hClientKey: ");
buffer.append(hClientKey);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("hServerKey: ");
buffer.append(hServerKey);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("pIVClient: ");
buffer.append(Functions.toHexString(pIVClient));
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("pIVServer: ");
buffer.append(Functions.toHexString(pIVServer));
//buffer.append(Constants.NEWLINE);
return buffer.toString();
}
}

View file

@ -0,0 +1,175 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_SSL3_KEY_MAT_PARAMS provides the parameters to the
* CKM_SSL3_KEY_AND_MAC_DERIVE mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_SSL3_KEY_MAT_PARAMS {
* CK_ULONG ulMacSizeInBits;
* CK_ULONG ulKeySizeInBits;
* CK_ULONG ulIVSizeInBits;
* CK_BBOOL bIsExport;
* CK_SSL3_RANDOM_DATA RandomInfo;
* CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
* } CK_SSL3_KEY_MAT_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_SSL3_KEY_MAT_PARAMS{
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulMacSizeInBits;
* </PRE>
*/
public long ulMacSizeInBits;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulKeySizeInBits;
* </PRE>
*/
public long ulKeySizeInBits;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulIVSizeInBits;
* </PRE>
*/
public long ulIVSizeInBits;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_BBOOL bIsExport;
* </PRE>
*/
public boolean bIsExport;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_SSL3_RANDOM_DATA RandomInfo;
* </PRE>
*/
public CK_SSL3_RANDOM_DATA RandomInfo;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
* </PRE>
*/
public CK_SSL3_KEY_MAT_OUT pReturnedKeyMaterial;
public CK_SSL3_KEY_MAT_PARAMS(int macSize, int keySize, int ivSize, boolean export, CK_SSL3_RANDOM_DATA random) {
ulMacSizeInBits = macSize;
ulKeySizeInBits = keySize;
ulIVSizeInBits = ivSize;
bIsExport = export;
RandomInfo = random;
pReturnedKeyMaterial = new CK_SSL3_KEY_MAT_OUT();
if (ivSize != 0) {
int n = ivSize >> 3;
pReturnedKeyMaterial.pIVClient = new byte[n];
pReturnedKeyMaterial.pIVServer = new byte[n];
}
}
/**
* Returns the string representation of CK_SSL3_KEY_MAT_PARAMS.
*
* @return the string representation of CK_SSL3_KEY_MAT_PARAMS
*/
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(Constants.INDENT);
buffer.append("ulMacSizeInBits: ");
buffer.append(ulMacSizeInBits);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("ulKeySizeInBits: ");
buffer.append(ulKeySizeInBits);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("ulIVSizeInBits: ");
buffer.append(ulIVSizeInBits);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("bIsExport: ");
buffer.append(bIsExport);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("RandomInfo: ");
buffer.append(RandomInfo);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("pReturnedKeyMaterial: ");
buffer.append(pReturnedKeyMaterial);
//buffer.append(Constants.NEWLINE);
return buffer.toString();
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_SSL3_MASTER_KEY_DERIVE_PARAMS provides the parameters to the
* CKM_SSL3_MASTER_KEY_DERIVE mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
* CK_SSL3_RANDOM_DATA RandomInfo;
* CK_VERSION_PTR pVersion;
* } CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_SSL3_RANDOM_DATA RandomInfo;
* </PRE>
*/
public CK_SSL3_RANDOM_DATA RandomInfo;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VERSION_PTR pVersion;
* </PRE>
*/
public CK_VERSION pVersion;
public CK_SSL3_MASTER_KEY_DERIVE_PARAMS(CK_SSL3_RANDOM_DATA random, CK_VERSION version) {
RandomInfo = random;
pVersion = version;
}
/**
* Returns the string representation of CK_SSL3_MASTER_KEY_DERIVE_PARAMS.
*
* @return the string representation of CK_SSL3_MASTER_KEY_DERIVE_PARAMS
*/
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(Constants.INDENT);
buffer.append("RandomInfo: ");
buffer.append(RandomInfo);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("pVersion: ");
buffer.append(pVersion);
//buffer.append(Constants.NEWLINE);
return buffer.toString();
}
}

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_SSL3_RANDOM_DATA provides information about the random data of a
* client and a server in an SSL context. This class is used by both the
* CKM_SSL3_MASTER_KEY_DERIVE and the CKM_SSL3_KEY_AND_MAC_DERIVE mechanisms.
* <p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_SSL3_RANDOM_DATA {
* CK_BYTE_PTR pClientRandom;
* CK_ULONG ulClientRandomLen;
* CK_BYTE_PTR pServerRandom;
* CK_ULONG ulServerRandomLen;
* } CK_SSL3_RANDOM_DATA;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_SSL3_RANDOM_DATA {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_BYTE_PTR pClientRandom;
* CK_ULONG ulClientRandomLen;
* </PRE>
*/
public byte[] pClientRandom;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_BYTE_PTR pServerRandom;
* CK_ULONG ulServerRandomLen;
* </PRE>
*/
public byte[] pServerRandom;
public CK_SSL3_RANDOM_DATA(byte[] clientRandom, byte[] serverRandom) {
pClientRandom = clientRandom;
pServerRandom = serverRandom;
}
/**
* Returns the string representation of CK_SSL3_RANDOM_DATA.
*
* @return the string representation of CK_SSL3_RANDOM_DATA
*/
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(Constants.INDENT);
buffer.append("pClientRandom: ");
buffer.append(Functions.toHexString(pClientRandom));
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("ulClientRandomLen: ");
buffer.append(pClientRandom.length);
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("pServerRandom: ");
buffer.append(Functions.toHexString(pServerRandom));
buffer.append(Constants.NEWLINE);
buffer.append(Constants.INDENT);
buffer.append("ulServerRandomLen: ");
buffer.append(pServerRandom.length);
//buffer.append(Constants.NEWLINE);
return buffer.toString();
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.pkcs11.wrapper;
/**
* CK_TLS_PRF_PARAMS from PKCS#11 v2.20.
*
* @author Andreas Sterbenz
* @since 1.6
*/
public class CK_TLS_PRF_PARAMS {
public byte[] pSeed;
public byte[] pLabel;
public byte[] pOutput;
public CK_TLS_PRF_PARAMS(byte[] pSeed, byte[] pLabel, byte[] pOutput) {
this.pSeed = pSeed;
this.pLabel = pLabel;
this.pOutput = pOutput;
}
}

View file

@ -0,0 +1,389 @@
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_TOKEN_INFO provides information about a token.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_TOKEN_INFO {&nbsp;&nbsp;
* CK_UTF8CHAR label[32];&nbsp;&nbsp;
* CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
* CK_UTF8CHAR model[16];&nbsp;&nbsp;
* CK_CHAR serialNumber[16];&nbsp;&nbsp;
* CK_FLAGS flags;&nbsp;&nbsp;
* CK_ULONG ulMaxSessionCount;&nbsp;&nbsp;
* CK_ULONG ulSessionCount;&nbsp;&nbsp;
* CK_ULONG ulMaxRwSessionCount;&nbsp;&nbsp;
* CK_ULONG ulRwSessionCount;&nbsp;&nbsp;
* CK_ULONG ulMaxPinLen;&nbsp;&nbsp;
* CK_ULONG ulMinPinLen;&nbsp;&nbsp;
* CK_ULONG ulTotalPublicMemory;&nbsp;&nbsp;
* CK_ULONG ulFreePublicMemory;&nbsp;&nbsp;
* CK_ULONG ulTotalPrivateMemory;&nbsp;&nbsp;
* CK_ULONG ulFreePrivateMemory;&nbsp;&nbsp;
* CK_VERSION hardwareVersion;&nbsp;&nbsp;
* CK_VERSION firmwareVersion;&nbsp;&nbsp;
* CK_CHAR utcTime[16];&nbsp;&nbsp;
* } CK_TOKEN_INFO;
* &nbsp;&nbsp;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_TOKEN_INFO {
/* label, manufacturerID, and model have been changed from
* CK_CHAR to CK_UTF8CHAR for v2.11. */
/**
* must be blank padded and only the first 32 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_UTF8CHAR label[32];
* </PRE>
*/
public char[] label; /* blank padded */
/**
* must be blank padded and only the first 32 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_UTF8CHAR manufacturerID[32];
* </PRE>
*/
public char[] manufacturerID; /* blank padded */
/**
* must be blank padded and only the first 16 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_UTF8CHAR model[16];
* </PRE>
*/
public char[] model; /* blank padded */
/**
* must be blank padded and only the first 16 chars will be used<p>
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR serialNumber[16];
* </PRE>
*/
public char[] serialNumber; /* blank padded */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_FLAGS flags;
* </PRE>
*/
public long flags; /* see below */
/* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
* ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
* changed from CK_USHORT to CK_ULONG for v2.0 */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulMaxSessionCount;
* </PRE>
*/
public long ulMaxSessionCount; /* max open sessions */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulSessionCount;
* </PRE>
*/
public long ulSessionCount; /* sess. now open */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulMaxRwSessionCount;
* </PRE>
*/
public long ulMaxRwSessionCount; /* max R/W sessions */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulRwSessionCount;
* </PRE>
*/
public long ulRwSessionCount; /* R/W sess. now open */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulMaxPinLen;
* </PRE>
*/
public long ulMaxPinLen; /* in bytes */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulMinPinLen;
* </PRE>
*/
public long ulMinPinLen; /* in bytes */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulTotalPublicMemory;
* </PRE>
*/
public long ulTotalPublicMemory; /* in bytes */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulFreePublicMemory;
* </PRE>
*/
public long ulFreePublicMemory; /* in bytes */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulTotalPrivateMemory;
* </PRE>
*/
public long ulTotalPrivateMemory; /* in bytes */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulFreePrivateMemory;
* </PRE>
*/
public long ulFreePrivateMemory; /* in bytes */
/* hardwareVersion, firmwareVersion, and time are new for
* v2.0 */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VERSION hardwareVersion;
* </PRE>
*/
public CK_VERSION hardwareVersion; /* version of hardware */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_VERSION firmwareVersion;
* </PRE>
*/
public CK_VERSION firmwareVersion; /* version of firmware */
/**
* only the first 16 chars will be used
* <B>PKCS#11:</B>
* <PRE>
* CK_CHAR utcTime[16];
* </PRE>
*/
public char[] utcTime; /* time */
public CK_TOKEN_INFO(char[] label, char[] vendor, char[] model,
char[] serialNo, long flags,
long sessionMax, long session,
long rwSessionMax, long rwSession,
long pinLenMax, long pinLenMin,
long totalPubMem, long freePubMem,
long totalPrivMem, long freePrivMem,
CK_VERSION hwVer, CK_VERSION fwVer, char[] utcTime) {
this.label = label;
this.manufacturerID = vendor;
this.model = model;
this.serialNumber = serialNo;
this.flags = flags;
this.ulMaxSessionCount = sessionMax;
this.ulSessionCount = session;
this.ulMaxRwSessionCount = rwSessionMax;
this.ulRwSessionCount = rwSession;
this.ulMaxPinLen = pinLenMax;
this.ulMinPinLen = pinLenMin;
this.ulTotalPublicMemory = totalPubMem;
this.ulFreePublicMemory = freePubMem;
this.ulTotalPrivateMemory = totalPrivMem;
this.ulFreePrivateMemory = freePrivMem;
this.hardwareVersion = hwVer;
this.firmwareVersion = fwVer;
this.utcTime = utcTime;
}
/**
* Returns the string representation of CK_TOKEN_INFO.
*
* @return the string representation of CK_TOKEN_INFO
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("label: ");
sb.append(new String(label));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("manufacturerID: ");
sb.append(new String(manufacturerID));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("model: ");
sb.append(new String(model));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("serialNumber: ");
sb.append(new String(serialNumber));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("flags: ");
sb.append(Functions.tokenInfoFlagsToString(flags));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulMaxSessionCount: ");
sb.append((ulMaxSessionCount == PKCS11Constants.CK_EFFECTIVELY_INFINITE)
? "CK_EFFECTIVELY_INFINITE"
: (ulMaxSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulMaxSessionCount));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulSessionCount: ");
sb.append((ulSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulSessionCount));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulMaxRwSessionCount: ");
sb.append((ulMaxRwSessionCount == PKCS11Constants.CK_EFFECTIVELY_INFINITE)
? "CK_EFFECTIVELY_INFINITE"
: (ulMaxRwSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulMaxRwSessionCount));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulRwSessionCount: ");
sb.append((ulRwSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulRwSessionCount));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulMaxPinLen: ");
sb.append(String.valueOf(ulMaxPinLen));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulMinPinLen: ");
sb.append(String.valueOf(ulMinPinLen));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulTotalPublicMemory: ");
sb.append((ulTotalPublicMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulTotalPublicMemory));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulFreePublicMemory: ");
sb.append((ulFreePublicMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulFreePublicMemory));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulTotalPrivateMemory: ");
sb.append((ulTotalPrivateMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulTotalPrivateMemory));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulFreePrivateMemory: ");
sb.append((ulFreePrivateMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
? "CK_UNAVAILABLE_INFORMATION"
: String.valueOf(ulFreePrivateMemory));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("hardwareVersion: ");
sb.append(hardwareVersion.toString());
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("firmwareVersion: ");
sb.append(firmwareVersion.toString());
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("utcTime: ");
sb.append(new String(utcTime));
//buffer.append(Constants.NEWLINE);
return sb.toString() ;
}
}

View file

@ -0,0 +1,68 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* interface CK_UNLOCKMUTEX<p>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public interface CK_UNLOCKMUTEX {
/**
* Method CK_UNLOCKMUTEX
*
* @param pMutex The mutex (lock) object to unlock.
* @exception PKCS11Exception
*/
public void CK_UNLOCKMUTEX(Object pMutex) throws PKCS11Exception;
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_VERSION describes the version of a Cryptoki interface, a Cryptoki
* library, or an SSL implementation, or the hardware or firmware version of a
* slot or token.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_VERSION {&nbsp;&nbsp;
* CK_BYTE major;&nbsp;&nbsp;
* CK_BYTE minor;&nbsp;&nbsp;
* } CK_VERSION;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class CK_VERSION {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_BYTE major;
* </PRE>
*/
public byte major; /* integer portion of version number */
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_BYTE minor;
* </PRE>
*/
public byte minor; /* 1/100ths portion of version number */
public CK_VERSION(int major, int minor) {
this.major = (byte)major;
this.minor = (byte)minor;
}
/**
* Returns the string representation of CK_VERSION.
*
* @return the string representation of CK_VERSION
*/
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append(major & 0xff);
buffer.append('.');
int m = minor & 0xff;
if (m < 10) {
buffer.append('0');
}
buffer.append(m);
return buffer.toString();
}
}

View file

@ -0,0 +1,132 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
* CKM_X9_42_DH_DERIVE mechanism.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
* CK_X9_42_DH_KDF_TYPE kdf;
* CK_ULONG ulOtherInfoLen;
* CK_BYTE_PTR pOtherInfo;
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* } CK_X9_42_DH1_DERIVE_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
public class CK_X9_42_DH1_DERIVE_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_X9_42_DH_KDF_TYPE kdf;
* </PRE>
*/
public long kdf;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulOtherInfoLen;
* CK_BYTE_PTR pOtherInfo;
* </PRE>
*/
public byte[] pOtherInfo;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* </PRE>
*/
public byte[] pPublicData;
/**
* Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
*
* @return the string representation of CK_PKCS5_PBKD2_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("kdf: 0x");
sb.append(Functions.toFullHexString(kdf));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pOtherInfoLen: ");
sb.append(pOtherInfo.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pOtherInfo: ");
sb.append(Functions.toHexString(pOtherInfo));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicDataLen: ");
sb.append(pPublicData.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicData: ");
sb.append(Functions.toHexString(pPublicData));
//buffer.append(Constants.NEWLINE);
return sb.toString();
}
}

View file

@ -0,0 +1,181 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* class CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
* CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE mechanisms.<p>
* <B>PKCS#11 structure:</B>
* <PRE>
* typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
* CK_X9_42_DH_KDF_TYPE kdf;
* CK_ULONG ulOtherInfoLen;
* CK_BYTE_PTR pOtherInfo;
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* CK_ULONG ulPrivateDataLen;
* CK_OBJECT_HANDLE hPrivateData;
* CK_ULONG ulPublicDataLen2;
* CK_BYTE_PTR pPublicData2;
* } CK_X9_42_DH2_DERIVE_PARAMS;
* </PRE>
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
public class CK_X9_42_DH2_DERIVE_PARAMS {
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_X9_42_DH_KDF_TYPE kdf;
* </PRE>
*/
public long kdf;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulOtherInfoLen;
* CK_BYTE_PTR pOtherInfo;
* </PRE>
*/
public byte[] pOtherInfo;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPublicDataLen;
* CK_BYTE_PTR pPublicData;
* </PRE>
*/
public byte[] pPublicData;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPrivateDataLen;
* </PRE>
*/
public long ulPrivateDataLen;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_OBJECT_HANDLE hPrivateData;
* </PRE>
*/
public long hPrivateData;
/**
* <B>PKCS#11:</B>
* <PRE>
* CK_ULONG ulPublicDataLen2;
* CK_BYTE_PTR pPublicData2;
* </PRE>
*/
public byte[] pPublicData2;
/**
* Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
*
* @return the string representation of CK_PKCS5_PBKD2_PARAMS
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.INDENT);
sb.append("kdf: 0x");
sb.append(Functions.toFullHexString(kdf));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pOtherInfoLen: ");
sb.append(pOtherInfo.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pOtherInfo: ");
sb.append(Functions.toHexString(pOtherInfo));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicDataLen: ");
sb.append(pPublicData.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicData: ");
sb.append(Functions.toHexString(pPublicData));
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("ulPrivateDataLen: ");
sb.append(ulPrivateDataLen);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("hPrivateData: ");
sb.append(hPrivateData);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicDataLen2: ");
sb.append(pPublicData2.length);
sb.append(Constants.NEWLINE);
sb.append(Constants.INDENT);
sb.append("pPublicData2: ");
sb.append(Functions.toHexString(pPublicData2));
//buffer.append(Constants.NEWLINE);
return sb.toString();
}
}

View file

@ -0,0 +1,65 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* This class holds only final static member variables that are constants
* in this package.
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class Constants {
public static final String NEWLINE = System.lineSeparator();
public static final String INDENT = " ";
}

View file

@ -0,0 +1,905 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
import java.math.BigInteger;
import java.util.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
/**
* This class contains onyl static methods. It is the place for all functions
* that are used by several classes in this package.
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
public class Functions {
// maps between ids and their names, forward and reverse
// ids are stored as Integers to save space
// since only the lower 32 bits are ever used anyway
// mechanisms (CKM_*)
private static final Map<Integer,String> mechNames =
new HashMap<Integer,String>();
private static final Map<String,Integer> mechIds =
new HashMap<String,Integer>();
// key types (CKK_*)
private static final Map<Integer,String> keyNames =
new HashMap<Integer,String>();
private static final Map<String,Integer> keyIds =
new HashMap<String,Integer>();
// attributes (CKA_*)
private static final Map<Integer,String> attributeNames =
new HashMap<Integer,String>();
private static final Map<String,Integer> attributeIds =
new HashMap<String,Integer>();
// object classes (CKO_*)
private static final Map<Integer,String> objectClassNames =
new HashMap<Integer,String>();
private static final Map<String,Integer> objectClassIds =
new HashMap<String,Integer>();
/**
* For converting numbers to their hex presentation.
*/
private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
/**
* Converts a long value to a hexadecimal String of length 16. Includes
* leading zeros if necessary.
*
* @param value The long value to be converted.
* @return The hexadecimal string representation of the long value.
*/
public static String toFullHexString(long value) {
long currentValue = value;
StringBuilder sb = new StringBuilder(16);
for(int j = 0; j < 16; j++) {
int currentDigit = (int) currentValue & 0xf;
sb.append(HEX_DIGITS[currentDigit]);
currentValue >>>= 4;
}
return sb.reverse().toString();
}
/**
* Converts a int value to a hexadecimal String of length 8. Includes
* leading zeros if necessary.
*
* @param value The int value to be converted.
* @return The hexadecimal string representation of the int value.
*/
public static String toFullHexString(int value) {
int currentValue = value;
StringBuilder sb = new StringBuilder(8);
for(int i = 0; i < 8; i++) {
int currentDigit = currentValue & 0xf;
sb.append(HEX_DIGITS[currentDigit]);
currentValue >>>= 4;
}
return sb.reverse().toString();
}
/**
* converts a long value to a hexadecimal String
*
* @param value the long value to be converted
* @return the hexadecimal string representation of the long value
*/
public static String toHexString(long value) {
return Long.toHexString(value);
}
/**
* Converts a byte array to a hexadecimal String. Each byte is presented by
* its two digit hex-code; 0x0A -> "0a", 0x00 -> "00". No leading "0x" is
* included in the result.
*
* @param value the byte array to be converted
* @return the hexadecimal string representation of the byte array
*/
public static String toHexString(byte[] value) {
if (value == null) {
return null;
}
StringBuilder sb = new StringBuilder(2 * value.length);
int single;
for (int i = 0; i < value.length; i++) {
single = value[i] & 0xFF;
if (single < 0x10) {
sb.append('0');
}
sb.append(Integer.toString(single, 16));
}
return sb.toString();
}
/**
* converts a long value to a binary String
*
* @param value the long value to be converted
* @return the binary string representation of the long value
*/
public static String toBinaryString(long value) {
return Long.toString(value, 2);
}
/**
* converts a byte array to a binary String
*
* @param value the byte array to be converted
* @return the binary string representation of the byte array
*/
public static String toBinaryString(byte[] value) {
BigInteger helpBigInteger = new BigInteger(1, value);
return helpBigInteger.toString(2);
}
private static class Flags {
private final long[] flagIds;
private final String[] flagNames;
Flags(long[] flagIds, String[] flagNames) {
if (flagIds.length != flagNames.length) {
throw new AssertionError("Array lengths do not match");
}
this.flagIds = flagIds;
this.flagNames = flagNames;
}
String toString(long val) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (int i = 0; i < flagIds.length; i++) {
if ((val & flagIds[i]) != 0) {
if (first == false) {
sb.append(" | ");
}
sb.append(flagNames[i]);
first = false;
}
}
return sb.toString();
}
}
private static final Flags slotInfoFlags = new Flags(new long[] {
CKF_TOKEN_PRESENT,
CKF_REMOVABLE_DEVICE,
CKF_HW_SLOT,
}, new String[] {
"CKF_TOKEN_PRESENT",
"CKF_REMOVABLE_DEVICE",
"CKF_HW_SLOT",
});
/**
* converts the long value flags to a SlotInfoFlag string
*
* @param flags the flags to be converted
* @return the SlotInfoFlag string representation of the flags
*/
public static String slotInfoFlagsToString(long flags) {
return slotInfoFlags.toString(flags);
}
private static final Flags tokenInfoFlags = new Flags(new long[] {
CKF_RNG,
CKF_WRITE_PROTECTED,
CKF_LOGIN_REQUIRED,
CKF_USER_PIN_INITIALIZED,
CKF_RESTORE_KEY_NOT_NEEDED,
CKF_CLOCK_ON_TOKEN,
CKF_PROTECTED_AUTHENTICATION_PATH,
CKF_DUAL_CRYPTO_OPERATIONS,
CKF_TOKEN_INITIALIZED,
CKF_SECONDARY_AUTHENTICATION,
CKF_USER_PIN_COUNT_LOW,
CKF_USER_PIN_FINAL_TRY,
CKF_USER_PIN_LOCKED,
CKF_USER_PIN_TO_BE_CHANGED,
CKF_SO_PIN_COUNT_LOW,
CKF_SO_PIN_FINAL_TRY,
CKF_SO_PIN_LOCKED,
CKF_SO_PIN_TO_BE_CHANGED,
}, new String[] {
"CKF_RNG",
"CKF_WRITE_PROTECTED",
"CKF_LOGIN_REQUIRED",
"CKF_USER_PIN_INITIALIZED",
"CKF_RESTORE_KEY_NOT_NEEDED",
"CKF_CLOCK_ON_TOKEN",
"CKF_PROTECTED_AUTHENTICATION_PATH",
"CKF_DUAL_CRYPTO_OPERATIONS",
"CKF_TOKEN_INITIALIZED",
"CKF_SECONDARY_AUTHENTICATION",
"CKF_USER_PIN_COUNT_LOW",
"CKF_USER_PIN_FINAL_TRY",
"CKF_USER_PIN_LOCKED",
"CKF_USER_PIN_TO_BE_CHANGED",
"CKF_SO_PIN_COUNT_LOW",
"CKF_SO_PIN_FINAL_TRY",
"CKF_SO_PIN_LOCKED",
"CKF_SO_PIN_TO_BE_CHANGED",
});
/**
* converts long value flags to a TokenInfoFlag string
*
* @param flags the flags to be converted
* @return the TokenInfoFlag string representation of the flags
*/
public static String tokenInfoFlagsToString(long flags) {
return tokenInfoFlags.toString(flags);
}
private static final Flags sessionInfoFlags = new Flags(new long[] {
CKF_RW_SESSION,
CKF_SERIAL_SESSION,
}, new String[] {
"CKF_RW_SESSION",
"CKF_SERIAL_SESSION",
});
/**
* converts the long value flags to a SessionInfoFlag string
*
* @param flags the flags to be converted
* @return the SessionInfoFlag string representation of the flags
*/
public static String sessionInfoFlagsToString(long flags) {
return sessionInfoFlags.toString(flags);
}
/**
* converts the long value state to a SessionState string
*
* @param state the state to be converted
* @return the SessionState string representation of the state
*/
public static String sessionStateToString(long state) {
String name;
if (state == CKS_RO_PUBLIC_SESSION) {
name = "CKS_RO_PUBLIC_SESSION";
} else if (state == CKS_RO_USER_FUNCTIONS) {
name = "CKS_RO_USER_FUNCTIONS";
} else if (state == CKS_RW_PUBLIC_SESSION) {
name = "CKS_RW_PUBLIC_SESSION";
} else if (state == CKS_RW_USER_FUNCTIONS) {
name = "CKS_RW_USER_FUNCTIONS";
} else if (state == CKS_RW_SO_FUNCTIONS) {
name = "CKS_RW_SO_FUNCTIONS";
} else {
name = "ERROR: unknown session state 0x" + toFullHexString(state);
}
return name;
}
private static final Flags mechanismInfoFlags = new Flags(new long[] {
CKF_HW,
CKF_ENCRYPT,
CKF_DECRYPT,
CKF_DIGEST,
CKF_SIGN,
CKF_SIGN_RECOVER,
CKF_VERIFY,
CKF_VERIFY_RECOVER,
CKF_GENERATE,
CKF_GENERATE_KEY_PAIR,
CKF_WRAP,
CKF_UNWRAP,
CKF_DERIVE,
CKF_EC_F_P,
CKF_EC_F_2M,
CKF_EC_ECPARAMETERS,
CKF_EC_NAMEDCURVE,
CKF_EC_UNCOMPRESS,
CKF_EC_COMPRESS,
CKF_EXTENSION,
}, new String[] {
"CKF_HW",
"CKF_ENCRYPT",
"CKF_DECRYPT",
"CKF_DIGEST",
"CKF_SIGN",
"CKF_SIGN_RECOVER",
"CKF_VERIFY",
"CKF_VERIFY_RECOVER",
"CKF_GENERATE",
"CKF_GENERATE_KEY_PAIR",
"CKF_WRAP",
"CKF_UNWRAP",
"CKF_DERIVE",
"CKF_EC_F_P",
"CKF_EC_F_2M",
"CKF_EC_ECPARAMETERS",
"CKF_EC_NAMEDCURVE",
"CKF_EC_UNCOMPRESS",
"CKF_EC_COMPRESS",
"CKF_EXTENSION",
});
/**
* converts the long value flags to a MechanismInfoFlag string
*
* @param flags the flags to be converted
* @return the MechanismInfoFlag string representation of the flags
*/
public static String mechanismInfoFlagsToString(long flags) {
return mechanismInfoFlags.toString(flags);
}
private static String getName(Map<Integer,String> nameMap, long id) {
String name = null;
if ((id >>> 32) == 0) {
name = nameMap.get(Integer.valueOf((int)id));
}
if (name == null) {
name = "Unknown 0x" + toFullHexString(id);
}
return name;
}
public static long getId(Map<String,Integer> idMap, String name) {
Integer mech = idMap.get(name);
if (mech == null) {
throw new IllegalArgumentException("Unknown name " + name);
}
return mech.intValue() & 0xffffffffL;
}
public static String getMechanismName(long id) {
return getName(mechNames, id);
}
public static long getMechanismId(String name) {
return getId(mechIds, name);
}
public static String getKeyName(long id) {
return getName(keyNames, id);
}
public static long getKeyId(String name) {
return getId(keyIds, name);
}
public static String getAttributeName(long id) {
return getName(attributeNames, id);
}
public static long getAttributeId(String name) {
return getId(attributeIds, name);
}
public static String getObjectClassName(long id) {
return getName(objectClassNames, id);
}
public static long getObjectClassId(String name) {
return getId(objectClassIds, name);
}
/**
* Check the given arrays for equalitiy. This method considers both arrays as
* equal, if both are <code>null</code> or both have the same length and
* contain exactly the same char values.
*
* @param array1 The first array.
* @param array2 The second array.
* @return True, if both arrays are <code>null</code> or both have the same
* length and contain exactly the same char values. False, otherwise.
* @preconditions
* @postconditions
*/
private static boolean equals(char[] array1, char[] array2) {
return Arrays.equals(array1, array2);
}
/**
* Check the given dates for equalitiy. This method considers both dates as
* equal, if both are <code>null</code> or both contain exactly the same char
* values.
*
* @param date1 The first date.
* @param date2 The second date.
* @return True, if both dates are <code>null</code> or both contain the same
* char values. False, otherwise.
* @preconditions
* @postconditions
*/
public static boolean equals(CK_DATE date1, CK_DATE date2) {
boolean equal = false;
if (date1 == date2) {
equal = true;
} else if ((date1 != null) && (date2 != null)) {
equal = equals(date1.year, date2.year)
&& equals(date1.month, date2.month)
&& equals(date1.day, date2.day);
} else {
equal = false;
}
return equal ;
}
/**
* Calculate a hash code for the given byte array.
*
* @param array The byte array.
* @return A hash code for the given array.
* @preconditions
* @postconditions
*/
public static int hashCode(byte[] array) {
int hash = 0;
if (array != null) {
for (int i = 0; (i < 4) && (i < array.length); i++) {
hash ^= (0xFF & array[i]) << ((i%4) << 3);
}
}
return hash ;
}
/**
* Calculate a hash code for the given char array.
*
* @param array The char array.
* @return A hash code for the given array.
* @preconditions
* @postconditions
*/
public static int hashCode(char[] array) {
int hash = 0;
if (array != null) {
for (int i = 0; (i < 4) && (i < array.length); i++) {
hash ^= (0xFFFF & array[i]) << ((i%2) << 4);
}
}
return hash ;
}
/**
* Calculate a hash code for the given date object.
*
* @param date The date object.
* @return A hash code for the given date.
* @preconditions
* @postconditions
*/
public static int hashCode(CK_DATE date) {
int hash = 0;
if (date != null) {
if (date.year.length == 4) {
hash ^= (0xFFFF & date.year[0]) << 16;
hash ^= 0xFFFF & date.year[1];
hash ^= (0xFFFF & date.year[2]) << 16;
hash ^= 0xFFFF & date.year[3];
}
if (date.month.length == 2) {
hash ^= (0xFFFF & date.month[0]) << 16;
hash ^= 0xFFFF & date.month[1];
}
if (date.day.length == 2) {
hash ^= (0xFFFF & date.day[0]) << 16;
hash ^= 0xFFFF & date.day[1];
}
}
return hash ;
}
private static void addMapping(Map<Integer,String> nameMap,
Map<String,Integer> idMap, long id, String name) {
if ((id >>> 32) != 0) {
throw new AssertionError("Id has high bits set: " + id + ", " + name);
}
Integer intId = Integer.valueOf((int)id);
if (nameMap.put(intId, name) != null) {
throw new AssertionError("Duplicate id: " + id + ", " + name);
}
if (idMap.put(name, intId) != null) {
throw new AssertionError("Duplicate name: " + id + ", " + name);
}
}
private static void addMech(long id, String name) {
addMapping(mechNames, mechIds, id, name);
}
private static void addKeyType(long id, String name) {
addMapping(keyNames, keyIds, id, name);
}
private static void addAttribute(long id, String name) {
addMapping(attributeNames, attributeIds, id, name);
}
private static void addObjectClass(long id, String name) {
addMapping(objectClassNames, objectClassIds, id, name);
}
static {
addMech(CKM_RSA_PKCS_KEY_PAIR_GEN, "CKM_RSA_PKCS_KEY_PAIR_GEN");
addMech(CKM_RSA_PKCS, "CKM_RSA_PKCS");
addMech(CKM_RSA_9796, "CKM_RSA_9796");
addMech(CKM_RSA_X_509, "CKM_RSA_X_509");
addMech(CKM_MD2_RSA_PKCS, "CKM_MD2_RSA_PKCS");
addMech(CKM_MD5_RSA_PKCS, "CKM_MD5_RSA_PKCS");
addMech(CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS");
addMech(CKM_RIPEMD128_RSA_PKCS, "CKM_RIPEMD128_RSA_PKCS");
addMech(CKM_RIPEMD160_RSA_PKCS, "CKM_RIPEMD160_RSA_PKCS");
addMech(CKM_RSA_PKCS_OAEP, "CKM_RSA_PKCS_OAEP");
addMech(CKM_RSA_X9_31_KEY_PAIR_GEN, "CKM_RSA_X9_31_KEY_PAIR_GEN");
addMech(CKM_RSA_X9_31, "CKM_RSA_X9_31");
addMech(CKM_SHA1_RSA_X9_31, "CKM_SHA1_RSA_X9_31");
addMech(CKM_RSA_PKCS_PSS, "CKM_RSA_PKCS_PSS");
addMech(CKM_SHA1_RSA_PKCS_PSS, "CKM_SHA1_RSA_PKCS_PSS");
addMech(CKM_DSA_KEY_PAIR_GEN, "CKM_DSA_KEY_PAIR_GEN");
addMech(CKM_DSA, "CKM_DSA");
addMech(CKM_DSA_SHA1, "CKM_DSA_SHA1");
addMech(CKM_DH_PKCS_KEY_PAIR_GEN, "CKM_DH_PKCS_KEY_PAIR_GEN");
addMech(CKM_DH_PKCS_DERIVE, "CKM_DH_PKCS_DERIVE");
addMech(CKM_X9_42_DH_KEY_PAIR_GEN, "CKM_X9_42_DH_KEY_PAIR_GEN");
addMech(CKM_X9_42_DH_DERIVE, "CKM_X9_42_DH_DERIVE");
addMech(CKM_X9_42_DH_HYBRID_DERIVE, "CKM_X9_42_DH_HYBRID_DERIVE");
addMech(CKM_X9_42_MQV_DERIVE, "CKM_X9_42_MQV_DERIVE");
addMech(CKM_SHA224_RSA_PKCS, "CKM_SHA224_RSA_PKCS");
addMech(CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS");
addMech(CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS");
addMech(CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS");
addMech(CKM_RC2_KEY_GEN, "CKM_RC2_KEY_GEN");
addMech(CKM_RC2_ECB, "CKM_RC2_ECB");
addMech(CKM_RC2_CBC, "CKM_RC2_CBC");
addMech(CKM_RC2_MAC, "CKM_RC2_MAC");
addMech(CKM_RC2_MAC_GENERAL, "CKM_RC2_MAC_GENERAL");
addMech(CKM_RC2_CBC_PAD, "CKM_RC2_CBC_PAD");
addMech(CKM_RC4_KEY_GEN, "CKM_RC4_KEY_GEN");
addMech(CKM_RC4, "CKM_RC4");
addMech(CKM_DES_KEY_GEN, "CKM_DES_KEY_GEN");
addMech(CKM_DES_ECB, "CKM_DES_ECB");
addMech(CKM_DES_CBC, "CKM_DES_CBC");
addMech(CKM_DES_MAC, "CKM_DES_MAC");
addMech(CKM_DES_MAC_GENERAL, "CKM_DES_MAC_GENERAL");
addMech(CKM_DES_CBC_PAD, "CKM_DES_CBC_PAD");
addMech(CKM_DES2_KEY_GEN, "CKM_DES2_KEY_GEN");
addMech(CKM_DES3_KEY_GEN, "CKM_DES3_KEY_GEN");
addMech(CKM_DES3_ECB, "CKM_DES3_ECB");
addMech(CKM_DES3_CBC, "CKM_DES3_CBC");
addMech(CKM_DES3_MAC, "CKM_DES3_MAC");
addMech(CKM_DES3_MAC_GENERAL, "CKM_DES3_MAC_GENERAL");
addMech(CKM_DES3_CBC_PAD, "CKM_DES3_CBC_PAD");
addMech(CKM_CDMF_KEY_GEN, "CKM_CDMF_KEY_GEN");
addMech(CKM_CDMF_ECB, "CKM_CDMF_ECB");
addMech(CKM_CDMF_CBC, "CKM_CDMF_CBC");
addMech(CKM_CDMF_MAC, "CKM_CDMF_MAC");
addMech(CKM_CDMF_MAC_GENERAL, "CKM_CDMF_MAC_GENERAL");
addMech(CKM_CDMF_CBC_PAD, "CKM_CDMF_CBC_PAD");
addMech(CKM_MD2, "CKM_MD2");
addMech(CKM_MD2_HMAC, "CKM_MD2_HMAC");
addMech(CKM_MD2_HMAC_GENERAL, "CKM_MD2_HMAC_GENERAL");
addMech(CKM_MD5, "CKM_MD5");
addMech(CKM_MD5_HMAC, "CKM_MD5_HMAC");
addMech(CKM_MD5_HMAC_GENERAL, "CKM_MD5_HMAC_GENERAL");
addMech(CKM_SHA_1, "CKM_SHA_1");
addMech(CKM_SHA_1_HMAC, "CKM_SHA_1_HMAC");
addMech(CKM_SHA_1_HMAC_GENERAL, "CKM_SHA_1_HMAC_GENERAL");
addMech(CKM_RIPEMD128, "CKM_RIPEMD128");
addMech(CKM_RIPEMD128_HMAC, "CKM_RIPEMD128_HMAC");
addMech(CKM_RIPEMD128_HMAC_GENERAL, "CKM_RIPEMD128_HMAC_GENERAL");
addMech(CKM_RIPEMD160, "CKM_RIPEMD160");
addMech(CKM_RIPEMD160_HMAC, "CKM_RIPEMD160_HMAC");
addMech(CKM_RIPEMD160_HMAC_GENERAL, "CKM_RIPEMD160_HMAC_GENERAL");
addMech(CKM_SHA224, "CKM_SHA224");
addMech(CKM_SHA224_HMAC, "CKM_SHA224_HMAC");
addMech(CKM_SHA224_HMAC_GENERAL, "CKM_SHA224_HMAC_GENERAL");
addMech(CKM_SHA256, "CKM_SHA256");
addMech(CKM_SHA256_HMAC, "CKM_SHA256_HMAC");
addMech(CKM_SHA256_HMAC_GENERAL, "CKM_SHA256_HMAC_GENERAL");
addMech(CKM_SHA384, "CKM_SHA384");
addMech(CKM_SHA384_HMAC, "CKM_SHA384_HMAC");
addMech(CKM_SHA384_HMAC_GENERAL, "CKM_SHA384_HMAC_GENERAL");
addMech(CKM_SHA512, "CKM_SHA512");
addMech(CKM_SHA512_HMAC, "CKM_SHA512_HMAC");
addMech(CKM_SHA512_HMAC_GENERAL, "CKM_SHA512_HMAC_GENERAL");
addMech(CKM_CAST_KEY_GEN, "CKM_CAST_KEY_GEN");
addMech(CKM_CAST_ECB, "CKM_CAST_ECB");
addMech(CKM_CAST_CBC, "CKM_CAST_CBC");
addMech(CKM_CAST_MAC, "CKM_CAST_MAC");
addMech(CKM_CAST_MAC_GENERAL, "CKM_CAST_MAC_GENERAL");
addMech(CKM_CAST_CBC_PAD, "CKM_CAST_CBC_PAD");
addMech(CKM_CAST3_KEY_GEN, "CKM_CAST3_KEY_GEN");
addMech(CKM_CAST3_ECB, "CKM_CAST3_ECB");
addMech(CKM_CAST3_CBC, "CKM_CAST3_CBC");
addMech(CKM_CAST3_MAC, "CKM_CAST3_MAC");
addMech(CKM_CAST3_MAC_GENERAL, "CKM_CAST3_MAC_GENERAL");
addMech(CKM_CAST3_CBC_PAD, "CKM_CAST3_CBC_PAD");
addMech(CKM_CAST128_KEY_GEN, "CKM_CAST128_KEY_GEN");
addMech(CKM_CAST128_ECB, "CKM_CAST128_ECB");
addMech(CKM_CAST128_CBC, "CKM_CAST128_CBC");
addMech(CKM_CAST128_MAC, "CKM_CAST128_MAC");
addMech(CKM_CAST128_MAC_GENERAL, "CKM_CAST128_MAC_GENERAL");
addMech(CKM_CAST128_CBC_PAD, "CKM_CAST128_CBC_PAD");
addMech(CKM_RC5_KEY_GEN, "CKM_RC5_KEY_GEN");
addMech(CKM_RC5_ECB, "CKM_RC5_ECB");
addMech(CKM_RC5_CBC, "CKM_RC5_CBC");
addMech(CKM_RC5_MAC, "CKM_RC5_MAC");
addMech(CKM_RC5_MAC_GENERAL, "CKM_RC5_MAC_GENERAL");
addMech(CKM_RC5_CBC_PAD, "CKM_RC5_CBC_PAD");
addMech(CKM_IDEA_KEY_GEN, "CKM_IDEA_KEY_GEN");
addMech(CKM_IDEA_ECB, "CKM_IDEA_ECB");
addMech(CKM_IDEA_CBC, "CKM_IDEA_CBC");
addMech(CKM_IDEA_MAC, "CKM_IDEA_MAC");
addMech(CKM_IDEA_MAC_GENERAL, "CKM_IDEA_MAC_GENERAL");
addMech(CKM_IDEA_CBC_PAD, "CKM_IDEA_CBC_PAD");
addMech(CKM_GENERIC_SECRET_KEY_GEN, "CKM_GENERIC_SECRET_KEY_GEN");
addMech(CKM_CONCATENATE_BASE_AND_KEY, "CKM_CONCATENATE_BASE_AND_KEY");
addMech(CKM_CONCATENATE_BASE_AND_DATA, "CKM_CONCATENATE_BASE_AND_DATA");
addMech(CKM_CONCATENATE_DATA_AND_BASE, "CKM_CONCATENATE_DATA_AND_BASE");
addMech(CKM_XOR_BASE_AND_DATA, "CKM_XOR_BASE_AND_DATA");
addMech(CKM_EXTRACT_KEY_FROM_KEY, "CKM_EXTRACT_KEY_FROM_KEY");
addMech(CKM_SSL3_PRE_MASTER_KEY_GEN, "CKM_SSL3_PRE_MASTER_KEY_GEN");
addMech(CKM_SSL3_MASTER_KEY_DERIVE, "CKM_SSL3_MASTER_KEY_DERIVE");
addMech(CKM_SSL3_KEY_AND_MAC_DERIVE, "CKM_SSL3_KEY_AND_MAC_DERIVE");
addMech(CKM_SSL3_MASTER_KEY_DERIVE_DH, "CKM_SSL3_MASTER_KEY_DERIVE_DH");
addMech(CKM_TLS_PRE_MASTER_KEY_GEN, "CKM_TLS_PRE_MASTER_KEY_GEN");
addMech(CKM_TLS_MASTER_KEY_DERIVE, "CKM_TLS_MASTER_KEY_DERIVE");
addMech(CKM_TLS_KEY_AND_MAC_DERIVE, "CKM_TLS_KEY_AND_MAC_DERIVE");
addMech(CKM_TLS_MASTER_KEY_DERIVE_DH, "CKM_TLS_MASTER_KEY_DERIVE_DH");
addMech(CKM_TLS_PRF, "CKM_TLS_PRF");
addMech(CKM_SSL3_MD5_MAC, "CKM_SSL3_MD5_MAC");
addMech(CKM_SSL3_SHA1_MAC, "CKM_SSL3_SHA1_MAC");
addMech(CKM_MD5_KEY_DERIVATION, "CKM_MD5_KEY_DERIVATION");
addMech(CKM_MD2_KEY_DERIVATION, "CKM_MD2_KEY_DERIVATION");
addMech(CKM_SHA1_KEY_DERIVATION, "CKM_SHA1_KEY_DERIVATION");
addMech(CKM_SHA224_KEY_DERIVATION, "CKM_SHA224_KEY_DERIVATION");
addMech(CKM_SHA256_KEY_DERIVATION, "CKM_SHA256_KEY_DERIVATION");
addMech(CKM_SHA384_KEY_DERIVATION, "CKM_SHA384_KEY_DERIVATION");
addMech(CKM_SHA512_KEY_DERIVATION, "CKM_SHA512_KEY_DERIVATION");
addMech(CKM_PBE_MD2_DES_CBC, "CKM_PBE_MD2_DES_CBC");
addMech(CKM_PBE_MD5_DES_CBC, "CKM_PBE_MD5_DES_CBC");
addMech(CKM_PBE_MD5_CAST_CBC, "CKM_PBE_MD5_CAST_CBC");
addMech(CKM_PBE_MD5_CAST3_CBC, "CKM_PBE_MD5_CAST3_CBC");
addMech(CKM_PBE_MD5_CAST128_CBC, "CKM_PBE_MD5_CAST128_CBC");
addMech(CKM_PBE_SHA1_CAST128_CBC, "CKM_PBE_SHA1_CAST128_CBC");
addMech(CKM_PBE_SHA1_RC4_128, "CKM_PBE_SHA1_RC4_128");
addMech(CKM_PBE_SHA1_RC4_40, "CKM_PBE_SHA1_RC4_40");
addMech(CKM_PBE_SHA1_DES3_EDE_CBC, "CKM_PBE_SHA1_DES3_EDE_CBC");
addMech(CKM_PBE_SHA1_DES2_EDE_CBC, "CKM_PBE_SHA1_DES2_EDE_CBC");
addMech(CKM_PBE_SHA1_RC2_128_CBC, "CKM_PBE_SHA1_RC2_128_CBC");
addMech(CKM_PBE_SHA1_RC2_40_CBC, "CKM_PBE_SHA1_RC2_40_CBC");
addMech(CKM_PKCS5_PBKD2, "CKM_PKCS5_PBKD2");
addMech(CKM_PBA_SHA1_WITH_SHA1_HMAC, "CKM_PBA_SHA1_WITH_SHA1_HMAC");
addMech(CKM_KEY_WRAP_LYNKS, "CKM_KEY_WRAP_LYNKS");
addMech(CKM_KEY_WRAP_SET_OAEP, "CKM_KEY_WRAP_SET_OAEP");
addMech(CKM_SKIPJACK_KEY_GEN, "CKM_SKIPJACK_KEY_GEN");
addMech(CKM_SKIPJACK_ECB64, "CKM_SKIPJACK_ECB64");
addMech(CKM_SKIPJACK_CBC64, "CKM_SKIPJACK_CBC64");
addMech(CKM_SKIPJACK_OFB64, "CKM_SKIPJACK_OFB64");
addMech(CKM_SKIPJACK_CFB64, "CKM_SKIPJACK_CFB64");
addMech(CKM_SKIPJACK_CFB32, "CKM_SKIPJACK_CFB32");
addMech(CKM_SKIPJACK_CFB16, "CKM_SKIPJACK_CFB16");
addMech(CKM_SKIPJACK_CFB8, "CKM_SKIPJACK_CFB8");
addMech(CKM_SKIPJACK_WRAP, "CKM_SKIPJACK_WRAP");
addMech(CKM_SKIPJACK_PRIVATE_WRAP, "CKM_SKIPJACK_PRIVATE_WRAP");
addMech(CKM_SKIPJACK_RELAYX, "CKM_SKIPJACK_RELAYX");
addMech(CKM_KEA_KEY_PAIR_GEN, "CKM_KEA_KEY_PAIR_GEN");
addMech(CKM_KEA_KEY_DERIVE, "CKM_KEA_KEY_DERIVE");
addMech(CKM_FORTEZZA_TIMESTAMP, "CKM_FORTEZZA_TIMESTAMP");
addMech(CKM_BATON_KEY_GEN, "CKM_BATON_KEY_GEN");
addMech(CKM_BATON_ECB128, "CKM_BATON_ECB128");
addMech(CKM_BATON_ECB96, "CKM_BATON_ECB96");
addMech(CKM_BATON_CBC128, "CKM_BATON_CBC128");
addMech(CKM_BATON_COUNTER, "CKM_BATON_COUNTER");
addMech(CKM_BATON_SHUFFLE, "CKM_BATON_SHUFFLE");
addMech(CKM_BATON_WRAP, "CKM_BATON_WRAP");
addMech(CKM_EC_KEY_PAIR_GEN, "CKM_EC_KEY_PAIR_GEN");
addMech(CKM_ECDSA, "CKM_ECDSA");
addMech(CKM_ECDSA_SHA1, "CKM_ECDSA_SHA1");
addMech(CKM_ECDH1_DERIVE, "CKM_ECDH1_DERIVE");
addMech(CKM_ECDH1_COFACTOR_DERIVE, "CKM_ECDH1_COFACTOR_DERIVE");
addMech(CKM_ECMQV_DERIVE, "CKM_ECMQV_DERIVE");
addMech(CKM_JUNIPER_KEY_GEN, "CKM_JUNIPER_KEY_GEN");
addMech(CKM_JUNIPER_ECB128, "CKM_JUNIPER_ECB128");
addMech(CKM_JUNIPER_CBC128, "CKM_JUNIPER_CBC128");
addMech(CKM_JUNIPER_COUNTER, "CKM_JUNIPER_COUNTER");
addMech(CKM_JUNIPER_SHUFFLE, "CKM_JUNIPER_SHUFFLE");
addMech(CKM_JUNIPER_WRAP, "CKM_JUNIPER_WRAP");
addMech(CKM_FASTHASH, "CKM_FASTHASH");
addMech(CKM_AES_KEY_GEN, "CKM_AES_KEY_GEN");
addMech(CKM_AES_ECB, "CKM_AES_ECB");
addMech(CKM_AES_CBC, "CKM_AES_CBC");
addMech(CKM_AES_MAC, "CKM_AES_MAC");
addMech(CKM_AES_MAC_GENERAL, "CKM_AES_MAC_GENERAL");
addMech(CKM_AES_CBC_PAD, "CKM_AES_CBC_PAD");
addMech(CKM_BLOWFISH_KEY_GEN, "CKM_BLOWFISH_KEY_GEN");
addMech(CKM_BLOWFISH_CBC, "CKM_BLOWFISH_CBC");
addMech(CKM_DSA_PARAMETER_GEN, "CKM_DSA_PARAMETER_GEN");
addMech(CKM_DH_PKCS_PARAMETER_GEN, "CKM_DH_PKCS_PARAMETER_GEN");
addMech(CKM_X9_42_DH_PARAMETER_GEN, "CKM_X9_42_DH_PARAMETER_GEN");
addMech(CKM_VENDOR_DEFINED, "CKM_VENDOR_DEFINED");
addMech(CKM_NSS_TLS_PRF_GENERAL, "CKM_NSS_TLS_PRF_GENERAL");
addMech(PCKM_SECURERANDOM, "SecureRandom");
addMech(PCKM_KEYSTORE, "KeyStore");
addKeyType(CKK_RSA, "CKK_RSA");
addKeyType(CKK_DSA, "CKK_DSA");
addKeyType(CKK_DH, "CKK_DH");
addKeyType(CKK_EC, "CKK_EC");
addKeyType(CKK_X9_42_DH, "CKK_X9_42_DH");
addKeyType(CKK_KEA, "CKK_KEA");
addKeyType(CKK_GENERIC_SECRET, "CKK_GENERIC_SECRET");
addKeyType(CKK_RC2, "CKK_RC2");
addKeyType(CKK_RC4, "CKK_RC4");
addKeyType(CKK_DES, "CKK_DES");
addKeyType(CKK_DES2, "CKK_DES2");
addKeyType(CKK_DES3, "CKK_DES3");
addKeyType(CKK_CAST, "CKK_CAST");
addKeyType(CKK_CAST3, "CKK_CAST3");
addKeyType(CKK_CAST128, "CKK_CAST128");
addKeyType(CKK_RC5, "CKK_RC5");
addKeyType(CKK_IDEA, "CKK_IDEA");
addKeyType(CKK_SKIPJACK, "CKK_SKIPJACK");
addKeyType(CKK_BATON, "CKK_BATON");
addKeyType(CKK_JUNIPER, "CKK_JUNIPER");
addKeyType(CKK_CDMF, "CKK_CDMF");
addKeyType(CKK_AES, "CKK_AES");
addKeyType(CKK_BLOWFISH, "CKK_BLOWFISH");
addKeyType(CKK_VENDOR_DEFINED, "CKK_VENDOR_DEFINED");
addKeyType(PCKK_ANY, "*");
addAttribute(CKA_CLASS, "CKA_CLASS");
addAttribute(CKA_TOKEN, "CKA_TOKEN");
addAttribute(CKA_PRIVATE, "CKA_PRIVATE");
addAttribute(CKA_LABEL, "CKA_LABEL");
addAttribute(CKA_APPLICATION, "CKA_APPLICATION");
addAttribute(CKA_VALUE, "CKA_VALUE");
addAttribute(CKA_OBJECT_ID, "CKA_OBJECT_ID");
addAttribute(CKA_CERTIFICATE_TYPE, "CKA_CERTIFICATE_TYPE");
addAttribute(CKA_ISSUER, "CKA_ISSUER");
addAttribute(CKA_SERIAL_NUMBER, "CKA_SERIAL_NUMBER");
addAttribute(CKA_AC_ISSUER, "CKA_AC_ISSUER");
addAttribute(CKA_OWNER, "CKA_OWNER");
addAttribute(CKA_ATTR_TYPES, "CKA_ATTR_TYPES");
addAttribute(CKA_TRUSTED, "CKA_TRUSTED");
addAttribute(CKA_KEY_TYPE, "CKA_KEY_TYPE");
addAttribute(CKA_SUBJECT, "CKA_SUBJECT");
addAttribute(CKA_ID, "CKA_ID");
addAttribute(CKA_SENSITIVE, "CKA_SENSITIVE");
addAttribute(CKA_ENCRYPT, "CKA_ENCRYPT");
addAttribute(CKA_DECRYPT, "CKA_DECRYPT");
addAttribute(CKA_WRAP, "CKA_WRAP");
addAttribute(CKA_UNWRAP, "CKA_UNWRAP");
addAttribute(CKA_SIGN, "CKA_SIGN");
addAttribute(CKA_SIGN_RECOVER, "CKA_SIGN_RECOVER");
addAttribute(CKA_VERIFY, "CKA_VERIFY");
addAttribute(CKA_VERIFY_RECOVER, "CKA_VERIFY_RECOVER");
addAttribute(CKA_DERIVE, "CKA_DERIVE");
addAttribute(CKA_START_DATE, "CKA_START_DATE");
addAttribute(CKA_END_DATE, "CKA_END_DATE");
addAttribute(CKA_MODULUS, "CKA_MODULUS");
addAttribute(CKA_MODULUS_BITS, "CKA_MODULUS_BITS");
addAttribute(CKA_PUBLIC_EXPONENT, "CKA_PUBLIC_EXPONENT");
addAttribute(CKA_PRIVATE_EXPONENT, "CKA_PRIVATE_EXPONENT");
addAttribute(CKA_PRIME_1, "CKA_PRIME_1");
addAttribute(CKA_PRIME_2, "CKA_PRIME_2");
addAttribute(CKA_EXPONENT_1, "CKA_EXPONENT_1");
addAttribute(CKA_EXPONENT_2, "CKA_EXPONENT_2");
addAttribute(CKA_COEFFICIENT, "CKA_COEFFICIENT");
addAttribute(CKA_PRIME, "CKA_PRIME");
addAttribute(CKA_SUBPRIME, "CKA_SUBPRIME");
addAttribute(CKA_BASE, "CKA_BASE");
addAttribute(CKA_PRIME_BITS, "CKA_PRIME_BITS");
addAttribute(CKA_SUB_PRIME_BITS, "CKA_SUB_PRIME_BITS");
addAttribute(CKA_VALUE_BITS, "CKA_VALUE_BITS");
addAttribute(CKA_VALUE_LEN, "CKA_VALUE_LEN");
addAttribute(CKA_EXTRACTABLE, "CKA_EXTRACTABLE");
addAttribute(CKA_LOCAL, "CKA_LOCAL");
addAttribute(CKA_NEVER_EXTRACTABLE, "CKA_NEVER_EXTRACTABLE");
addAttribute(CKA_ALWAYS_SENSITIVE, "CKA_ALWAYS_SENSITIVE");
addAttribute(CKA_KEY_GEN_MECHANISM, "CKA_KEY_GEN_MECHANISM");
addAttribute(CKA_MODIFIABLE, "CKA_MODIFIABLE");
addAttribute(CKA_EC_PARAMS, "CKA_EC_PARAMS");
addAttribute(CKA_EC_POINT, "CKA_EC_POINT");
addAttribute(CKA_SECONDARY_AUTH, "CKA_SECONDARY_AUTH");
addAttribute(CKA_AUTH_PIN_FLAGS, "CKA_AUTH_PIN_FLAGS");
addAttribute(CKA_HW_FEATURE_TYPE, "CKA_HW_FEATURE_TYPE");
addAttribute(CKA_RESET_ON_INIT, "CKA_RESET_ON_INIT");
addAttribute(CKA_HAS_RESET, "CKA_HAS_RESET");
addAttribute(CKA_VENDOR_DEFINED, "CKA_VENDOR_DEFINED");
addAttribute(CKA_NETSCAPE_DB, "CKA_NETSCAPE_DB");
addAttribute(CKA_NETSCAPE_TRUST_SERVER_AUTH, "CKA_NETSCAPE_TRUST_SERVER_AUTH");
addAttribute(CKA_NETSCAPE_TRUST_CLIENT_AUTH, "CKA_NETSCAPE_TRUST_CLIENT_AUTH");
addAttribute(CKA_NETSCAPE_TRUST_CODE_SIGNING, "CKA_NETSCAPE_TRUST_CODE_SIGNING");
addAttribute(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, "CKA_NETSCAPE_TRUST_EMAIL_PROTECTION");
addAttribute(CKA_NETSCAPE_CERT_SHA1_HASH, "CKA_NETSCAPE_CERT_SHA1_HASH");
addAttribute(CKA_NETSCAPE_CERT_MD5_HASH, "CKA_NETSCAPE_CERT_MD5_HASH");
addObjectClass(CKO_DATA, "CKO_DATA");
addObjectClass(CKO_CERTIFICATE, "CKO_CERTIFICATE");
addObjectClass(CKO_PUBLIC_KEY, "CKO_PUBLIC_KEY");
addObjectClass(CKO_PRIVATE_KEY, "CKO_PRIVATE_KEY");
addObjectClass(CKO_SECRET_KEY, "CKO_SECRET_KEY");
addObjectClass(CKO_HW_FEATURE, "CKO_HW_FEATURE");
addObjectClass(CKO_DOMAIN_PARAMETERS, "CKO_DOMAIN_PARAMETERS");
addObjectClass(CKO_VENDOR_DEFINED, "CKO_VENDOR_DEFINED");
addObjectClass(PCKO_ANY, "*");
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,966 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* This interface holds constants of the PKCS#11 v2.11 standard.
* This is mainly the content of the 'pkcs11t.h' header file.
*
* Mapping of primitiv data types to Java types:
* <pre>
* TRUE .......................................... true
* FALSE ......................................... false
* CK_BYTE ....................................... byte
* CK_CHAR ....................................... char
* CK_UTF8CHAR ................................... char
* CK_BBOOL ...................................... boolean
* CK_ULONG ...................................... long
* CK_LONG ....................................... long
* CK_FLAGS ...................................... long
* CK_NOTIFICATION ............................... long
* CK_SLOT_ID .................................... long
* CK_SESSION_HANDLE ............................. long
* CK_USER_TYPE .................................. long
* CK_SESSION_HANDLE ............................. long
* CK_STATE ...................................... long
* CK_OBJECT_HANDLE .............................. long
* CK_OBJECT_CLASS ............................... long
* CK_HW_FEATURE_TYPE ............................ long
* CK_KEY_TYPE ................................... long
* CK_CERTIFICATE_TYPE ........................... long
* CK_ATTRIBUTE_TYPE ............................. long
* CK_VOID_PTR ................................... Object[]
* CK_BYTE_PTR ................................... byte[]
* CK_CHAR_PTR ................................... char[]
* CK_UTF8CHAR_PTR ............................... char[]
* CK_MECHANISM_TYPE ............................. long
* CK_RV ......................................... long
* CK_RSA_PKCS_OAEP_MGF_TYPE ..................... long
* CK_RSA_PKCS_OAEP_SOURCE_TYPE .................. long
* CK_RC2_PARAMS ................................. long
* CK_MAC_GENERAL_PARAMS ......................... long
* CK_EXTRACT_PARAMS ............................. long
* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE .... long
* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE .............. long
* CK_EC_KDF_TYPE ................................ long
* CK_X9_42_DH_KDF_TYPE .......................... long
* </pre>
*
* @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
* @invariants
*/
public interface PKCS11Constants {
public static final boolean TRUE = true;
public static final boolean FALSE = false;
public static final Object NULL_PTR = null;
/* some special values for certain CK_ULONG variables */
// Cryptoki defines CK_UNAVAILABLE_INFORMATION as (~0UL)
// This means it is 0xffffffff in ILP32/LLP64 but 0xffffffffffffffff in LP64.
// To avoid these differences on the Java side, the native code treats
// CK_UNAVAILABLE_INFORMATION specially and always returns (long)-1 for it.
// See ckULongSpecialToJLong() in pkcs11wrapper.h
public static final long CK_UNAVAILABLE_INFORMATION = -1;
public static final long CK_EFFECTIVELY_INFINITE = 0L;
/* The following value is always invalid if used as a session */
/* handle or object handle */
public static final long CK_INVALID_HANDLE = 0L;
/* CK_NOTIFICATION enumerates the types of notifications that
* Cryptoki provides to an application */
/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
* for v2.0 */
public static final long CKN_SURRENDER = 0L;
/* flags: bit flags that provide capabilities of the slot
* Bit Flag Mask Meaning
*/
public static final long CKF_TOKEN_PRESENT = 0x00000001L;
public static final long CKF_REMOVABLE_DEVICE = 0x00000002L;
public static final long CKF_HW_SLOT = 0x00000004L;
/* The flags parameter is defined as follows:
* Bit Flag Mask Meaning
*/
/* has random # generator */
public static final long CKF_RNG = 0x00000001L;
/* token is write-protected */
public static final long CKF_WRITE_PROTECTED = 0x00000002L;
/* user must login */
public static final long CKF_LOGIN_REQUIRED = 0x00000004L;
/* normal user's PIN is set */
public static final long CKF_USER_PIN_INITIALIZED = 0x00000008L;
/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
* that means that *every* time the state of cryptographic
* operations of a session is successfully saved, all keys
* needed to continue those operations are stored in the state */
public static final long CKF_RESTORE_KEY_NOT_NEEDED = 0x00000020L;
/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
* that the token has some sort of clock. The time on that
* clock is returned in the token info structure */
public static final long CKF_CLOCK_ON_TOKEN = 0x00000040L;
/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
* set, that means that there is some way for the user to login
* without sending a PIN through the Cryptoki library itself */
public static final long CKF_PROTECTED_AUTHENTICATION_PATH = 0x00000100L;
/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
* that means that a single session with the token can perform
* dual simultaneous cryptographic operations (digest and
* encrypt; decrypt and digest; sign and encrypt; and decrypt
* and sign) */
public static final long CKF_DUAL_CRYPTO_OPERATIONS = 0x00000200L;
/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
* token has been initialized using C_InitializeToken or an
* equivalent mechanism outside the scope of PKCS #11.
* Calling C_InitializeToken when this flag is set will cause
* the token to be reinitialized. */
public static final long CKF_TOKEN_INITIALIZED = 0x00000400L;
/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
* true, the token supports secondary authentication for
* private key objects. */
public static final long CKF_SECONDARY_AUTHENTICATION = 0x00000800L;
/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
* incorrect user login PIN has been entered at least once
* since the last successful authentication. */
public static final long CKF_USER_PIN_COUNT_LOW = 0x00010000L;
/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
* supplying an incorrect user PIN will it to become locked. */
public static final long CKF_USER_PIN_FINAL_TRY = 0x00020000L;
/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
* user PIN has been locked. User login to the token is not
* possible. */
public static final long CKF_USER_PIN_LOCKED = 0x00040000L;
/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
* the user PIN value is the default value set by token
* initialization or manufacturing. */
public static final long CKF_USER_PIN_TO_BE_CHANGED = 0x00080000L;
/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
* incorrect SO login PIN has been entered at least once since
* the last successful authentication. */
public static final long CKF_SO_PIN_COUNT_LOW = 0x00100000L;
/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
* supplying an incorrect SO PIN will it to become locked. */
public static final long CKF_SO_PIN_FINAL_TRY = 0x00200000L;
/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
* PIN has been locked. SO login to the token is not possible.
*/
public static final long CKF_SO_PIN_LOCKED = 0x00400000L;
/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
* the SO PIN value is the default value set by token
* initialization or manufacturing. */
public static final long CKF_SO_PIN_TO_BE_CHANGED = 0x00800000L;
/* CK_USER_TYPE enumerates the types of Cryptoki users */
/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
* v2.0 */
/* Security Officer */
public static final long CKU_SO = 0L;
/* Normal user */
public static final long CKU_USER = 1L;
/* CK_STATE enumerates the session states */
/* CK_STATE has been changed from an enum to a CK_ULONG for
* v2.0 */
public static final long CKS_RO_PUBLIC_SESSION = 0L;
public static final long CKS_RO_USER_FUNCTIONS = 1L;
public static final long CKS_RW_PUBLIC_SESSION = 2L;
public static final long CKS_RW_USER_FUNCTIONS = 3L;
public static final long CKS_RW_SO_FUNCTIONS = 4L;
/* The flags are defined in the following table:
* Bit Flag Mask Meaning
*/
/* session is r/w */
public static final long CKF_RW_SESSION = 0x00000002L;
/* no parallel */
public static final long CKF_SERIAL_SESSION = 0x00000004L;
/* The following classes of objects are defined: */
/* CKO_HW_FEATURE is new for v2.10 */
/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
public static final long CKO_DATA = 0x00000000L;
public static final long CKO_CERTIFICATE = 0x00000001L;
public static final long CKO_PUBLIC_KEY = 0x00000002L;
public static final long CKO_PRIVATE_KEY = 0x00000003L;
public static final long CKO_SECRET_KEY = 0x00000004L;
public static final long CKO_HW_FEATURE = 0x00000005L;
public static final long CKO_DOMAIN_PARAMETERS = 0x00000006L;
public static final long CKO_VENDOR_DEFINED = 0x80000000L;
// pseudo object class ANY (for template manager)
public static final long PCKO_ANY = 0x7FFFFF23L;
/* The following hardware feature types are defined */
public static final long CKH_MONOTONIC_COUNTER = 0x00000001L;
public static final long CKH_CLOCK = 0x00000002L;
public static final long CKH_VENDOR_DEFINED = 0x80000000L;
/* the following key types are defined: */
public static final long CKK_RSA = 0x00000000L;
public static final long CKK_DSA = 0x00000001L;
public static final long CKK_DH = 0x00000002L;
/* CKK_ECDSA and CKK_KEA are new for v2.0 */
/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
public static final long CKK_ECDSA = 0x00000003L;
public static final long CKK_EC = 0x00000003L;
public static final long CKK_X9_42_DH = 0x00000004L;
public static final long CKK_KEA = 0x00000005L;
public static final long CKK_GENERIC_SECRET = 0x00000010L;
public static final long CKK_RC2 = 0x00000011L;
public static final long CKK_RC4 = 0x00000012L;
public static final long CKK_DES = 0x00000013L;
public static final long CKK_DES2 = 0x00000014L;
public static final long CKK_DES3 = 0x00000015L;
/* all these key types are new for v2.0 */
public static final long CKK_CAST = 0x00000016L;
public static final long CKK_CAST3 = 0x00000017L;
/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
public static final long CKK_CAST5 = 0x00000018L;
/* CAST128=CAST5 */
public static final long CKK_CAST128 = 0x00000018L;
public static final long CKK_RC5 = 0x00000019L;
public static final long CKK_IDEA = 0x0000001AL;
public static final long CKK_SKIPJACK = 0x0000001BL;
public static final long CKK_BATON = 0x0000001CL;
public static final long CKK_JUNIPER = 0x0000001DL;
public static final long CKK_CDMF = 0x0000001EL;
public static final long CKK_AES = 0x0000001FL;
// v2.20
public static final long CKK_BLOWFISH = 0x00000020L;
public static final long CKK_VENDOR_DEFINED = 0x80000000L;
// new for v2.20 amendment 3
//public static final long CKK_CAMELLIA = 0x00000025L;
//public static final long CKK_ARIA = 0x00000026L;
// pseudo key type ANY (for template manager)
public static final long PCKK_ANY = 0x7FFFFF22L;
public static final long PCKK_HMAC = 0x7FFFFF23L;
public static final long PCKK_SSLMAC = 0x7FFFFF24L;
public static final long PCKK_TLSPREMASTER = 0x7FFFFF25L;
public static final long PCKK_TLSRSAPREMASTER = 0x7FFFFF26L;
public static final long PCKK_TLSMASTER = 0x7FFFFF27L;
/* The following certificate types are defined: */
/* CKC_X_509_ATTR_CERT is new for v2.10 */
public static final long CKC_X_509 = 0x00000000L;
public static final long CKC_X_509_ATTR_CERT = 0x00000001L;
public static final long CKC_VENDOR_DEFINED = 0x80000000L;
/* The following attribute types are defined: */
public static final long CKA_CLASS = 0x00000000L;
public static final long CKA_TOKEN = 0x00000001L;
public static final long CKA_PRIVATE = 0x00000002L;
public static final long CKA_LABEL = 0x00000003L;
public static final long CKA_APPLICATION = 0x00000010L;
public static final long CKA_VALUE = 0x00000011L;
/* CKA_OBJECT_ID is new for v2.10 */
public static final long CKA_OBJECT_ID = 0x00000012L;
public static final long CKA_CERTIFICATE_TYPE = 0x00000080L;
public static final long CKA_ISSUER = 0x00000081L;
public static final long CKA_SERIAL_NUMBER = 0x00000082L;
/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new L;
* for v2.10 */
public static final long CKA_AC_ISSUER = 0x00000083L;
public static final long CKA_OWNER = 0x00000084L;
public static final long CKA_ATTR_TYPES = 0x00000085L;
/* CKA_TRUSTED is new for v2.11 */
public static final long CKA_TRUSTED = 0x00000086L;
public static final long CKA_KEY_TYPE = 0x00000100L;
public static final long CKA_SUBJECT = 0x00000101L;
public static final long CKA_ID = 0x00000102L;
public static final long CKA_SENSITIVE = 0x00000103L;
public static final long CKA_ENCRYPT = 0x00000104L;
public static final long CKA_DECRYPT = 0x00000105L;
public static final long CKA_WRAP = 0x00000106L;
public static final long CKA_UNWRAP = 0x00000107L;
public static final long CKA_SIGN = 0x00000108L;
public static final long CKA_SIGN_RECOVER = 0x00000109L;
public static final long CKA_VERIFY = 0x0000010AL;
public static final long CKA_VERIFY_RECOVER = 0x0000010BL;
public static final long CKA_DERIVE = 0x0000010CL;
public static final long CKA_START_DATE = 0x00000110L;
public static final long CKA_END_DATE = 0x00000111L;
public static final long CKA_MODULUS = 0x00000120L;
public static final long CKA_MODULUS_BITS = 0x00000121L;
public static final long CKA_PUBLIC_EXPONENT = 0x00000122L;
public static final long CKA_PRIVATE_EXPONENT = 0x00000123L;
public static final long CKA_PRIME_1 = 0x00000124L;
public static final long CKA_PRIME_2 = 0x00000125L;
public static final long CKA_EXPONENT_1 = 0x00000126L;
public static final long CKA_EXPONENT_2 = 0x00000127L;
public static final long CKA_COEFFICIENT = 0x00000128L;
public static final long CKA_PRIME = 0x00000130L;
public static final long CKA_SUBPRIME = 0x00000131L;
public static final long CKA_BASE = 0x00000132L;
/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
public static final long CKA_PRIME_BITS = 0x00000133L;
public static final long CKA_SUB_PRIME_BITS = 0x00000134L;
public static final long CKA_VALUE_BITS = 0x00000160L;
public static final long CKA_VALUE_LEN = 0x00000161L;
/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
* CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
* and CKA_EC_POINT are new for v2.0 */
public static final long CKA_EXTRACTABLE = 0x00000162L;
public static final long CKA_LOCAL = 0x00000163L;
public static final long CKA_NEVER_EXTRACTABLE = 0x00000164L;
public static final long CKA_ALWAYS_SENSITIVE = 0x00000165L;
/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
public static final long CKA_KEY_GEN_MECHANISM = 0x00000166L;
public static final long CKA_MODIFIABLE = 0x00000170L;
/* CKA_ECDSA_PARAMS is deprecated in v2.11,
* CKA_EC_PARAMS is preferred. */
public static final long CKA_ECDSA_PARAMS = 0x00000180L;
public static final long CKA_EC_PARAMS = 0x00000180L;
public static final long CKA_EC_POINT = 0x00000181L;
/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
* are new for v2.10 */
public static final long CKA_SECONDARY_AUTH = 0x00000200L;
public static final long CKA_AUTH_PIN_FLAGS = 0x00000201L;
public static final long CKA_HW_FEATURE_TYPE = 0x00000300L;
public static final long CKA_RESET_ON_INIT = 0x00000301L;
public static final long CKA_HAS_RESET = 0x00000302L;
public static final long CKA_VENDOR_DEFINED = 0x80000000L;
/* the following mechanism types are defined: */
public static final long CKM_RSA_PKCS_KEY_PAIR_GEN = 0x00000000L;
public static final long CKM_RSA_PKCS = 0x00000001L;
public static final long CKM_RSA_9796 = 0x00000002L;
public static final long CKM_RSA_X_509 = 0x00000003L;
/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
* are new for v2.0. They are mechanisms which hash and sign */
public static final long CKM_MD2_RSA_PKCS = 0x00000004L;
public static final long CKM_MD5_RSA_PKCS = 0x00000005L;
public static final long CKM_SHA1_RSA_PKCS = 0x00000006L;
/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
* CKM_RSA_PKCS_OAEP are new for v2.10 */
public static final long CKM_RIPEMD128_RSA_PKCS = 0x00000007L;
public static final long CKM_RIPEMD160_RSA_PKCS = 0x00000008L;
public static final long CKM_RSA_PKCS_OAEP = 0x00000009L;
/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
* CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
public static final long CKM_RSA_X9_31_KEY_PAIR_GEN = 0x0000000AL;
public static final long CKM_RSA_X9_31 = 0x0000000BL;
public static final long CKM_SHA1_RSA_X9_31 = 0x0000000CL;
public static final long CKM_RSA_PKCS_PSS = 0x0000000DL;
public static final long CKM_SHA1_RSA_PKCS_PSS = 0x0000000EL;
public static final long CKM_DSA_KEY_PAIR_GEN = 0x00000010L;
public static final long CKM_DSA = 0x00000011L;
public static final long CKM_DSA_SHA1 = 0x00000012L;
public static final long CKM_DH_PKCS_KEY_PAIR_GEN = 0x00000020L;
public static final long CKM_DH_PKCS_DERIVE = 0x00000021L;
/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
* CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
* v2.11 */
public static final long CKM_X9_42_DH_KEY_PAIR_GEN = 0x00000030L;
public static final long CKM_X9_42_DH_DERIVE = 0x00000031L;
public static final long CKM_X9_42_DH_HYBRID_DERIVE = 0x00000032L;
public static final long CKM_X9_42_MQV_DERIVE = 0x00000033L;
// v2.20
public static final long CKM_SHA256_RSA_PKCS = 0x00000040L;
public static final long CKM_SHA384_RSA_PKCS = 0x00000041L;
public static final long CKM_SHA512_RSA_PKCS = 0x00000042L;
public static final long CKM_RC2_KEY_GEN = 0x00000100L;
public static final long CKM_RC2_ECB = 0x00000101L;
public static final long CKM_RC2_CBC = 0x00000102L;
public static final long CKM_RC2_MAC = 0x00000103L;
/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
public static final long CKM_RC2_MAC_GENERAL = 0x00000104L;
public static final long CKM_RC2_CBC_PAD = 0x00000105L;
public static final long CKM_RC4_KEY_GEN = 0x00000110L;
public static final long CKM_RC4 = 0x00000111L;
public static final long CKM_DES_KEY_GEN = 0x00000120L;
public static final long CKM_DES_ECB = 0x00000121L;
public static final long CKM_DES_CBC = 0x00000122L;
public static final long CKM_DES_MAC = 0x00000123L;
/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
public static final long CKM_DES_MAC_GENERAL = 0x00000124L;
public static final long CKM_DES_CBC_PAD = 0x00000125L;
public static final long CKM_DES2_KEY_GEN = 0x00000130L;
public static final long CKM_DES3_KEY_GEN = 0x00000131L;
public static final long CKM_DES3_ECB = 0x00000132L;
public static final long CKM_DES3_CBC = 0x00000133L;
public static final long CKM_DES3_MAC = 0x00000134L;
/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
* CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
* CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
public static final long CKM_DES3_MAC_GENERAL = 0x00000135L;
public static final long CKM_DES3_CBC_PAD = 0x00000136L;
public static final long CKM_CDMF_KEY_GEN = 0x00000140L;
public static final long CKM_CDMF_ECB = 0x00000141L;
public static final long CKM_CDMF_CBC = 0x00000142L;
public static final long CKM_CDMF_MAC = 0x00000143L;
public static final long CKM_CDMF_MAC_GENERAL = 0x00000144L;
public static final long CKM_CDMF_CBC_PAD = 0x00000145L;
public static final long CKM_MD2 = 0x00000200L;
/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
public static final long CKM_MD2_HMAC = 0x00000201L;
public static final long CKM_MD2_HMAC_GENERAL = 0x00000202L;
public static final long CKM_MD5 = 0x00000210L;
/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
public static final long CKM_MD5_HMAC = 0x00000211L;
public static final long CKM_MD5_HMAC_GENERAL = 0x00000212L;
public static final long CKM_SHA_1 = 0x00000220L;
/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
public static final long CKM_SHA_1_HMAC = 0x00000221L;
public static final long CKM_SHA_1_HMAC_GENERAL = 0x00000222L;
/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
* CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
* and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
public static final long CKM_RIPEMD128 = 0x00000230L;
public static final long CKM_RIPEMD128_HMAC = 0x00000231L;
public static final long CKM_RIPEMD128_HMAC_GENERAL = 0x00000232L;
public static final long CKM_RIPEMD160 = 0x00000240L;
public static final long CKM_RIPEMD160_HMAC = 0x00000241L;
public static final long CKM_RIPEMD160_HMAC_GENERAL = 0x00000242L;
// v2.20
public static final long CKM_SHA256 = 0x00000250L;
public static final long CKM_SHA256_HMAC = 0x00000251L;
public static final long CKM_SHA256_HMAC_GENERAL = 0x00000252L;
public static final long CKM_SHA384 = 0x00000260L;
public static final long CKM_SHA384_HMAC = 0x00000261L;
public static final long CKM_SHA384_HMAC_GENERAL = 0x00000262L;
public static final long CKM_SHA512 = 0x00000270L;
public static final long CKM_SHA512_HMAC = 0x00000271L;
public static final long CKM_SHA512_HMAC_GENERAL = 0x00000272L;
/* All of the following mechanisms are new for v2.0 */
/* Note that CAST128 and CAST5 are the same algorithm */
public static final long CKM_CAST_KEY_GEN = 0x00000300L;
public static final long CKM_CAST_ECB = 0x00000301L;
public static final long CKM_CAST_CBC = 0x00000302L;
public static final long CKM_CAST_MAC = 0x00000303L;
public static final long CKM_CAST_MAC_GENERAL = 0x00000304L;
public static final long CKM_CAST_CBC_PAD = 0x00000305L;
public static final long CKM_CAST3_KEY_GEN = 0x00000310L;
public static final long CKM_CAST3_ECB = 0x00000311L;
public static final long CKM_CAST3_CBC = 0x00000312L;
public static final long CKM_CAST3_MAC = 0x00000313L;
public static final long CKM_CAST3_MAC_GENERAL = 0x00000314L;
public static final long CKM_CAST3_CBC_PAD = 0x00000315L;
public static final long CKM_CAST5_KEY_GEN = 0x00000320L;
public static final long CKM_CAST128_KEY_GEN = 0x00000320L;
public static final long CKM_CAST5_ECB = 0x00000321L;
public static final long CKM_CAST128_ECB = 0x00000321L;
public static final long CKM_CAST5_CBC = 0x00000322L;
public static final long CKM_CAST128_CBC = 0x00000322L;
public static final long CKM_CAST5_MAC = 0x00000323L;
public static final long CKM_CAST128_MAC = 0x00000323L;
public static final long CKM_CAST5_MAC_GENERAL = 0x00000324L;
public static final long CKM_CAST128_MAC_GENERAL = 0x00000324L;
public static final long CKM_CAST5_CBC_PAD = 0x00000325L;
public static final long CKM_CAST128_CBC_PAD = 0x00000325L;
public static final long CKM_RC5_KEY_GEN = 0x00000330L;
public static final long CKM_RC5_ECB = 0x00000331L;
public static final long CKM_RC5_CBC = 0x00000332L;
public static final long CKM_RC5_MAC = 0x00000333L;
public static final long CKM_RC5_MAC_GENERAL = 0x00000334L;
public static final long CKM_RC5_CBC_PAD = 0x00000335L;
public static final long CKM_IDEA_KEY_GEN = 0x00000340L;
public static final long CKM_IDEA_ECB = 0x00000341L;
public static final long CKM_IDEA_CBC = 0x00000342L;
public static final long CKM_IDEA_MAC = 0x00000343L;
public static final long CKM_IDEA_MAC_GENERAL = 0x00000344L;
public static final long CKM_IDEA_CBC_PAD = 0x00000345L;
public static final long CKM_GENERIC_SECRET_KEY_GEN = 0x00000350L;
public static final long CKM_CONCATENATE_BASE_AND_KEY = 0x00000360L;
public static final long CKM_CONCATENATE_BASE_AND_DATA = 0x00000362L;
public static final long CKM_CONCATENATE_DATA_AND_BASE = 0x00000363L;
public static final long CKM_XOR_BASE_AND_DATA = 0x00000364L;
public static final long CKM_EXTRACT_KEY_FROM_KEY = 0x00000365L;
public static final long CKM_SSL3_PRE_MASTER_KEY_GEN = 0x00000370L;
public static final long CKM_SSL3_MASTER_KEY_DERIVE = 0x00000371L;
public static final long CKM_SSL3_KEY_AND_MAC_DERIVE = 0x00000372L;
/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
* CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
* CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
public static final long CKM_SSL3_MASTER_KEY_DERIVE_DH = 0x00000373L;
public static final long CKM_TLS_PRE_MASTER_KEY_GEN = 0x00000374L;
public static final long CKM_TLS_MASTER_KEY_DERIVE = 0x00000375L;
public static final long CKM_TLS_KEY_AND_MAC_DERIVE = 0x00000376L;
public static final long CKM_TLS_MASTER_KEY_DERIVE_DH = 0x00000377L;
public static final long CKM_TLS_PRF = 0x00000378L;
public static final long CKM_SSL3_MD5_MAC = 0x00000380L;
public static final long CKM_SSL3_SHA1_MAC = 0x00000381L;
public static final long CKM_MD5_KEY_DERIVATION = 0x00000390L;
public static final long CKM_MD2_KEY_DERIVATION = 0x00000391L;
public static final long CKM_SHA1_KEY_DERIVATION = 0x00000392L;
// v2.20
public static final long CKM_SHA256_KEY_DERIVATION = 0x00000393L;
public static final long CKM_SHA384_KEY_DERIVATION = 0x00000394L;
public static final long CKM_SHA512_KEY_DERIVATION = 0x00000395L;
public static final long CKM_PBE_MD2_DES_CBC = 0x000003A0L;
public static final long CKM_PBE_MD5_DES_CBC = 0x000003A1L;
public static final long CKM_PBE_MD5_CAST_CBC = 0x000003A2L;
public static final long CKM_PBE_MD5_CAST3_CBC = 0x000003A3L;
public static final long CKM_PBE_MD5_CAST5_CBC = 0x000003A4L;
public static final long CKM_PBE_MD5_CAST128_CBC = 0x000003A4L;
public static final long CKM_PBE_SHA1_CAST5_CBC = 0x000003A5L;
public static final long CKM_PBE_SHA1_CAST128_CBC = 0x000003A5L;
public static final long CKM_PBE_SHA1_RC4_128 = 0x000003A6L;
public static final long CKM_PBE_SHA1_RC4_40 = 0x000003A7L;
public static final long CKM_PBE_SHA1_DES3_EDE_CBC = 0x000003A8L;
public static final long CKM_PBE_SHA1_DES2_EDE_CBC = 0x000003A9L;
public static final long CKM_PBE_SHA1_RC2_128_CBC = 0x000003AAL;
public static final long CKM_PBE_SHA1_RC2_40_CBC = 0x000003ABL;
/* CKM_PKCS5_PBKD2 is new for v2.10 */
public static final long CKM_PKCS5_PBKD2 = 0x000003B0L;
public static final long CKM_PBA_SHA1_WITH_SHA1_HMAC = 0x000003C0L;
public static final long CKM_KEY_WRAP_LYNKS = 0x00000400L;
public static final long CKM_KEY_WRAP_SET_OAEP = 0x00000401L;
/* Fortezza mechanisms */
public static final long CKM_SKIPJACK_KEY_GEN = 0x00001000L;
public static final long CKM_SKIPJACK_ECB64 = 0x00001001L;
public static final long CKM_SKIPJACK_CBC64 = 0x00001002L;
public static final long CKM_SKIPJACK_OFB64 = 0x00001003L;
public static final long CKM_SKIPJACK_CFB64 = 0x00001004L;
public static final long CKM_SKIPJACK_CFB32 = 0x00001005L;
public static final long CKM_SKIPJACK_CFB16 = 0x00001006L;
public static final long CKM_SKIPJACK_CFB8 = 0x00001007L;
public static final long CKM_SKIPJACK_WRAP = 0x00001008L;
public static final long CKM_SKIPJACK_PRIVATE_WRAP = 0x00001009L;
public static final long CKM_SKIPJACK_RELAYX = 0x0000100AL;
public static final long CKM_KEA_KEY_PAIR_GEN = 0x00001010L;
public static final long CKM_KEA_KEY_DERIVE = 0x00001011L;
public static final long CKM_FORTEZZA_TIMESTAMP = 0x00001020L;
public static final long CKM_BATON_KEY_GEN = 0x00001030L;
public static final long CKM_BATON_ECB128 = 0x00001031L;
public static final long CKM_BATON_ECB96 = 0x00001032L;
public static final long CKM_BATON_CBC128 = 0x00001033L;
public static final long CKM_BATON_COUNTER = 0x00001034L;
public static final long CKM_BATON_SHUFFLE = 0x00001035L;
public static final long CKM_BATON_WRAP = 0x00001036L;
/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
* CKM_EC_KEY_PAIR_GEN is preferred */
public static final long CKM_ECDSA_KEY_PAIR_GEN = 0x00001040L;
public static final long CKM_EC_KEY_PAIR_GEN = 0x00001040L;
public static final long CKM_ECDSA = 0x00001041L;
public static final long CKM_ECDSA_SHA1 = 0x00001042L;
/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
* are new for v2.11 */
public static final long CKM_ECDH1_DERIVE = 0x00001050L;
public static final long CKM_ECDH1_COFACTOR_DERIVE = 0x00001051L;
public static final long CKM_ECMQV_DERIVE = 0x00001052L;
public static final long CKM_JUNIPER_KEY_GEN = 0x00001060L;
public static final long CKM_JUNIPER_ECB128 = 0x00001061L;
public static final long CKM_JUNIPER_CBC128 = 0x00001062L;
public static final long CKM_JUNIPER_COUNTER = 0x00001063L;
public static final long CKM_JUNIPER_SHUFFLE = 0x00001064L;
public static final long CKM_JUNIPER_WRAP = 0x00001065L;
public static final long CKM_FASTHASH = 0x00001070L;
/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
* CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
* CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
* new for v2.11 */
public static final long CKM_AES_KEY_GEN = 0x00001080L;
public static final long CKM_AES_ECB = 0x00001081L;
public static final long CKM_AES_CBC = 0x00001082L;
public static final long CKM_AES_MAC = 0x00001083L;
public static final long CKM_AES_MAC_GENERAL = 0x00001084L;
public static final long CKM_AES_CBC_PAD = 0x00001085L;
// v2.20
public static final long CKM_BLOWFISH_KEY_GEN = 0x00001090L;
public static final long CKM_BLOWFISH_CBC = 0x00001091L;
public static final long CKM_DSA_PARAMETER_GEN = 0x00002000L;
public static final long CKM_DH_PKCS_PARAMETER_GEN = 0x00002001L;
public static final long CKM_X9_42_DH_PARAMETER_GEN = 0x00002002L;
public static final long CKM_VENDOR_DEFINED = 0x80000000L;
// new for v2.20 amendment 3
public static final long CKM_SHA224 = 0x00000255L;
public static final long CKM_SHA224_HMAC = 0x00000256L;
public static final long CKM_SHA224_HMAC_GENERAL = 0x00000257L;
public static final long CKM_SHA224_KEY_DERIVATION = 0x00000396L;
public static final long CKM_SHA224_RSA_PKCS = 0x00000046L;
public static final long CKM_SHA224_RSA_PKCS_PSS = 0x00000047L;
public static final long CKM_AES_CTR = 0x00001086L;
/*
public static final long CKM_CAMELLIA_KEY_GEN = 0x00000550L;
public static final long CKM_CAMELLIA_ECB = 0x00000551L;
public static final long CKM_CAMELLIA_CBC = 0x00000552L;
public static final long CKM_CAMELLIA_MAC = 0x00000553L;
public static final long CKM_CAMELLIA_MAC_GENERAL = 0x00000554L;
public static final long CKM_CAMELLIA_CBC_PAD = 0x00000555L;
public static final long CKM_CAMELLIA_ECB_ENCRYPT_DATA = 0x00000556L;
public static final long CKM_CAMELLIA_CBC_ENCRYPT_DATA = 0x00000557L;
public static final long CKM_CAMELLIA_CTR = 0x00000558L;
public static final long CKM_ARIA_KEY_GEN = 0x00000560L;
public static final long CKM_ARIA_ECB = 0x00000561L;
public static final long CKM_ARIA_CBC = 0x00000562L;
public static final long CKM_ARIA_MAC = 0x00000563L;
public static final long CKM_ARIA_MAC_GENERAL = 0x00000564L;
public static final long CKM_ARIA_CBC_PAD = 0x00000565L;
public static final long CKM_ARIA_ECB_ENCRYPT_DATA = 0x00000566L;
public static final long CKM_ARIA_CBC_ENCRYPT_DATA = 0x00000567L;
*/
// NSS private
public static final long CKM_NSS_TLS_PRF_GENERAL = 0x80000373L;
// ids for our pseudo mechanisms SecureRandom and KeyStore
public static final long PCKM_SECURERANDOM = 0x7FFFFF20L;
public static final long PCKM_KEYSTORE = 0x7FFFFF21L;
/* The flags are defined as follows:
* Bit Flag Mask Meaning */
/* performed by HW */
public static final long CKF_HW = 0x00000001L;
/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
* CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
* CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
* and CKF_DERIVE are new for v2.0. They specify whether or not
* a mechanism can be used for a particular task */
public static final long CKF_ENCRYPT = 0x00000100L;
public static final long CKF_DECRYPT = 0x00000200L;
public static final long CKF_DIGEST = 0x00000400L;
public static final long CKF_SIGN = 0x00000800L;
public static final long CKF_SIGN_RECOVER = 0x00001000L;
public static final long CKF_VERIFY = 0x00002000L;
public static final long CKF_VERIFY_RECOVER = 0x00004000L;
public static final long CKF_GENERATE = 0x00008000L;
public static final long CKF_GENERATE_KEY_PAIR = 0x00010000L;
public static final long CKF_WRAP = 0x00020000L;
public static final long CKF_UNWRAP = 0x00040000L;
public static final long CKF_DERIVE = 0x00080000L;
/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
* CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
* describe a token's EC capabilities not available in mechanism
* information. */
public static final long CKF_EC_F_P = 0x00100000L;
public static final long CKF_EC_F_2M = 0x00200000L;
public static final long CKF_EC_ECPARAMETERS = 0x00400000L;
public static final long CKF_EC_NAMEDCURVE = 0x00800000L;
public static final long CKF_EC_UNCOMPRESS = 0x01000000L;
public static final long CKF_EC_COMPRESS = 0x02000000L;
/* FALSE for 2.01 */
public static final long CKF_EXTENSION = 0x80000000L;
/* CK_RV is a value that identifies the return value of a
* Cryptoki function */
/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
public static final long CKR_OK = 0x00000000L;
public static final long CKR_CANCEL = 0x00000001L;
public static final long CKR_HOST_MEMORY = 0x00000002L;
public static final long CKR_SLOT_ID_INVALID = 0x00000003L;
/* CKR_FLAGS_INVALID was removed for v2.0 */
/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
public static final long CKR_GENERAL_ERROR = 0x00000005L;
public static final long CKR_FUNCTION_FAILED = 0x00000006L;
/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
* and CKR_CANT_LOCK are new for v2.01 */
public static final long CKR_ARGUMENTS_BAD = 0x00000007L;
public static final long CKR_NO_EVENT = 0x00000008L;
public static final long CKR_NEED_TO_CREATE_THREADS = 0x00000009L;
public static final long CKR_CANT_LOCK = 0x0000000AL;
public static final long CKR_ATTRIBUTE_READ_ONLY = 0x00000010L;
public static final long CKR_ATTRIBUTE_SENSITIVE = 0x00000011L;
public static final long CKR_ATTRIBUTE_TYPE_INVALID = 0x00000012L;
public static final long CKR_ATTRIBUTE_VALUE_INVALID = 0x00000013L;
public static final long CKR_DATA_INVALID = 0x00000020L;
public static final long CKR_DATA_LEN_RANGE = 0x00000021L;
public static final long CKR_DEVICE_ERROR = 0x00000030L;
public static final long CKR_DEVICE_MEMORY = 0x00000031L;
public static final long CKR_DEVICE_REMOVED = 0x00000032L;
public static final long CKR_ENCRYPTED_DATA_INVALID = 0x00000040L;
public static final long CKR_ENCRYPTED_DATA_LEN_RANGE = 0x00000041L;
public static final long CKR_FUNCTION_CANCELED = 0x00000050L;
public static final long CKR_FUNCTION_NOT_PARALLEL = 0x00000051L;
/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
public static final long CKR_FUNCTION_NOT_SUPPORTED = 0x00000054L;
public static final long CKR_KEY_HANDLE_INVALID = 0x00000060L;
/* CKR_KEY_SENSITIVE was removed for v2.0 */
public static final long CKR_KEY_SIZE_RANGE = 0x00000062L;
public static final long CKR_KEY_TYPE_INCONSISTENT = 0x00000063L;
/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
* CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
* CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
* v2.0 */
public static final long CKR_KEY_NOT_NEEDED = 0x00000064L;
public static final long CKR_KEY_CHANGED = 0x00000065L;
public static final long CKR_KEY_NEEDED = 0x00000066L;
public static final long CKR_KEY_INDIGESTIBLE = 0x00000067L;
public static final long CKR_KEY_FUNCTION_NOT_PERMITTED = 0x00000068L;
public static final long CKR_KEY_NOT_WRAPPABLE = 0x00000069L;
public static final long CKR_KEY_UNEXTRACTABLE = 0x0000006AL;
public static final long CKR_MECHANISM_INVALID = 0x00000070L;
public static final long CKR_MECHANISM_PARAM_INVALID = 0x00000071L;
/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
* were removed for v2.0 */
public static final long CKR_OBJECT_HANDLE_INVALID = 0x00000082L;
public static final long CKR_OPERATION_ACTIVE = 0x00000090L;
public static final long CKR_OPERATION_NOT_INITIALIZED = 0x00000091L;
public static final long CKR_PIN_INCORRECT = 0x000000A0L;
public static final long CKR_PIN_INVALID = 0x000000A1L;
public static final long CKR_PIN_LEN_RANGE = 0x000000A2L;
/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
public static final long CKR_PIN_EXPIRED = 0x000000A3L;
public static final long CKR_PIN_LOCKED = 0x000000A4L;
public static final long CKR_SESSION_CLOSED = 0x000000B0L;
public static final long CKR_SESSION_COUNT = 0x000000B1L;
public static final long CKR_SESSION_HANDLE_INVALID = 0x000000B3L;
public static final long CKR_SESSION_PARALLEL_NOT_SUPPORTED = 0x000000B4L;
public static final long CKR_SESSION_READ_ONLY = 0x000000B5L;
public static final long CKR_SESSION_EXISTS = 0x000000B6L;
/* CKR_SESSION_READ_ONLY_EXISTS and
* CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
public static final long CKR_SESSION_READ_ONLY_EXISTS = 0x000000B7L;
public static final long CKR_SESSION_READ_WRITE_SO_EXISTS = 0x000000B8L;
public static final long CKR_SIGNATURE_INVALID = 0x000000C0L;
public static final long CKR_SIGNATURE_LEN_RANGE = 0x000000C1L;
public static final long CKR_TEMPLATE_INCOMPLETE = 0x000000D0L;
public static final long CKR_TEMPLATE_INCONSISTENT = 0x000000D1L;
public static final long CKR_TOKEN_NOT_PRESENT = 0x000000E0L;
public static final long CKR_TOKEN_NOT_RECOGNIZED = 0x000000E1L;
public static final long CKR_TOKEN_WRITE_PROTECTED = 0x000000E2L;
public static final long CKR_UNWRAPPING_KEY_HANDLE_INVALID = 0x000000F0L;
public static final long CKR_UNWRAPPING_KEY_SIZE_RANGE = 0x000000F1L;
public static final long CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT = 0x000000F2L;
public static final long CKR_USER_ALREADY_LOGGED_IN = 0x00000100L;
public static final long CKR_USER_NOT_LOGGED_IN = 0x00000101L;
public static final long CKR_USER_PIN_NOT_INITIALIZED = 0x00000102L;
public static final long CKR_USER_TYPE_INVALID = 0x00000103L;
/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
* are new to v2.01 */
public static final long CKR_USER_ANOTHER_ALREADY_LOGGED_IN = 0x00000104L;
public static final long CKR_USER_TOO_MANY_TYPES = 0x00000105L;
public static final long CKR_WRAPPED_KEY_INVALID = 0x00000110L;
public static final long CKR_WRAPPED_KEY_LEN_RANGE = 0x00000112L;
public static final long CKR_WRAPPING_KEY_HANDLE_INVALID = 0x00000113L;
public static final long CKR_WRAPPING_KEY_SIZE_RANGE = 0x00000114L;
public static final long CKR_WRAPPING_KEY_TYPE_INCONSISTENT = 0x00000115L;
public static final long CKR_RANDOM_SEED_NOT_SUPPORTED = 0x00000120L;
/* These are new to v2.0 */
public static final long CKR_RANDOM_NO_RNG = 0x00000121L;
/* These are new to v2.11 */
public static final long CKR_DOMAIN_PARAMS_INVALID = 0x00000130L;
/* These are new to v2.0 */
public static final long CKR_BUFFER_TOO_SMALL = 0x00000150L;
public static final long CKR_SAVED_STATE_INVALID = 0x00000160L;
public static final long CKR_INFORMATION_SENSITIVE = 0x00000170L;
public static final long CKR_STATE_UNSAVEABLE = 0x00000180L;
/* These are new to v2.01 */
public static final long CKR_CRYPTOKI_NOT_INITIALIZED = 0x00000190L;
public static final long CKR_CRYPTOKI_ALREADY_INITIALIZED = 0x00000191L;
public static final long CKR_MUTEX_BAD = 0x000001A0L;
public static final long CKR_MUTEX_NOT_LOCKED = 0x000001A1L;
public static final long CKR_VENDOR_DEFINED = 0x80000000L;
/* flags: bit flags that provide capabilities of the slot
* Bit Flag = Mask
*/
public static final long CKF_LIBRARY_CANT_CREATE_OS_THREADS = 0x00000001L;
public static final long CKF_OS_LOCKING_OK = 0x00000002L;
/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
public static final long CKF_DONT_BLOCK = 1L;
/* The following MGFs are defined */
public static final long CKG_MGF1_SHA1 = 0x00000001L;
// new for v2.20 amendment 3
public static final long CKG_MGF1_SHA224 = 0x00000005L;
/* The following encoding parameter sources are defined */
public static final long CKZ_DATA_SPECIFIED = 0x00000001L;
/* The following PRFs are defined in PKCS #5 v2.0. */
public static final long CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L;
/* The following salt value sources are defined in PKCS #5 v2.0. */
public static final long CKZ_SALT_SPECIFIED = 0x00000001L;
/* the following EC Key Derivation Functions are defined */
public static final long CKD_NULL = 0x00000001L;
public static final long CKD_SHA1_KDF = 0x00000002L;
/* the following X9.42 Diffie-Hellman Key Derivation Functions are defined */
public static final long CKD_SHA1_KDF_ASN1 = 0x00000003L;
public static final long CKD_SHA1_KDF_CONCATENATE = 0x00000004L;
// private NSS attribute (for DSA and DH private keys)
public static final long CKA_NETSCAPE_DB = 0xD5A0DB00L;
// base number of NSS private attributes
public static final long CKA_NETSCAPE_BASE = 0x80000000L + 0x4E534350L;
// object type for NSS trust
public static final long CKO_NETSCAPE_TRUST = CKA_NETSCAPE_BASE + 3;
// base number for NSS trust attributes
public static final long CKA_NETSCAPE_TRUST_BASE = CKA_NETSCAPE_BASE + 0x2000;
// attributes for NSS trust
public static final long CKA_NETSCAPE_TRUST_SERVER_AUTH = CKA_NETSCAPE_TRUST_BASE + 8;
public static final long CKA_NETSCAPE_TRUST_CLIENT_AUTH = CKA_NETSCAPE_TRUST_BASE + 9;
public static final long CKA_NETSCAPE_TRUST_CODE_SIGNING = CKA_NETSCAPE_TRUST_BASE + 10;
public static final long CKA_NETSCAPE_TRUST_EMAIL_PROTECTION = CKA_NETSCAPE_TRUST_BASE + 11;
public static final long CKA_NETSCAPE_CERT_SHA1_HASH = CKA_NETSCAPE_TRUST_BASE + 100;
public static final long CKA_NETSCAPE_CERT_MD5_HASH = CKA_NETSCAPE_TRUST_BASE + 101;
// trust values for each of the NSS trust attributes
public static final long CKT_NETSCAPE_TRUSTED = CKA_NETSCAPE_BASE + 1;
public static final long CKT_NETSCAPE_TRUSTED_DELEGATOR = CKA_NETSCAPE_BASE + 2;
public static final long CKT_NETSCAPE_UNTRUSTED = CKA_NETSCAPE_BASE + 3;
public static final long CKT_NETSCAPE_MUST_VERIFY = CKA_NETSCAPE_BASE + 4;
public static final long CKT_NETSCAPE_TRUST_UNKNOWN = CKA_NETSCAPE_BASE + 5; /* default */
public static final long CKT_NETSCAPE_VALID = CKA_NETSCAPE_BASE + 10;
public static final long CKT_NETSCAPE_VALID_DELEGATOR = CKA_NETSCAPE_BASE + 11;
}

View file

@ -0,0 +1,296 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
import java.util.*;
/**
* This is the superclass of all checked exceptions used by this package. An
* exception of this class indicates that a function call to the underlying
* PKCS#11 module returned a value not equal to CKR_OK. The application can get
* the returned value by calling getErrorCode(). A return value not equal to
* CKR_OK is the only reason for such an exception to be thrown.
* PKCS#11 defines the meaning of an error-code, which may depend on the
* context in which the error occurs.
*
* @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
* @invariants
*/
public class PKCS11Exception extends Exception {
private static final long serialVersionUID = 4877072363729195L;
/**
* The code of the error which was the reason for this exception.
*/
protected long errorCode_;
private static final Map<Long,String> errorMap;
static {
int[] errorCodes = new int[] {
0x00000000,
0x00000001,
0x00000002,
0x00000003,
0x00000005,
0x00000006,
0x00000007,
0x00000008,
0x00000009,
0x0000000A,
0x00000010,
0x00000011,
0x00000012,
0x00000013,
0x00000020,
0x00000021,
0x00000030,
0x00000031,
0x00000032,
0x00000040,
0x00000041,
0x00000050,
0x00000051,
0x00000054,
0x00000060,
0x00000062,
0x00000063,
0x00000064,
0x00000065,
0x00000066,
0x00000067,
0x00000068,
0x00000069,
0x0000006A,
0x00000070,
0x00000071,
0x00000082,
0x00000090,
0x00000091,
0x000000A0,
0x000000A1,
0x000000A2,
0x000000A3,
0x000000A4,
0x000000B0,
0x000000B1,
0x000000B3,
0x000000B4,
0x000000B5,
0x000000B6,
0x000000B7,
0x000000B8,
0x000000C0,
0x000000C1,
0x000000D0,
0x000000D1,
0x000000E0,
0x000000E1,
0x000000E2,
0x000000F0,
0x000000F1,
0x000000F2,
0x00000100,
0x00000101,
0x00000102,
0x00000103,
0x00000104,
0x00000105,
0x00000110,
0x00000112,
0x00000113,
0x00000114,
0x00000115,
0x00000120,
0x00000121,
0x00000130,
0x00000150,
0x00000160,
0x00000170,
0x00000180,
0x00000190,
0x00000191,
0x000001A0,
0x000001A1,
0x00000200,
0x80000000,
};
String[] errorMessages = new String[] {
"CKR_OK",
"CKR_CANCEL",
"CKR_HOST_MEMORY",
"CKR_SLOT_ID_INVALID",
"CKR_GENERAL_ERROR",
"CKR_FUNCTION_FAILED",
"CKR_ARGUMENTS_BAD",
"CKR_NO_EVENT",
"CKR_NEED_TO_CREATE_THREADS",
"CKR_CANT_LOCK",
"CKR_ATTRIBUTE_READ_ONLY",
"CKR_ATTRIBUTE_SENSITIVE",
"CKR_ATTRIBUTE_TYPE_INVALID",
"CKR_ATTRIBUTE_VALUE_INVALID",
"CKR_DATA_INVALID",
"CKR_DATA_LEN_RANGE",
"CKR_DEVICE_ERROR",
"CKR_DEVICE_MEMORY",
"CKR_DEVICE_REMOVED",
"CKR_ENCRYPTED_DATA_INVALID",
"CKR_ENCRYPTED_DATA_LEN_RANGE",
"CKR_FUNCTION_CANCELED",
"CKR_FUNCTION_NOT_PARALLEL",
"CKR_FUNCTION_NOT_SUPPORTED",
"CKR_KEY_HANDLE_INVALID",
"CKR_KEY_SIZE_RANGE",
"CKR_KEY_TYPE_INCONSISTENT",
"CKR_KEY_NOT_NEEDED",
"CKR_KEY_CHANGED",
"CKR_KEY_NEEDED",
"CKR_KEY_INDIGESTIBLE",
"CKR_KEY_FUNCTION_NOT_PERMITTED",
"CKR_KEY_NOT_WRAPPABLE",
"CKR_KEY_UNEXTRACTABLE",
"CKR_MECHANISM_INVALID",
"CKR_MECHANISM_PARAM_INVALID",
"CKR_OBJECT_HANDLE_INVALID",
"CKR_OPERATION_ACTIVE",
"CKR_OPERATION_NOT_INITIALIZED",
"CKR_PIN_INCORRECT",
"CKR_PIN_INVALID",
"CKR_PIN_LEN_RANGE",
"CKR_PIN_EXPIRED",
"CKR_PIN_LOCKED",
"CKR_SESSION_CLOSED",
"CKR_SESSION_COUNT",
"CKR_SESSION_HANDLE_INVALID",
"CKR_SESSION_PARALLEL_NOT_SUPPORTED",
"CKR_SESSION_READ_ONLY",
"CKR_SESSION_EXISTS",
"CKR_SESSION_READ_ONLY_EXISTS",
"CKR_SESSION_READ_WRITE_SO_EXISTS",
"CKR_SIGNATURE_INVALID",
"CKR_SIGNATURE_LEN_RANGE",
"CKR_TEMPLATE_INCOMPLETE",
"CKR_TEMPLATE_INCONSISTENT",
"CKR_TOKEN_NOT_PRESENT",
"CKR_TOKEN_NOT_RECOGNIZED",
"CKR_TOKEN_WRITE_PROTECTED",
"CKR_UNWRAPPING_KEY_HANDLE_INVALID",
"CKR_UNWRAPPING_KEY_SIZE_RANGE",
"CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT",
"CKR_USER_ALREADY_LOGGED_IN",
"CKR_USER_NOT_LOGGED_IN",
"CKR_USER_PIN_NOT_INITIALIZED",
"CKR_USER_TYPE_INVALID",
"CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
"CKR_USER_TOO_MANY_TYPES",
"CKR_WRAPPED_KEY_INVALID",
"CKR_WRAPPED_KEY_LEN_RANGE",
"CKR_WRAPPING_KEY_HANDLE_INVALID",
"CKR_WRAPPING_KEY_SIZE_RANGE",
"CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
"CKR_RANDOM_SEED_NOT_SUPPORTED",
"CKR_RANDOM_NO_RNG",
"CKR_DOMAIN_PARAMS_INVALID",
"CKR_BUFFER_TOO_SMALL",
"CKR_SAVED_STATE_INVALID",
"CKR_INFORMATION_SENSITIVE",
"CKR_STATE_UNSAVEABLE",
"CKR_CRYPTOKI_NOT_INITIALIZED",
"CKR_CRYPTOKI_ALREADY_INITIALIZED",
"CKR_MUTEX_BAD",
"CKR_MUTEX_NOT_LOCKED",
"CKR_FUNCTION_REJECTED",
"CKR_VENDOR_DEFINED",
};
errorMap = new HashMap<Long,String>();
for (int i = 0; i < errorCodes.length; i++) {
errorMap.put(Long.valueOf(errorCodes[i]), errorMessages[i]);
}
}
/**
* Constructor taking the error code as defined for the CKR_* constants
* in PKCS#11.
*/
public PKCS11Exception(long errorCode) {
errorCode_ = errorCode;
}
/**
* This method gets the corresponding text error message from
* a property file. If this file is not available, it returns the error
* code as a hex-string.
*
* @return The message or the error code; e.g. "CKR_DEVICE_ERROR" or
* "0x00000030".
* @preconditions
* @postconditions (result <> null)
*/
public String getMessage() {
String message = errorMap.get(Long.valueOf(errorCode_));
if (message == null) {
message = "0x" + Functions.toFullHexString((int)errorCode_);
}
return message;
}
/**
* Returns the PKCS#11 error code.
*
* @return The error code; e.g. 0x00000030.
* @preconditions
* @postconditions
*/
public long getErrorCode() {
return errorCode_ ;
}
}

View file

@ -0,0 +1,109 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package sun.security.pkcs11.wrapper;
/**
* This is the superclass of all runtime exception used by this library.
* For instance, Runtime exceptions occur, if an internal error in the native
* part of the wrapper occurs.
*
* @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
* @invariants
*/
public class PKCS11RuntimeException extends RuntimeException {
private static final long serialVersionUID = 7889842162743590564L;
/**
* Empty constructor.
*
* @preconditions
* @postconditions
*/
public PKCS11RuntimeException() {
super();
}
/**
* Constructor taking a string that describes the reason of the exception
* in more detail.
*
* @param message A descrption of the reason for this exception.
* @preconditions
* @postconditions
*/
public PKCS11RuntimeException(String message) {
super(message);
}
/**
* Constructor taking an other exception to wrap.
*
* @param encapsulatedException The other exception the wrap into this.
* @preconditions
* @postconditions
*/
public PKCS11RuntimeException(Exception encapsulatedException) {
super(encapsulatedException);
}
/**
* Constructor taking a message for this exception and an other exception to
* wrap.
*
* @param message The message giving details about the exception to ease
* debugging.
* @param encapsulatedException The other exception the wrap into this.
* @preconditions
* @postconditions
*/
public PKCS11RuntimeException(String message, Exception encapsulatedException) {
super(message, encapsulatedException);
}
}

View file

@ -0,0 +1,20 @@
## PKCS #11 Cryptographic Token Interface v2.20 Amendment 3 Header Files
### PKCS #11 Cryptographic Token Interface License
<pre>
License to copy and use this software is granted provided that it is
identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
(Cryptoki)" in all material mentioning or referencing this software.
License is also granted to make and use derivative works provided that
such works are identified as "derived from the RSA Security Inc. PKCS #11
Cryptographic Token Interface (Cryptoki)" in all material mentioning or
referencing the derived work.
RSA Security Inc. makes no representations concerning either the
merchantability of this software or the suitability of this software for
any particular purpose. It is provided "as is" without express or implied
warranty of any kind.
</pre>

View file

@ -0,0 +1,46 @@
## IAIK (Institute for Applied Information Processing and Communication) PKCS#11 wrapper files v1
### IAIK License
<pre>
Copyright (c) 2002 Graz University of Technology. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment:
"This product includes software developed by IAIK of Graz University of
Technology."
Alternately, this acknowledgment may appear in the software itself, if and
wherever such third-party acknowledgments normally appear.
4. The names "Graz University of Technology" and "IAIK of Graz University of
Technology" must not be used to endorse or promote products derived from this
software without prior written permission.
5. Products derived from this software may not be called "IAIK PKCS Wrapper",
nor may "IAIK" appear in their name, without prior written permission of
Graz University of Technology.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
</pre>

View file

@ -0,0 +1,233 @@
/*
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// #define SECMOD_DEBUG
#include "j2secmod.h"
#include "jni_util.h"
JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssVersionCheck
(JNIEnv *env, jclass thisClass, jlong jHandle, jstring jVersion)
{
int res = 0;
FPTR_VersionCheck versionCheck;
const char *requiredVersion;
versionCheck = (FPTR_VersionCheck)findFunction(env, jHandle,
"NSS_VersionCheck");
if (versionCheck == NULL) {
return JNI_FALSE;
}
requiredVersion = (*env)->GetStringUTFChars(env, jVersion, NULL);
if (requiredVersion == NULL) {
return JNI_FALSE;
}
res = versionCheck(requiredVersion);
dprintf2("-version >=%s: %d\n", requiredVersion, res);
(*env)->ReleaseStringUTFChars(env, jVersion, requiredVersion);
return (res == 0) ? JNI_FALSE : JNI_TRUE;
}
/*
* Initializes NSS.
* The NSS_INIT_OPTIMIZESPACE flag is supplied by the caller.
* The NSS_Init* functions are mapped to the NSS_Initialize function.
*/
JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssInitialize
(JNIEnv *env, jclass thisClass, jstring jFunctionName, jlong jHandle, jstring jConfigDir, jboolean jNssOptimizeSpace)
{
int res = 0;
FPTR_Initialize initialize =
(FPTR_Initialize)findFunction(env, jHandle, "NSS_Initialize");
unsigned int flags = 0x00;
const char *configDir = NULL;
const char *functionName = NULL;
/* If we cannot initialize, exit now */
if (initialize == NULL) {
res = 1;
goto cleanup;
}
functionName = (*env)->GetStringUTFChars(env, jFunctionName, NULL);
if (functionName == NULL) {
res = 1;
goto cleanup;
}
if (jConfigDir != NULL) {
configDir = (*env)->GetStringUTFChars(env, jConfigDir, NULL);
if (!configDir) {
res = 1;
goto cleanup;
}
}
if (jNssOptimizeSpace == JNI_TRUE) {
flags = 0x20; // NSS_INIT_OPTIMIZESPACE flag
}
/*
* If the NSS_Init function is requested then call NSS_Initialize to
* open the Cert, Key and Security Module databases, read only.
*/
if (strcmp("NSS_Init", functionName) == 0) {
flags = flags | 0x01; // NSS_INIT_READONLY flag
res = initialize(configDir, "", "", "secmod.db", flags);
/*
* If the NSS_InitReadWrite function is requested then call
* NSS_Initialize to open the Cert, Key and Security Module databases,
* read/write.
*/
} else if (strcmp("NSS_InitReadWrite", functionName) == 0) {
res = initialize(configDir, "", "", "secmod.db", flags);
/*
* If the NSS_NoDB_Init function is requested then call
* NSS_Initialize without creating Cert, Key or Security Module
* databases.
*/
} else if (strcmp("NSS_NoDB_Init", functionName) == 0) {
flags = flags | 0x02 // NSS_INIT_NOCERTDB flag
| 0x04 // NSS_INIT_NOMODDB flag
| 0x08 // NSS_INIT_FORCEOPEN flag
| 0x10; // NSS_INIT_NOROOTINIT flag
res = initialize("", "", "", "", flags);
} else {
res = 2;
}
cleanup:
if (functionName != NULL) {
(*env)->ReleaseStringUTFChars(env, jFunctionName, functionName);
}
if (configDir != NULL) {
(*env)->ReleaseStringUTFChars(env, jConfigDir, configDir);
}
dprintf1("-res: %d\n", res);
return (res == 0) ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList
(JNIEnv *env, jclass thisClass, jlong jHandle, jstring jLibDir)
{
FPTR_GetDBModuleList getModuleList =
(FPTR_GetDBModuleList)findFunction(env, jHandle, "SECMOD_GetDefaultModuleList");
SECMODModuleList *list;
SECMODModule *module;
jclass jListClass, jModuleClass;
jobject jList, jModule;
jmethodID jListConstructor, jAdd, jModuleConstructor;
jstring jCommonName, jDllName;
jboolean jFIPS;
jint i;
if (getModuleList == NULL) {
dprintf("-getmodulelist function not found\n");
return NULL;
}
list = getModuleList();
if (list == NULL) {
dprintf("-module list is null\n");
return NULL;
}
jListClass = (*env)->FindClass(env, "java/util/ArrayList");
if (jListClass == NULL) {
return NULL;
}
jListConstructor = (*env)->GetMethodID(env, jListClass, "<init>", "()V");
if (jListConstructor == NULL) {
return NULL;
}
jAdd = (*env)->GetMethodID(env, jListClass, "add", "(Ljava/lang/Object;)Z");
if (jAdd == NULL) {
return NULL;
}
jList = (*env)->NewObject(env, jListClass, jListConstructor);
if (jList == NULL) {
return NULL;
}
jModuleClass = (*env)->FindClass(env, "sun/security/pkcs11/Secmod$Module");
if (jModuleClass == NULL) {
return NULL;
}
jModuleConstructor = (*env)->GetMethodID(env, jModuleClass, "<init>",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V");
if (jModuleConstructor == NULL) {
return NULL;
}
while (list != NULL) {
module = list->module;
// assert module != null
dprintf1("-commonname: %s\n", module->commonName);
dprintf1("-dllname: %s\n", (module->dllName != NULL) ? module->dllName : "NULL");
dprintf1("-slots: %d\n", module->slotCount);
dprintf1("-loaded: %d\n", module->loaded);
dprintf1("-internal: %d\n", module->internal);
dprintf1("-fips: %d\n", module->isFIPS);
jCommonName = (*env)->NewStringUTF(env, module->commonName);
if (jCommonName == NULL) {
return NULL;
}
if (module->dllName == NULL) {
jDllName = NULL;
} else {
jDllName = (*env)->NewStringUTF(env, module->dllName);
if (jDllName == NULL) {
return NULL;
}
}
jFIPS = module->isFIPS;
for (i = 0; i < module->slotCount; i++ ) {
jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor,
jLibDir, jDllName, jCommonName, jFIPS, i);
if (jModule == NULL) {
return NULL;
}
(*env)->CallVoidMethod(env, jList, jAdd, jModule);
if ((*env)->ExceptionCheck(env)) {
return NULL;
}
}
list = list->next;
}
dprintf("-ok\n");
return jList;
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <jni.h>
#include "sun_security_pkcs11_Secmod.h"
// #define SECMOD_DEBUG
#include "j2secmod_md.h"
#include "p11_md.h"
void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName);
#ifdef SECMOD_DEBUG
#define dprintf(s) printf(s)
#define dprintf1(s, p1) printf(s, p1)
#define dprintf2(s, p1, p2) printf(s, p1, p2)
#define dprintf3(s, p1, p2, p3) printf(s, p1, p2, p3)
#else
#define dprintf(s)
#define dprintf1(s, p1)
#define dprintf2(s, p1, p2)
#define dprintf3(s, p1, p2, p3)
#endif
// NSS types
typedef int PRBool;
typedef struct SECMODModuleStr SECMODModule;
typedef struct SECMODModuleListStr SECMODModuleList;
struct SECMODModuleStr {
void *v1;
PRBool internal; /* true of internally linked modules, false
* for the loaded modules */
PRBool loaded; /* Set to true if module has been loaded */
PRBool isFIPS; /* Set to true if module is finst internal */
char *dllName; /* name of the shared library which implements
* this module */
char *commonName; /* name of the module to display to the user */
void *library; /* pointer to the library. opaque. used only by
* pk11load.c */
void *functionList; /* The PKCS #11 function table */
void *refLock; /* only used pk11db.c */
int refCount; /* Module reference count */
void **slots; /* array of slot points attached to this mod*/
int slotCount; /* count of slot in above array */
void *slotInfo; /* special info about slots default settings */
int slotInfoCount; /* count */
// incomplete, sizeof() is wrong
};
struct SECMODModuleListStr {
SECMODModuleList *next;
SECMODModule *module;
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,489 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* ===========================================================================
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
#ifdef P11_ENABLE_C_ENCRYPTINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_EncryptInit
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptInit
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jobject jMechanism, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckKeyHandle = jLongToCKULong(jKeyHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, &ckMechanism,
ckKeyHandle);
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_ENCRYPT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Encrypt
* Signature: (J[BII[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG ulDataLen
* @return jbyteArray jEncryptedData CK_BYTE_PTR pEncryptedData
* CK_ULONG_PTR pulEncryptedDataLen
*/
JNIEXPORT jint JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jbyteArray jIn, jint jInOfs, jint jInLen,
jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR inBufP;
CK_BYTE_PTR outBufP;
CK_ULONG ckEncryptedPartLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
if (inBufP == NULL) { return 0; }
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
// Make sure to release inBufP
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
return 0;
}
ckEncryptedPartLen = jOutLen;
rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle,
(CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckEncryptedPartLen);
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
ckAssertReturnValueOK(env, rv);
return ckEncryptedPartLen;
}
#endif
#ifdef P11_ENABLE_C_ENCRYPTUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_EncryptUpdate
* Signature: (J[BII[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG ulPartLen
* @return jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
* CK_ULONG_PTR pulEncryptedPartLen
*/
JNIEXPORT jint JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR inBufP;
CK_BYTE_PTR outBufP;
CK_ULONG ckEncryptedPartLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (directIn != 0) {
inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
} else {
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
if (inBufP == NULL) { return 0; }
}
if (directOut != 0) {
outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
// Make sure to release inBufP
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
return 0;
}
}
ckEncryptedPartLen = jOutLen;
//printf("EU: inBufP=%i, jInOfs=%i, jInLen=%i, outBufP=%i\n",
// inBufP, jInOfs, jInLen, outBufP);
rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle,
(CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckEncryptedPartLen);
//printf("EU: ckEncryptedPartLen=%i\n", ckEncryptedPartLen);
if (directIn == 0) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
if (directOut == 0) {
(*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
ckAssertReturnValueOK(env, rv);
return ckEncryptedPartLen;
}
#endif
#ifdef P11_ENABLE_C_ENCRYPTFINAL
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_EncryptFinal
* Signature: (J[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @return jbyteArray jLastEncryptedPart CK_BYTE_PTR pLastEncryptedDataPart
* CK_ULONG_PTR pulLastEncryptedDataPartLen
*/
JNIEXPORT jint JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR outBufP;
CK_ULONG ckLastEncryptedPartLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (directOut != 0) {
outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) { return 0; }
}
ckLastEncryptedPartLen = jOutLen;
//printf("EF: outBufP=%i\n", outBufP);
rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle,
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckLastEncryptedPartLen);
//printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen);
if (directOut == 0) {
(*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
ckAssertReturnValueOK(env, rv);
return ckLastEncryptedPartLen;
}
#endif
#ifdef P11_ENABLE_C_DECRYPTINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DecryptInit
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptInit
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jobject jMechanism, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckKeyHandle = jLongToCKULong(jKeyHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, &ckMechanism,
ckKeyHandle);
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_DECRYPT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Decrypt
* Signature: (J[BII[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jEncryptedData CK_BYTE_PTR pEncryptedData
* CK_ULONG ulEncryptedDataLen
* @return jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG_PTR pulDataLen
*/
JNIEXPORT jint JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jbyteArray jIn, jint jInOfs, jint jInLen,
jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR inBufP;
CK_BYTE_PTR outBufP;
CK_ULONG ckPartLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
if (inBufP == NULL) { return 0; }
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
// Make sure to release inBufP
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
return 0;
}
ckPartLen = jOutLen;
rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle,
(CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckPartLen);
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
ckAssertReturnValueOK(env, rv);
return ckPartLen;
}
#endif
#ifdef P11_ENABLE_C_DECRYPTUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DecryptUpdate
* Signature: (J[BII[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
* CK_ULONG ulEncryptedPartLen
* @return jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG_PTR pulPartLen
*/
JNIEXPORT jint JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR inBufP;
CK_BYTE_PTR outBufP;
CK_ULONG ckDecryptedPartLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (directIn != 0) {
inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
} else {
inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
if (inBufP == NULL) { return 0; }
}
if (directOut != 0) {
outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) {
// Make sure to release inBufP
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
return 0;
}
}
ckDecryptedPartLen = jOutLen;
rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle,
(CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckDecryptedPartLen);
if (directIn == 0) {
(*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
}
if (directOut == 0) {
(*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
ckAssertReturnValueOK(env, rv);
return ckDecryptedPartLen;
}
#endif
#ifdef P11_ENABLE_C_DECRYPTFINAL
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DecryptFinal
* Signature: (J[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @return jbyteArray jLastPart CK_BYTE_PTR pLastPart
* CK_ULONG_PTR pulLastPartLen
*/
JNIEXPORT jint JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal
(JNIEnv *env, jobject obj, jlong jSessionHandle,
jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR outBufP;
CK_ULONG ckLastPartLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (directOut != 0) {
outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
} else {
outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
if (outBufP == NULL) { return 0; }
}
ckLastPartLen = jOutLen;
rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle,
(CK_BYTE_PTR)(outBufP + jOutOfs),
&ckLastPartLen);
if (directOut == 0) {
(*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
}
ckAssertReturnValueOK(env, rv);
return ckLastPartLen;
}
#endif

View file

@ -0,0 +1,348 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "jlong.h"
#include "sun_security_pkcs11_wrapper_PKCS11.h"
#ifdef P11_ENABLE_C_DIGESTINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DigestInit
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestInit
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism);
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_DIGEST
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Digest
* Signature: (J[BII[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG ulDataLen
* @return jbyteArray jDigest CK_BYTE_PTR pDigest
* CK_ULONG_PTR pulDigestLen
*/
JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestSingle
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR bufP;
CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
CK_BYTE DIGESTBUF[MAX_DIGEST_LEN];
CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen);
CK_MECHANISM ckMechanism;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return 0; }
rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism);
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0; }
if (jInLen <= MAX_STACK_BUFFER_LEN) {
bufP = BUF;
} else {
/* always use single part op, even for large data */
bufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
if (bufP == NULL) {
throwOutOfMemoryError(env, 0);
return 0;
}
}
(*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
if (bufP != BUF) { free(bufP); }
return 0;
}
rv = (*ckpFunctions->C_Digest)(ckSessionHandle, bufP, jInLen, DIGESTBUF, &ckDigestLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
(*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)DIGESTBUF);
}
if (bufP != BUF) { free(bufP); }
return ckDigestLength;
}
#endif
#ifdef P11_ENABLE_C_DIGESTUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DigestUpdate
* Signature: (J[B)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG ulDataLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR bufP;
CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
jsize bufLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (directIn != 0) {
rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
ckAssertReturnValueOK(env, rv);
return;
}
if (jInLen <= MAX_STACK_BUFFER_LEN) {
bufLen = MAX_STACK_BUFFER_LEN;
bufP = BUF;
} else {
bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
if (bufP == NULL) {
throwOutOfMemoryError(env, 0);
return;
}
}
while (jInLen > 0) {
jsize chunkLen = min(bufLen, jInLen);
(*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
if (bufP != BUF) { free(bufP); }
return;
}
rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, bufP, chunkLen);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
if (bufP != BUF) { free(bufP); }
return;
}
jInOfs += chunkLen;
jInLen -= chunkLen;
}
if (bufP != BUF) {
free(bufP);
}
}
#endif
#ifdef P11_ENABLE_C_DIGESTKEY
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DigestKey
* Signature: (JJ)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestKey
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_ULONG ckKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckKeyHandle = jLongToCKULong(jKeyHandle);
rv = (*ckpFunctions->C_DigestKey)(ckSessionHandle, ckKeyHandle);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_DIGESTFINAL
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DigestFinal
* Signature: (J[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @return jbyteArray jDigest CK_BYTE_PTR pDigest
* CK_ULONG_PTR pulDigestLen
*/
JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestFinal
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE BUF[MAX_DIGEST_LEN];
CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen);
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
rv = (*ckpFunctions->C_DigestFinal)(ckSessionHandle, BUF, &ckDigestLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
(*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)BUF);
}
return ckDigestLength;
}
#endif
#ifdef P11_ENABLE_C_SEEDRANDOM
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SeedRandom
* Signature: (J[B)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jSeed CK_BYTE_PTR pSeed
* CK_ULONG ulSeedLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SeedRandom
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSeed)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpSeed = NULL_PTR;
CK_ULONG ckSeedLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jSeed, &ckpSeed, &ckSeedLength);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_SeedRandom)(ckSessionHandle, ckpSeed, ckSeedLength);
free(ckpSeed);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_GENERATERANDOM
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GenerateRandom
* Signature: (J[B)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jRandomData CK_BYTE_PTR pRandomData
* CK_ULONG ulRandomDataLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateRandom
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jRandomData)
{
CK_SESSION_HANDLE ckSessionHandle;
jbyte *jRandomBuffer;
jlong jRandomBufferLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jRandomBufferLength = (*env)->GetArrayLength(env, jRandomData);
jRandomBuffer = (*env)->GetByteArrayElements(env, jRandomData, NULL);
if (jRandomBuffer == NULL) { return; }
rv = (*ckpFunctions->C_GenerateRandom)(ckSessionHandle,
(CK_BYTE_PTR) jRandomBuffer,
jLongToCKULong(jRandomBufferLength));
/* copy back generated bytes */
(*env)->ReleaseByteArrayElements(env, jRandomData, jRandomBuffer, 0);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif

View file

@ -0,0 +1,315 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* ===========================================================================
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
#ifdef P11_ENABLE_C_DIGESTENCRYPTUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DigestEncryptUpdate
* Signature: (J[B)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG ulPartLen
* @return jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
* CK_ULONG_PTR pulEncryptedPartLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestEncryptUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
jbyteArray jEncryptedPart = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength);
if ((*env)->ExceptionCheck(env)) { return NULL; }
rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
free(ckpPart);
return NULL;
}
ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
if (ckpEncryptedPart == NULL) {
free(ckpPart);
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
}
free(ckpPart);
free(ckpEncryptedPart);
return jEncryptedPart ;
}
#endif
#ifdef P11_ENABLE_C_DECRYPTDIGESTUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DecryptDigestUpdate
* Signature: (J[B)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
* CK_ULONG ulEncryptedPartLen
* @return jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG_PTR pulPartLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptDigestUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
jbyteArray jPart = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength);
if ((*env)->ExceptionCheck(env)) { return NULL; }
rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
free(ckpEncryptedPart);
return NULL;
}
ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
if (ckpPart == NULL) {
free(ckpEncryptedPart);
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
}
free(ckpEncryptedPart);
free(ckpPart);
return jPart ;
}
#endif
#ifdef P11_ENABLE_C_SIGNENCRYPTUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SignEncryptUpdate
* Signature: (J[B)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG ulPartLen
* @return jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
* CK_ULONG_PTR pulEncryptedPartLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignEncryptUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
jbyteArray jEncryptedPart = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength);
if ((*env)->ExceptionCheck(env)) { return NULL; }
rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
free(ckpPart);
return NULL;
}
ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
if (ckpEncryptedPart == NULL) {
free(ckpPart);
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
}
free(ckpPart);
free(ckpEncryptedPart);
return jEncryptedPart ;
}
#endif
#ifdef P11_ENABLE_C_DECRYPTVERIFYUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DecryptVerifyUpdate
* Signature: (J[B)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart
* CK_ULONG ulEncryptedPartLen
* @return jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG_PTR pulPartLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptVerifyUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
jbyteArray jPart = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength);
if ((*env)->ExceptionCheck(env)) { return NULL; }
rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
free(ckpEncryptedPart);
return NULL;
}
ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
if (ckpPart == NULL) {
free(ckpEncryptedPart);
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
}
free(ckpEncryptedPart);
free(ckpPart);
return jPart ;
}
#endif
#ifdef P11_ENABLE_C_GETFUNCTIONSTATUS
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetFunctionStatus
* Signature: (J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetFunctionStatus
(JNIEnv *env, jobject obj, jlong jSessionHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
/* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
rv = (*ckpFunctions->C_GetFunctionStatus)(ckSessionHandle);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_CANCELFUNCTION
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_CancelFunction
* Signature: (J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CancelFunction
(JNIEnv *env, jobject obj, jlong jSessionHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
/* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
rv = (*ckpFunctions->C_CancelFunction)(ckSessionHandle);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif

View file

@ -0,0 +1,881 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
/* declare file private functions */
void prefetchFields(JNIEnv *env, jclass thisClass);
jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo);
jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo);
jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo);
jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo);
/* define variables */
jfieldID pNativeDataID;
jfieldID mech_mechanismID;
jfieldID mech_pParameterID;
jclass jByteArrayClass;
jclass jLongClass;
JavaVM* jvm = NULL;
jboolean debug = 0;
JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
jvm = vm;
return JNI_VERSION_1_4;
}
/* ************************************************************************** */
/* The native implementation of the methods of the PKCS11Implementation class */
/* ************************************************************************** */
/*
* This method is used to do static initialization. This method is static and
* synchronized. Summary: use this method like a static initialization block.
*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: initializeLibrary
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary
(JNIEnv *env, jclass thisClass, jboolean enableDebug)
{
#ifndef NO_CALLBACKS
if (notifyListLock == NULL) {
notifyListLock = createLockObject(env);
}
#endif
prefetchFields(env, thisClass);
debug = enableDebug;
}
jclass fetchClass(JNIEnv *env, const char *name) {
jclass tmpClass = (*env)->FindClass(env, name);
if (tmpClass == NULL) { return NULL; }
return (*env)->NewGlobalRef(env, tmpClass);
}
void prefetchFields(JNIEnv *env, jclass thisClass) {
jclass tmpClass;
/* PKCS11 */
pNativeDataID = (*env)->GetFieldID(env, thisClass, "pNativeData", "J");
if (pNativeDataID == NULL) { return; }
/* CK_MECHANISM */
tmpClass = (*env)->FindClass(env, CLASS_MECHANISM);
if (tmpClass == NULL) { return; }
mech_mechanismID = (*env)->GetFieldID(env, tmpClass, "mechanism", "J");
if (mech_mechanismID == NULL) { return; }
mech_pParameterID = (*env)->GetFieldID(env, tmpClass, "pParameter",
"Ljava/lang/Object;");
if (mech_pParameterID == NULL) { return; }
jByteArrayClass = fetchClass(env, "[B");
if (jByteArrayClass == NULL) { return; }
jLongClass = fetchClass(env, "java/lang/Long");
}
/* This method is designed to do a clean-up. It releases all global resources
* of this library. By now, this function is not called. Calling from
* JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload.
*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: finalizeLibrary
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary
(JNIEnv *env, jclass thisClass)
{
/* XXX
* remove all left lists and release the resources and the lock
* objects that synchroniz access to these lists.
*
removeAllModuleEntries(env);
if (moduleListHead == NULL) { * check, if we removed the last active module *
* remove also the moduleListLock, it is no longer used *
if (moduleListLock != NULL) {
destroyLockObject(env, moduleListLock);
moduleListLock = NULL;
}
#ifndef NO_CALLBACKS
* remove all left notify callback entries *
while (removeFirstNotifyEntry(env));
* remove also the notifyListLock, it is no longer used *
if (notifyListLock != NULL) {
destroyLockObject(env, notifyListLock);
notifyListLock = NULL;
}
if (jInitArgsObject != NULL) {
(*env)->DeleteGlobalRef(env, jInitArgsObject);
}
if (ckpGlobalInitArgs != NULL_PTR) {
free(ckpGlobalInitArgs);
}
#endif * NO_CALLBACKS *
}
*/
}
#ifdef P11_ENABLE_C_INITIALIZE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Initialize
* Signature: (Ljava/lang/Object;)V
* Parametermapping: *PKCS11*
* @param jobject jInitArgs CK_VOID_PTR pInitArgs
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize
(JNIEnv *env, jobject obj, jobject jInitArgs)
{
/*
* Initalize Cryptoki
*/
CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions;
TRACE0("DEBUG: initializing module... ");
ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) {
TRACE0("failed getting module entry");
return;
}
ckpInitArgs = (jInitArgs != NULL)
? makeCKInitArgsAdapter(env, jInitArgs)
: NULL_PTR;
rv = (*ckpFunctions->C_Initialize)(ckpInitArgs);
free(ckpInitArgs);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
TRACE0("FINISHED\n");
}
#endif
#ifdef P11_ENABLE_C_FINALIZE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Finalize
* Signature: (Ljava/lang/Object;)V
* Parametermapping: *PKCS11*
* @param jobject jReserved CK_VOID_PTR pReserved
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize
(JNIEnv *env, jobject obj, jobject jReserved)
{
/*
* Finalize Cryptoki
*/
CK_VOID_PTR ckpReserved;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckpReserved = jObjectToCKVoidPtr(jReserved);
rv = (*ckpFunctions->C_Finalize)(ckpReserved);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_GETINFO
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetInfo
* Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO;
* Parametermapping: *PKCS11*
* @return jobject jInfoObject CK_INFO_PTR pInfo
*/
JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo
(JNIEnv *env, jobject obj)
{
CK_INFO ckLibInfo;
jobject jInfoObject=NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions;
memset(&ckLibInfo, 0, sizeof(CK_INFO));
ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
}
return jInfoObject ;
}
/*
* converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
*
* @param env - used to call JNI funktions to create the new Java object
* @param ckpInfo - the pointer to the CK_INFO structure
* @return - the new Java CK_INFO object
*/
jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
{
jclass jInfoClass;
jmethodID jCtrId;
jobject jInfoObject;
jobject jCryptokiVer;
jcharArray jVendor;
jlong jFlags;
jcharArray jLibraryDesc;
jobject jLibraryVer;
/* load CK_INFO class */
jInfoClass = (*env)->FindClass(env, CLASS_INFO);
if (jInfoClass == NULL) { return NULL; };
/* load CK_INFO constructor */
jCtrId = (*env)->GetMethodID
(env, jInfoClass, "<init>",
"(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V");
if (jCtrId == NULL) { return NULL; }
/* prep all fields */
jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
if (jCryptokiVer == NULL) { return NULL; }
jVendor =
ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
if (jVendor == NULL) { return NULL; }
jFlags = ckULongToJLong(ckpInfo->flags);
jLibraryDesc =
ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32);
if (jLibraryDesc == NULL) { return NULL; }
jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
if (jLibraryVer == NULL) { return NULL; }
/* create new CK_INFO object */
jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer,
jVendor, jFlags, jLibraryDesc, jLibraryVer);
if (jInfoObject == NULL) { return NULL; }
/* free local references */
(*env)->DeleteLocalRef(env, jInfoClass);
(*env)->DeleteLocalRef(env, jCryptokiVer);
(*env)->DeleteLocalRef(env, jVendor);
(*env)->DeleteLocalRef(env, jLibraryDesc);
(*env)->DeleteLocalRef(env, jLibraryVer);
return jInfoObject ;
}
#endif
#ifdef P11_ENABLE_C_GETSLOTLIST
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetSlotList
* Signature: (Z)[J
* Parametermapping: *PKCS11*
* @param jboolean jTokenPresent CK_BBOOL tokenPresent
* @return jlongArray jSlotList CK_SLOT_ID_PTR pSlotList
* CK_ULONG_PTR pulCount
*/
JNIEXPORT jlongArray JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList
(JNIEnv *env, jobject obj, jboolean jTokenPresent)
{
CK_ULONG ckTokenNumber;
CK_SLOT_ID_PTR ckpSlotList;
CK_BBOOL ckTokenPresent;
jlongArray jSlotList = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR,
&ckTokenNumber);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
if (ckpSlotList == NULL) {
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList,
&ckTokenNumber);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
}
free(ckpSlotList);
return jSlotList ;
}
#endif
#ifdef P11_ENABLE_C_GETSLOTINFO
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetSlotInfo
* Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO;
* Parametermapping: *PKCS11*
* @param jlong jSlotID CK_SLOT_ID slotID
* @return jobject jSlotInfoObject CK_SLOT_INFO_PTR pInfo
*/
JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo
(JNIEnv *env, jobject obj, jlong jSlotID)
{
CK_SLOT_ID ckSlotID;
CK_SLOT_INFO ckSlotInfo;
jobject jSlotInfoObject=NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSlotID = jLongToCKULong(jSlotID);
rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
}
return jSlotInfoObject;
}
/*
* converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO
* Object.
*
* @param env - used to call JNI funktions to create the new Java object
* @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
* @return - the new Java CK_SLOT_INFO object
*/
jobject
ckSlotInfoPtrToJSlotInfo
(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
{
jclass jSlotInfoClass;
jmethodID jCtrId;
jobject jSlotInfoObject;
jcharArray jSlotDesc;
jcharArray jVendor;
jlong jFlags;
jobject jHardwareVer;
jobject jFirmwareVer;
/* load CK_SLOT_INFO class */
jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
if (jSlotInfoClass == NULL) { return NULL; };
/* load CK_SLOT_INFO constructor */
jCtrId = (*env)->GetMethodID
(env, jSlotInfoClass, "<init>",
"([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V");
if (jCtrId == NULL) { return NULL; }
/* prep all fields */
jSlotDesc =
ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64);
if (jSlotDesc == NULL) { return NULL; }
jVendor =
ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32);
if (jVendor == NULL) { return NULL; }
jFlags = ckULongToJLong(ckpSlotInfo->flags);
jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
if (jHardwareVer == NULL) { return NULL; }
jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
if (jFirmwareVer == NULL) { return NULL; }
/* create new CK_SLOT_INFO object */
jSlotInfoObject = (*env)->NewObject
(env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags,
jHardwareVer, jFirmwareVer);
if (jSlotInfoObject == NULL) { return NULL; }
/* free local references */
(*env)->DeleteLocalRef(env, jSlotInfoClass);
(*env)->DeleteLocalRef(env, jSlotDesc);
(*env)->DeleteLocalRef(env, jVendor);
(*env)->DeleteLocalRef(env, jHardwareVer);
(*env)->DeleteLocalRef(env, jFirmwareVer);
return jSlotInfoObject ;
}
#endif
#ifdef P11_ENABLE_C_GETTOKENINFO
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetTokenInfo
* Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO;
* Parametermapping: *PKCS11*
* @param jlong jSlotID CK_SLOT_ID slotID
* @return jobject jInfoTokenObject CK_TOKEN_INFO_PTR pInfo
*/
JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo
(JNIEnv *env, jobject obj, jlong jSlotID)
{
CK_SLOT_ID ckSlotID;
CK_TOKEN_INFO ckTokenInfo;
jobject jInfoTokenObject = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSlotID = jLongToCKULong(jSlotID);
rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
}
return jInfoTokenObject ;
}
/*
* converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO
* Object.
*
* @param env - used to call JNI funktions to create the new Java object
* @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
* @return - the new Java CK_TOKEN_INFO object
*/
jobject
ckTokenInfoPtrToJTokenInfo
(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
{
jclass jTokenInfoClass;
jmethodID jCtrId;
jobject jTokenInfoObject;
jcharArray jLabel;
jcharArray jVendor;
jcharArray jModel;
jcharArray jSerialNo;
jlong jFlags;
jlong jMaxSnCnt;
jlong jSnCnt;
jlong jMaxRwSnCnt;
jlong jRwSnCnt;
jlong jMaxPinLen;
jlong jMinPinLen;
jlong jTotalPubMem;
jlong jFreePubMem;
jlong jTotalPrivMem;
jlong jFreePrivMem;
jobject jHardwareVer;
jobject jFirmwareVer;
jcharArray jUtcTime;
/* load CK_TOKEN_INFO class */
jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
if (jTokenInfoClass == NULL) { return NULL; };
/* load CK_TOKEN_INFO constructor */
jCtrId = (*env)->GetMethodID
(env, jTokenInfoClass, "<init>",
"([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V");
if (jCtrId == NULL) { return NULL; };
/* prep all fields */
jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32);
if (jLabel == NULL) { return NULL; };
jVendor =
ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32);
if (jVendor == NULL) { return NULL; };
jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16);
if (jModel == NULL) { return NULL; };
jSerialNo =
ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16);
if (jSerialNo == NULL) { return NULL; };
jFlags = ckULongToJLong(ckpTokenInfo->flags);
jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount);
jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount);
jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount);
jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount);
jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen);
jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen);
jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory);
jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory);
jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory);
jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory);
jHardwareVer =
ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
if (jHardwareVer == NULL) { return NULL; }
jFirmwareVer =
ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
if (jFirmwareVer == NULL) { return NULL; }
jUtcTime =
ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16);
if (jUtcTime == NULL) { return NULL; }
/* create new CK_TOKEN_INFO object */
jTokenInfoObject =
(*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel,
jSerialNo, jFlags,
jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt,
jMaxPinLen, jMinPinLen,
jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem,
jHardwareVer, jFirmwareVer, jUtcTime);
if (jTokenInfoObject == NULL) { return NULL; }
/* free local references */
(*env)->DeleteLocalRef(env, jTokenInfoClass);
(*env)->DeleteLocalRef(env, jLabel);
(*env)->DeleteLocalRef(env, jVendor);
(*env)->DeleteLocalRef(env, jModel);
(*env)->DeleteLocalRef(env, jSerialNo);
(*env)->DeleteLocalRef(env, jHardwareVer);
(*env)->DeleteLocalRef(env, jFirmwareVer);
return jTokenInfoObject ;
}
#endif
#ifdef P11_ENABLE_C_WAITFORSLOTEVENT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_WaitForSlotEvent
* Signature: (JLjava/lang/Object;)J
* Parametermapping: *PKCS11*
* @param jlong jFlags CK_FLAGS flags
* @param jobject jReserved CK_VOID_PTR pReserved
* @return jlong jSlotID CK_SLOT_ID_PTR pSlot
*/
JNIEXPORT jlong JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent
(JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
{
CK_FLAGS ckFlags;
CK_SLOT_ID ckSlotID;
jlong jSlotID = 0L;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckFlags = jLongToCKULong(jFlags);
rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jSlotID = ckULongToJLong(ckSlotID);
}
return jSlotID ;
}
#endif
#ifdef P11_ENABLE_C_GETMECHANISMLIST
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetMechanismList
* Signature: (J)[J
* Parametermapping: *PKCS11*
* @param jlong jSlotID CK_SLOT_ID slotID
* @return jlongArray jMechanismList CK_MECHANISM_TYPE_PTR pMechanismList
* CK_ULONG_PTR pulCount
*/
JNIEXPORT jlongArray JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList
(JNIEnv *env, jobject obj, jlong jSlotID)
{
CK_SLOT_ID ckSlotID;
CK_ULONG ckMechanismNumber;
CK_MECHANISM_TYPE_PTR ckpMechanismList;
jlongArray jMechanismList = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSlotID = jLongToCKULong(jSlotID);
rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR,
&ckMechanismNumber);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
ckpMechanismList = (CK_MECHANISM_TYPE_PTR)
malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
if (ckpMechanismList == NULL) {
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList,
&ckMechanismNumber);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList,
ckMechanismNumber);
}
free(ckpMechanismList);
return jMechanismList ;
}
#endif
#ifdef P11_ENABLE_C_GETMECHANISMINFO
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetMechanismInfo
* Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO;
* Parametermapping: *PKCS11*
* @param jlong jSlotID CK_SLOT_ID slotID
* @param jlong jType CK_MECHANISM_TYPE type
* @return jobject jMechanismInfo CK_MECHANISM_INFO_PTR pInfo
*/
JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo
(JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
{
CK_SLOT_ID ckSlotID;
CK_MECHANISM_TYPE ckMechanismType;
CK_MECHANISM_INFO ckMechanismInfo;
jobject jMechanismInfo = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSlotID = jLongToCKULong(jSlotID);
ckMechanismType = jLongToCKULong(jType);
rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType,
&ckMechanismInfo);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
}
return jMechanismInfo ;
}
/*
* converts a pointer to a CK_MECHANISM_INFO structure into a Java
* CK_MECHANISM_INFO Object.
*
* @param env - used to call JNI funktions to create the new Java object
* @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
* @return - the new Java CK_MECHANISM_INFO object
*/
jobject
ckMechanismInfoPtrToJMechanismInfo
(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
{
jclass jMechanismInfoClass;
jmethodID jCtrId;
jobject jMechanismInfoObject;
jlong jMinKeySize;
jlong jMaxKeySize;
jlong jFlags;
/* load CK_MECHANISM_INFO class */
jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
if (jMechanismInfoClass == NULL) { return NULL; };
/* load CK_MECHANISM_INFO constructor */
jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "<init>", "(JJJ)V");
if (jCtrId == NULL) { return NULL; };
/* prep all fields */
jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize);
jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize);
jFlags = ckULongToJLong(ckpMechanismInfo->flags);
/* create new CK_MECHANISM_INFO object */
jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId,
jMinKeySize, jMaxKeySize, jFlags);
if (jMechanismInfoObject == NULL) { return NULL; };
/* free local references */
(*env)->DeleteLocalRef(env, jMechanismInfoClass);
return jMechanismInfoObject ;
}
#endif
#ifdef P11_ENABLE_C_INITTOKEN
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_InitToken
* Signature: (J[C[C)V
* Parametermapping: *PKCS11*
* @param jlong jSlotID CK_SLOT_ID slotID
* @param jcharArray jPin CK_CHAR_PTR pPin
* CK_ULONG ulPinLen
* @param jcharArray jLabel CK_UTF8CHAR_PTR pLabel
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken
(JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
{
CK_SLOT_ID ckSlotID;
CK_CHAR_PTR ckpPin = NULL_PTR;
CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
CK_ULONG ckPinLength;
CK_ULONG ckLabelLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSlotID = jLongToCKULong(jSlotID);
jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
if ((*env)->ExceptionCheck(env)) { return; }
/* ckLabelLength <= 32 !!! */
jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength);
if ((*env)->ExceptionCheck(env)) {
free(ckpPin);
return;
}
rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
TRACE1("InitToken return code: %d", rv);
free(ckpPin);
free(ckpLabel);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_INITPIN
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_InitPIN
* Signature: (J[C)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE
* @param jcharArray jPin CK_CHAR_PTR pPin
* CK_ULONG ulPinLen
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN
(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_CHAR_PTR ckpPin = NULL_PTR;
CK_ULONG ckPinLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
free(ckpPin);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_SETPIN
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SetPIN
* Signature: (J[C[C)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jcharArray jOldPin CK_CHAR_PTR pOldPin
* CK_ULONG ulOldLen
* @param jcharArray jNewPin CK_CHAR_PTR pNewPin
* CK_ULONG ulNewLen
*/
JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN
(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin,
jcharArray jNewPin)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_CHAR_PTR ckpOldPin = NULL_PTR;
CK_CHAR_PTR ckpNewPin = NULL_PTR;
CK_ULONG ckOldPinLength;
CK_ULONG ckNewPinLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength);
if ((*env)->ExceptionCheck(env)) { return; }
jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength);
if ((*env)->ExceptionCheck(env)) {
free(ckpOldPin);
return;
}
rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength,
ckpNewPin, ckNewPinLength);
free(ckpOldPin);
free(ckpNewPin);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif

View file

@ -0,0 +1,773 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
#ifdef P11_ENABLE_C_GENERATEKEY
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GenerateKey
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
* @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey
*/
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
CK_OBJECT_HANDLE ckKeyHandle = 0;
jlong jKeyHandle = 0L;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return 0L ; }
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
return 0L;
}
rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, &ckMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jKeyHandle = ckULongToJLong(ckKeyHandle);
/* cheack, if we must give a initialization vector back to Java */
switch (ckMechanism.mechanism) {
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_PBE_MD5_CAST_CBC:
case CKM_PBE_MD5_CAST3_CBC:
case CKM_PBE_MD5_CAST128_CBC:
/* case CKM_PBE_MD5_CAST5_CBC: the same as CKM_PBE_MD5_CAST128_CBC */
case CKM_PBE_SHA1_CAST128_CBC:
/* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */
/* we must copy back the initialization vector to the jMechanism object */
copyBackPBEInitializationVector(env, &ckMechanism, jMechanism);
break;
}
}
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
return jKeyHandle ;
}
#endif
#ifdef P11_ENABLE_C_GENERATEKEYPAIR
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GenerateKeyPair
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @param jobjectArray jPublicKeyTemplate CK_ATTRIBUTE_PTR pPublicKeyTemplate
* CK_ULONG ulPublicKeyAttributeCount
* @param jobjectArray jPrivateKeyTemplate CK_ATTRIBUTE_PTR pPrivateKeyTemplate
* CK_ULONG ulPrivateKeyAttributeCount
* @return jlongArray jKeyHandles CK_OBJECT_HANDLE_PTR phPublicKey
* CK_OBJECT_HANDLE_PTR phPublicKey
*/
JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKeyPair
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism,
jobjectArray jPublicKeyTemplate, jobjectArray jPrivateKeyTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_ATTRIBUTE_PTR ckpPublicKeyAttributes = NULL_PTR;
CK_ATTRIBUTE_PTR ckpPrivateKeyAttributes = NULL_PTR;
CK_ULONG ckPublicKeyAttributesLength;
CK_ULONG ckPrivateKeyAttributesLength;
CK_OBJECT_HANDLE_PTR ckpPublicKeyHandle; /* pointer to Public Key */
CK_OBJECT_HANDLE_PTR ckpPrivateKeyHandle; /* pointer to Private Key */
CK_OBJECT_HANDLE_PTR ckpKeyHandles; /* pointer to array with Public and Private Key */
jlongArray jKeyHandles = NULL;
CK_RV rv;
int attempts;
const int MAX_ATTEMPTS = 3;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return NULL; }
ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) malloc(2 * sizeof(CK_OBJECT_HANDLE));
if (ckpKeyHandles == NULL) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
throwOutOfMemoryError(env, 0);
return NULL;
}
ckpPublicKeyHandle = ckpKeyHandles; /* first element of array is Public Key */
ckpPrivateKeyHandle = (ckpKeyHandles + 1); /* second element of array is Private Key */
jAttributeArrayToCKAttributeArray(env, jPublicKeyTemplate, &ckpPublicKeyAttributes, &ckPublicKeyAttributesLength);
if ((*env)->ExceptionCheck(env)) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
free(ckpKeyHandles);
return NULL;
}
jAttributeArrayToCKAttributeArray(env, jPrivateKeyTemplate, &ckpPrivateKeyAttributes, &ckPrivateKeyAttributesLength);
if ((*env)->ExceptionCheck(env)) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
free(ckpKeyHandles);
freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
return NULL;
}
/*
* Workaround for NSS bug 1012786:
*
* Key generation may fail with CKR_FUNCTION_FAILED error
* if there is insufficient entropy to generate a random key.
*
* PKCS11 spec says the following about CKR_FUNCTION_FAILED error
* (see section 11.1.1):
*
* ... In any event, although the function call failed, the situation
* is not necessarily totally hopeless, as it is likely to be
* when CKR_GENERAL_ERROR is returned. Depending on what the root cause of
* the error actually was, it is possible that an attempt
* to make the exact same function call again would succeed.
*
* Call C_GenerateKeyPair() several times if CKR_FUNCTION_FAILED occurs.
*/
for (attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {
rv = (*ckpFunctions->C_GenerateKeyPair)(ckSessionHandle, &ckMechanism,
ckpPublicKeyAttributes, ckPublicKeyAttributesLength,
ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength,
ckpPublicKeyHandle, ckpPrivateKeyHandle);
if (rv == CKR_FUNCTION_FAILED) {
printDebug("C_1GenerateKeyPair(): C_GenerateKeyPair() failed \
with CKR_FUNCTION_FAILED error, try again\n");
} else {
break;
}
}
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jKeyHandles = ckULongArrayToJLongArray(env, ckpKeyHandles, 2);
}
if(ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
free(ckpKeyHandles);
freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
freeCKAttributeArray(ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength);
return jKeyHandles ;
}
#endif
#ifdef P11_ENABLE_C_WRAPKEY
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_WrapKey
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;JJ)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @param jlong jWrappingKeyHandle CK_OBJECT_HANDLE hWrappingKey
* @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
* @return jbyteArray jWrappedKey CK_BYTE_PTR pWrappedKey
* CK_ULONG_PTR pulWrappedKeyLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jWrappingKeyHandle, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckWrappingKeyHandle;
CK_OBJECT_HANDLE ckKeyHandle;
jbyteArray jWrappedKey = NULL;
CK_RV rv;
CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
CK_BYTE_PTR ckpWrappedKey = BUF;
CK_ULONG ckWrappedKeyLength = MAX_STACK_BUFFER_LEN;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return NULL; }
ckWrappingKeyHandle = jLongToCKULong(jWrappingKeyHandle);
ckKeyHandle = jLongToCKULong(jKeyHandle);
rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
if (rv == CKR_BUFFER_TOO_SMALL) {
ckpWrappedKey = (CK_BYTE_PTR) malloc(ckWrappedKeyLength);
if (ckpWrappedKey == NULL) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
}
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jWrappedKey = ckByteArrayToJByteArray(env, ckpWrappedKey, ckWrappedKeyLength);
}
if (ckpWrappedKey != BUF) { free(ckpWrappedKey); }
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
return jWrappedKey ;
}
#endif
#ifdef P11_ENABLE_C_UNWRAPKEY
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_UnwrapKey
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[B[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @param jlong jUnwrappingKeyHandle CK_OBJECT_HANDLE hUnwrappingKey
* @param jbyteArray jWrappedKey CK_BYTE_PTR pWrappedKey
* CK_ULONG_PTR pulWrappedKeyLen
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
* @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey
*/
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle,
jbyteArray jWrappedKey, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckUnwrappingKeyHandle;
CK_BYTE_PTR ckpWrappedKey = NULL_PTR;
CK_ULONG ckWrappedKeyLength;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
CK_OBJECT_HANDLE ckKeyHandle = 0;
jlong jKeyHandle = 0L;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return 0L; }
ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle);
jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength);
if ((*env)->ExceptionCheck(env)) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
return 0L;
}
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
free(ckpWrappedKey);
return 0L;
}
rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, ckUnwrappingKeyHandle,
ckpWrappedKey, ckWrappedKeyLength,
ckpAttributes, ckAttributesLength, &ckKeyHandle);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jKeyHandle = ckLongToJLong(ckKeyHandle);
#if 0
/* cheack, if we must give a initialization vector back to Java */
if (ckMechanism.mechanism == CKM_KEY_WRAP_SET_OAEP) {
/* we must copy back the unwrapped key info to the jMechanism object */
copyBackSetUnwrappedKey(env, &ckMechanism, jMechanism);
}
#endif
}
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
free(ckpWrappedKey);
return jKeyHandle ;
}
#endif
#ifdef P11_ENABLE_C_DERIVEKEY
void freeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) {
CK_SSL3_MASTER_KEY_DERIVE_PARAMS *params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
if (params == NULL) {
return;
}
if (params->RandomInfo.pClientRandom != NULL) {
free(params->RandomInfo.pClientRandom);
}
if (params->RandomInfo.pServerRandom != NULL) {
free(params->RandomInfo.pServerRandom);
}
if (params->pVersion != NULL) {
free(params->pVersion);
}
}
void freeEcdh1DeriveParams(CK_MECHANISM_PTR ckMechanism) {
CK_ECDH1_DERIVE_PARAMS *params = (CK_ECDH1_DERIVE_PARAMS *) ckMechanism->pParameter;
if (params == NULL) {
return;
}
if (params->pSharedData != NULL) {
free(params->pSharedData);
}
if (params->pPublicData != NULL) {
free(params->pPublicData);
}
}
/*
* Copy back the PRF output to Java.
*/
void copyBackTLSPrfParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
{
jclass jMechanismClass, jTLSPrfParamsClass;
CK_TLS_PRF_PARAMS *ckTLSPrfParams;
jobject jTLSPrfParams;
jfieldID fieldID;
CK_MECHANISM_TYPE ckMechanismType;
jlong jMechanismType;
CK_BYTE_PTR output;
jobject jOutput;
jint jLength;
jbyte* jBytes;
int i;
/* get mechanism */
jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
if (jMechanismClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
if (fieldID == NULL) { return; }
jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
ckMechanismType = jLongToCKULong(jMechanismType);
if (ckMechanismType != ckMechanism->mechanism) {
/* we do not have maching types, this should not occur */
return;
}
/* get the native CK_TLS_PRF_PARAMS */
ckTLSPrfParams = (CK_TLS_PRF_PARAMS *) ckMechanism->pParameter;
if (ckTLSPrfParams != NULL_PTR) {
/* get the Java CK_TLS_PRF_PARAMS object (pParameter) */
fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
if (fieldID == NULL) { return; }
jTLSPrfParams = (*env)->GetObjectField(env, jMechanism, fieldID);
/* copy back the client IV */
jTLSPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
if (jTLSPrfParamsClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jTLSPrfParamsClass, "pOutput", "[B");
if (fieldID == NULL) { return; }
jOutput = (*env)->GetObjectField(env, jTLSPrfParams, fieldID);
output = ckTLSPrfParams->pOutput;
// Note: we assume that the token returned exactly as many bytes as we
// requested. Anything else would not make sense.
if (jOutput != NULL) {
jLength = (*env)->GetArrayLength(env, jOutput);
jBytes = (*env)->GetByteArrayElements(env, jOutput, NULL);
if (jBytes == NULL) { return; }
/* copy the bytes to the Java buffer */
for (i=0; i < jLength; i++) {
jBytes[i] = ckByteToJByte(output[i]);
}
/* copy back the Java buffer to the object */
(*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0);
}
// free malloc'd data
free(ckTLSPrfParams->pSeed);
free(ckTLSPrfParams->pLabel);
free(ckTLSPrfParams->pulOutputLen);
free(ckTLSPrfParams->pOutput);
}
}
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DeriveKey
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @param jlong jBaseKeyHandle CK_OBJECT_HANDLE hBaseKey
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
* @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey
*/
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckBaseKeyHandle;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
CK_OBJECT_HANDLE ckKeyHandle = 0;
jlong jKeyHandle = 0L;
CK_RV rv;
CK_OBJECT_HANDLE_PTR phKey = &ckKeyHandle;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return 0L; }
ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle);
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) {
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
return 0L;
}
switch (ckMechanism.mechanism) {
case CKM_SSL3_KEY_AND_MAC_DERIVE:
case CKM_TLS_KEY_AND_MAC_DERIVE:
case CKM_TLS_PRF:
// these mechanism do not return a key handle via phKey
// set to NULL in case pedantic implementations check for it
phKey = NULL;
break;
default:
// empty
break;
}
rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, &ckMechanism, ckBaseKeyHandle,
ckpAttributes, ckAttributesLength, phKey);
jKeyHandle = ckLongToJLong(ckKeyHandle);
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
switch (ckMechanism.mechanism) {
case CKM_SSL3_MASTER_KEY_DERIVE:
case CKM_TLS_MASTER_KEY_DERIVE:
/* we must copy back the client version */
copyBackClientVersion(env, &ckMechanism, jMechanism);
freeMasterKeyDeriveParams(&ckMechanism);
break;
case CKM_SSL3_MASTER_KEY_DERIVE_DH:
case CKM_TLS_MASTER_KEY_DERIVE_DH:
freeMasterKeyDeriveParams(&ckMechanism);
break;
case CKM_SSL3_KEY_AND_MAC_DERIVE:
case CKM_TLS_KEY_AND_MAC_DERIVE:
/* we must copy back the unwrapped key info to the jMechanism object */
copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism);
break;
case CKM_TLS_PRF:
copyBackTLSPrfParams(env, &ckMechanism, jMechanism);
break;
case CKM_ECDH1_DERIVE:
freeEcdh1DeriveParams(&ckMechanism);
break;
default:
// empty
break;
}
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
return jKeyHandle ;
}
/*
* Copy back the client version information from the native
* structure to the Java object. This is only used for the
* CKM_SSL3_MASTER_KEY_DERIVE mechanism when used for deriving a key.
*
*/
void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
{
jclass jMechanismClass, jSSL3MasterKeyDeriveParamsClass, jVersionClass;
CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams;
CK_VERSION *ckVersion;
jfieldID fieldID;
CK_MECHANISM_TYPE ckMechanismType;
jlong jMechanismType;
jobject jSSL3MasterKeyDeriveParams;
jobject jVersion;
/* get mechanism */
jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
if (jMechanismClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
if (fieldID == NULL) { return; }
jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
ckMechanismType = jLongToCKULong(jMechanismType);
if (ckMechanismType != ckMechanism->mechanism) {
/* we do not have maching types, this should not occur */
return;
}
/* get the native CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
ckSSL3MasterKeyDeriveParams = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
if (ckSSL3MasterKeyDeriveParams != NULL_PTR) {
/* get the native CK_VERSION */
ckVersion = ckSSL3MasterKeyDeriveParams->pVersion;
if (ckVersion != NULL_PTR) {
/* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */
fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
if (fieldID == NULL) { return; }
jSSL3MasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID);
/* get the Java CK_VERSION */
jSSL3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
if (jSSL3MasterKeyDeriveParamsClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jSSL3MasterKeyDeriveParamsClass, "pVersion", "L"CLASS_VERSION";");
if (fieldID == NULL) { return; }
jVersion = (*env)->GetObjectField(env, jSSL3MasterKeyDeriveParams, fieldID);
/* now copy back the version from the native structure to the Java structure */
/* copy back the major version */
jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
if (jVersionClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
if (fieldID == NULL) { return; }
(*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->major));
/* copy back the minor version */
fieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
if (fieldID == NULL) { return; }
(*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor));
}
}
}
/*
* Copy back the derived keys and initialization vectors from the native
* structure to the Java object. This is only used for the
* CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key.
*
*/
void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
{
jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass;
CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam;
CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut;
jfieldID fieldID;
CK_MECHANISM_TYPE ckMechanismType;
jlong jMechanismType;
CK_BYTE_PTR iv;
jobject jSSL3KeyMatParam;
jobject jSSL3KeyMatOut;
jobject jIV;
jint jLength;
jbyte* jBytes;
int i;
/* get mechanism */
jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
if (jMechanismClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
if (fieldID == NULL) { return; }
jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
ckMechanismType = jLongToCKULong(jMechanismType);
if (ckMechanismType != ckMechanism->mechanism) {
/* we do not have maching types, this should not occur */
return;
}
/* get the native CK_SSL3_KEY_MAT_PARAMS */
ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter;
if (ckSSL3KeyMatParam != NULL_PTR) {
// free malloc'd data
if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) {
free(ckSSL3KeyMatParam->RandomInfo.pClientRandom);
}
if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) {
free(ckSSL3KeyMatParam->RandomInfo.pServerRandom);
}
/* get the native CK_SSL3_KEY_MAT_OUT */
ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial;
if (ckSSL3KeyMatOut != NULL_PTR) {
/* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */
fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
if (fieldID == NULL) { return; }
jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID);
/* get the Java CK_SSL3_KEY_MAT_OUT */
jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
if (jSSL3KeyMatParamsClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";");
if (fieldID == NULL) { return; }
jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID);
/* now copy back all the key handles and the initialization vectors */
/* copy back client MAC secret handle */
jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
if (jSSL3KeyMatOutClass == NULL) { return; }
fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J");
if (fieldID == NULL) { return; }
(*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret));
/* copy back server MAC secret handle */
fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J");
if (fieldID == NULL) { return; }
(*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret));
/* copy back client secret key handle */
fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J");
if (fieldID == NULL) { return; }
(*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey));
/* copy back server secret key handle */
fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J");
if (fieldID == NULL) { return; }
(*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey));
/* copy back the client IV */
fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B");
if (fieldID == NULL) { return; }
jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
iv = ckSSL3KeyMatOut->pIVClient;
if (jIV != NULL) {
jLength = (*env)->GetArrayLength(env, jIV);
jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
if (jBytes == NULL) { return; }
/* copy the bytes to the Java buffer */
for (i=0; i < jLength; i++) {
jBytes[i] = ckByteToJByte(iv[i]);
}
/* copy back the Java buffer to the object */
(*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
}
// free malloc'd data
free(ckSSL3KeyMatOut->pIVClient);
/* copy back the server IV */
fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
if (fieldID == NULL) { return; }
jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
iv = ckSSL3KeyMatOut->pIVServer;
if (jIV != NULL) {
jLength = (*env)->GetArrayLength(env, jIV);
jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
if (jBytes == NULL) { return; }
/* copy the bytes to the Java buffer */
for (i=0; i < jLength; i++) {
jBytes[i] = ckByteToJByte(iv[i]);
}
/* copy back the Java buffer to the object */
(*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
}
// free malloc'd data
free(ckSSL3KeyMatOut->pIVServer);
free(ckSSL3KeyMatOut);
}
}
}
#endif

View file

@ -0,0 +1,552 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
/* The initArgs that enable the application to do custom mutex-handling */
#ifndef NO_CALLBACKS
jobject jInitArgsObject;
CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs;
#endif /* NO_CALLBACKS */
/* ************************************************************************** */
/* Now come the functions for mutex handling and notification callbacks */
/* ************************************************************************** */
/*
* converts the InitArgs object to a CK_C_INITIALIZE_ARGS structure and sets the functions
* that will call the right Java mutex functions
*
* @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
* @param pInitArgs - the InitArgs object with the Java mutex functions to call
* @return - the pointer to the CK_C_INITIALIZE_ARGS structure with the functions that will call
* the corresponding Java functions
*/
CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject jInitArgs)
{
CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
jclass jInitArgsClass;
jfieldID fieldID;
jlong jFlags;
jobject jReserved;
CK_ULONG ckReservedLength;
#ifndef NO_CALLBACKS
jobject jMutexHandler;
#endif /* NO_CALLBACKS */
if(jInitArgs == NULL) {
return NULL_PTR;
}
/* convert the Java InitArgs object to a pointer to a CK_C_INITIALIZE_ARGS structure */
ckpInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
if (ckpInitArgs == NULL) {
throwOutOfMemoryError(env, 0);
return NULL_PTR;
}
ckpInitArgs->flags = (CK_FLAGS)0;
ckpInitArgs->pReserved = (CK_VOID_PTR)NULL;
/* Set the mutex functions that will call the Java mutex functions, but
* only set it, if the field is not null.
*/
jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
if (jInitArgsClass == NULL) {
free(ckpInitArgs);
return NULL;
}
#ifdef NO_CALLBACKS
ckpInitArgs->CreateMutex = NULL_PTR;
ckpInitArgs->DestroyMutex = NULL_PTR;
ckpInitArgs->LockMutex = NULL_PTR;
ckpInitArgs->UnlockMutex = NULL_PTR;
#else
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;");
if (fieldID == NULL) {
free(ckpInitArgs);
return NULL;
}
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->CreateMutex = (jMutexHandler != NULL) ? &callJCreateMutex : NULL_PTR;
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;");
if (fieldID == NULL) {
free(ckpInitArgs);
return NULL;
}
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->DestroyMutex = (jMutexHandler != NULL) ? &callJDestroyMutex : NULL_PTR;
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;");
if (fieldID == NULL) {
free(ckpInitArgs);
return NULL;
}
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->LockMutex = (jMutexHandler != NULL) ? &callJLockMutex : NULL_PTR;
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;");
if (fieldID == NULL) {
free(ckpInitArgs);
return NULL;
}
jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
ckpInitArgs->UnlockMutex = (jMutexHandler != NULL) ? &callJUnlockMutex : NULL_PTR;
if ((ckpInitArgs->CreateMutex != NULL_PTR)
|| (ckpInitArgs->DestroyMutex != NULL_PTR)
|| (ckpInitArgs->LockMutex != NULL_PTR)
|| (ckpInitArgs->UnlockMutex != NULL_PTR)) {
/* we only need to keep a global copy, if we need callbacks */
/* set the global object jInitArgs so that the right Java mutex functions will be called */
jInitArgsObject = (*env)->NewGlobalRef(env, jInitArgs);
ckpGlobalInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
if (ckpGlobalInitArgs == NULL) {
free(ckpInitArgs);
throwOutOfMemoryError(env, 0);
return NULL_PTR;
}
memcpy(ckpGlobalInitArgs, ckpInitArgs, sizeof(CK_C_INITIALIZE_ARGS));
}
#endif /* NO_CALLBACKS */
/* convert and set the flags field */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "flags", "J");
if (fieldID == NULL) {
free(ckpInitArgs);
return NULL;
}
jFlags = (*env)->GetLongField(env, jInitArgs, fieldID);
ckpInitArgs->flags = jLongToCKULong(jFlags);
/* pReserved should be NULL_PTR in this version */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "pReserved", "Ljava/lang/Object;");
if (fieldID == NULL) {
free(ckpInitArgs);
return NULL;
}
jReserved = (*env)->GetObjectField(env, jInitArgs, fieldID);
/* we try to convert the reserved parameter also */
jObjectToPrimitiveCKObjectPtrPtr(env, jReserved, &(ckpInitArgs->pReserved), &ckReservedLength);
return ckpInitArgs ;
}
#ifndef NO_CALLBACKS
/*
* is the function that gets called by PKCS#11 to create a mutex and calls the Java
* CreateMutex function
*
* @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
* @param ppMutex - the new created mutex
* @return - should return CKR_OK if the mutex creation was ok
*/
CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex)
{
extern JavaVM *jvm;
JNIEnv *env;
jint returnValue;
jthrowable pkcs11Exception;
jclass pkcs11ExceptionClass;
jlong errorCode;
CK_RV rv = CKR_OK;
int wasAttached = 1;
jclass jCreateMutexClass;
jclass jInitArgsClass;
jmethodID methodID;
jfieldID fieldID;
jobject jCreateMutex;
jobject jMutex;
/* Get the currently running Java VM */
if (jvm == NULL) { return rv ;} /* there is no VM running */
/* Determine, if current thread is already attached */
returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
if (returnValue == JNI_EDETACHED) {
/* thread detached, so attach it */
wasAttached = 0;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else if (returnValue == JNI_EVERSION) {
/* this version of JNI is not supported, so just try to attach */
/* we assume it was attached to ensure that this thread is not detached
* afterwards even though it should not
*/
wasAttached = 1;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else {
/* attached */
wasAttached = 1;
}
jCreateMutexClass = (*env)->FindClass(env, CLASS_CREATEMUTEX);
if (jCreateMutexClass == NULL) { return rv; }
jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
if (jInitArgsClass == NULL) { return rv; }
/* get the CreateMutex object out of the jInitArgs object */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;");
if (fieldID == NULL) { return rv; }
jCreateMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
assert(jCreateMutex != 0);
/* call the CK_CREATEMUTEX function of the CreateMutex object */
/* and get the new Java mutex object */
methodID = (*env)->GetMethodID(env, jCreateMutexClass, "CK_CREATEMUTEX", "()Ljava/lang/Object;");
if (methodID == NULL) { return rv; }
jMutex = (*env)->CallObjectMethod(env, jCreateMutex, methodID);
/* set a global reference on the Java mutex */
jMutex = (*env)->NewGlobalRef(env, jMutex);
/* convert the Java mutex to a CK mutex */
*ppMutex = jObjectToCKVoidPtr(jMutex);
/* check, if callback threw an exception */
pkcs11Exception = (*env)->ExceptionOccurred(env);
if (pkcs11Exception != NULL) {
/* TBD: clear the pending exception with ExceptionClear? */
/* The was an exception thrown, now we get the error-code from it */
pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
if (pkcs11ExceptionClass == NULL) { return rv; }
methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
if (methodID == NULL) { return rv; }
errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
rv = jLongToCKULong(errorCode);
}
/* if we attached this thread to the VM just for callback, we detach it now */
if (wasAttached) {
returnValue = (*jvm)->DetachCurrentThread(jvm);
}
return rv ;
}
/*
* is the function that gets called by PKCS#11 to destroy a mutex and calls the Java
* DestroyMutex function
*
* @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
* @param pMutex - the mutex to destroy
* @return - should return CKR_OK if the mutex was destroyed
*/
CK_RV callJDestroyMutex(CK_VOID_PTR pMutex)
{
extern JavaVM *jvm;
JNIEnv *env;
jint returnValue;
jthrowable pkcs11Exception;
jclass pkcs11ExceptionClass;
jlong errorCode;
CK_RV rv = CKR_OK;
int wasAttached = 1;
jclass jDestroyMutexClass;
jclass jInitArgsClass;
jmethodID methodID;
jfieldID fieldID;
jobject jDestroyMutex;
jobject jMutex;
/* Get the currently running Java VM */
if (jvm == NULL) { return rv ; } /* there is no VM running */
/* Determine, if current thread is already attached */
returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
if (returnValue == JNI_EDETACHED) {
/* thread detached, so attach it */
wasAttached = 0;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else if (returnValue == JNI_EVERSION) {
/* this version of JNI is not supported, so just try to attach */
/* we assume it was attached to ensure that this thread is not detached
* afterwards even though it should not
*/
wasAttached = 1;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else {
/* attached */
wasAttached = 1;
}
jDestroyMutexClass = (*env)->FindClass(env, CLASS_DESTROYMUTEX);
if (jDestroyMutexClass == NULL) { return rv; }
jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
if (jInitArgsClass == NULL) { return rv; }
/* convert the CK mutex to a Java mutex */
jMutex = ckVoidPtrToJObject(pMutex);
/* get the DestroyMutex object out of the jInitArgs object */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;");
if (fieldID == NULL) { return rv; }
jDestroyMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
assert(jDestroyMutex != 0);
/* call the CK_DESTROYMUTEX method of the DestroyMutex object */
methodID = (*env)->GetMethodID(env, jDestroyMutexClass, "CK_DESTROYMUTEX", "(Ljava/lang/Object;)V");
if (methodID == NULL) { return rv; }
(*env)->CallVoidMethod(env, jDestroyMutex, methodID, jMutex);
/* delete the global reference on the Java mutex */
(*env)->DeleteGlobalRef(env, jMutex);
/* check, if callback threw an exception */
pkcs11Exception = (*env)->ExceptionOccurred(env);
if (pkcs11Exception != NULL) {
/* TBD: clear the pending exception with ExceptionClear? */
/* The was an exception thrown, now we get the error-code from it */
pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
if (pkcs11ExceptionClass == NULL) { return rv; }
methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
if (methodID == NULL) { return rv; }
errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
rv = jLongToCKULong(errorCode);
}
/* if we attached this thread to the VM just for callback, we detach it now */
if (wasAttached) {
returnValue = (*jvm)->DetachCurrentThread(jvm);
}
return rv ;
}
/*
* is the function that gets called by PKCS#11 to lock a mutex and calls the Java
* LockMutex function
*
* @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
* @param pMutex - the mutex to lock
* @return - should return CKR_OK if the mutex was not locked already
*/
CK_RV callJLockMutex(CK_VOID_PTR pMutex)
{
extern JavaVM *jvm;
JNIEnv *env;
jint returnValue;
jthrowable pkcs11Exception;
jclass pkcs11ExceptionClass;
jlong errorCode;
CK_RV rv = CKR_OK;
int wasAttached = 1;
jclass jLockMutexClass;
jclass jInitArgsClass;
jmethodID methodID;
jfieldID fieldID;
jobject jLockMutex;
jobject jMutex;
/* Get the currently running Java VM */
if (jvm == NULL) { return rv ; } /* there is no VM running */
/* Determine, if current thread is already attached */
returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
if (returnValue == JNI_EDETACHED) {
/* thread detached, so attach it */
wasAttached = 0;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else if (returnValue == JNI_EVERSION) {
/* this version of JNI is not supported, so just try to attach */
/* we assume it was attached to ensure that this thread is not detached
* afterwards even though it should not
*/
wasAttached = 1;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else {
/* attached */
wasAttached = 1;
}
jLockMutexClass = (*env)->FindClass(env, CLASS_LOCKMUTEX);
if (jLockMutexClass == NULL) { return rv; }
jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
if (jInitArgsClass == NULL) { return rv; }
/* convert the CK mutex to a Java mutex */
jMutex = ckVoidPtrToJObject(pMutex);
/* get the LockMutex object out of the jInitArgs object */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;");
if (fieldID == NULL) { return rv; }
jLockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
assert(jLockMutex != 0);
/* call the CK_LOCKMUTEX method of the LockMutex object */
methodID = (*env)->GetMethodID(env, jLockMutexClass, "CK_LOCKMUTEX", "(Ljava/lang/Object;)V");
if (methodID == NULL) { return rv; }
(*env)->CallVoidMethod(env, jLockMutex, methodID, jMutex);
/* check, if callback threw an exception */
pkcs11Exception = (*env)->ExceptionOccurred(env);
if (pkcs11Exception != NULL) {
/* TBD: clear the pending exception with ExceptionClear? */
/* The was an exception thrown, now we get the error-code from it */
pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
if (pkcs11ExceptionClass == NULL) { return rv; }
methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
if (methodID == NULL) { return rv; }
errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
rv = jLongToCKULong(errorCode);
}
/* if we attached this thread to the VM just for callback, we detach it now */
if (wasAttached) {
returnValue = (*jvm)->DetachCurrentThread(jvm);
}
return rv ;
}
/*
* is the function that gets called by PKCS#11 to unlock a mutex and calls the Java
* UnlockMutex function
*
* @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
* @param pMutex - the mutex to unlock
* @return - should return CKR_OK if the mutex was not unlocked already
*/
CK_RV callJUnlockMutex(CK_VOID_PTR pMutex)
{
extern JavaVM *jvm;
JNIEnv *env;
jint returnValue;
jthrowable pkcs11Exception;
jclass pkcs11ExceptionClass;
jlong errorCode;
CK_RV rv = CKR_OK;
int wasAttached = 1;
jclass jUnlockMutexClass;
jclass jInitArgsClass;
jmethodID methodID;
jfieldID fieldID;
jobject jUnlockMutex;
jobject jMutex;
/* Get the currently running Java VM */
if (jvm == NULL) { return rv ; } /* there is no VM running */
/* Determine, if current thread is already attached */
returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
if (returnValue == JNI_EDETACHED) {
/* thread detached, so attach it */
wasAttached = 0;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else if (returnValue == JNI_EVERSION) {
/* this version of JNI is not supported, so just try to attach */
/* we assume it was attached to ensure that this thread is not detached
* afterwards even though it should not
*/
wasAttached = 1;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else {
/* attached */
wasAttached = 1;
}
jUnlockMutexClass = (*env)->FindClass(env, CLASS_UNLOCKMUTEX);
if (jUnlockMutexClass == NULL) { return rv; }
jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
if (jInitArgsClass == NULL) { return rv; }
/* convert the CK-type mutex to a Java mutex */
jMutex = ckVoidPtrToJObject(pMutex);
/* get the UnlockMutex object out of the jInitArgs object */
fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;");
if (fieldID == NULL) { return rv; }
jUnlockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
assert(jUnlockMutex != 0);
/* call the CK_UNLOCKMUTEX method of the UnLockMutex object */
methodID = (*env)->GetMethodID(env, jUnlockMutexClass, "CK_UNLOCKMUTEX", "(Ljava/lang/Object;)V");
if (methodID == NULL) { return rv; }
(*env)->CallVoidMethod(env, jUnlockMutex, methodID, jMutex);
/* check, if callback threw an exception */
pkcs11Exception = (*env)->ExceptionOccurred(env);
if (pkcs11Exception != NULL) {
/* TBD: clear the pending exception with ExceptionClear? */
/* The was an exception thrown, now we get the error-code from it */
pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
if (pkcs11ExceptionClass == NULL) { return rv; }
methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
if (methodID == NULL) { return rv; }
errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
rv = jLongToCKULong(errorCode);
}
/* if we attached this thread to the VM just for callback, we detach it now */
if (wasAttached) {
returnValue = (*jvm)->DetachCurrentThread(jvm);
}
return rv ;
}
#endif /* NO_CALLBACKS */

View file

@ -0,0 +1,429 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
#ifdef P11_ENABLE_C_CREATEOBJECT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_CreateObject
* Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
* @return jlong jObjectHandle CK_OBJECT_HANDLE_PTR phObject
*/
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_OBJECT_HANDLE ckObjectHandle;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
jlong jObjectHandle = 0L;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) { return 0L; }
rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle, ckpAttributes, ckAttributesLength, &ckObjectHandle);
jObjectHandle = ckULongToJLong(ckObjectHandle);
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
return jObjectHandle ;
}
#endif
#ifdef P11_ENABLE_C_COPYOBJECT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_CopyObject
* Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
* @return jlong jNewObjectHandle CK_OBJECT_HANDLE_PTR phNewObject
*/
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CopyObject
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_OBJECT_HANDLE ckObjectHandle;
CK_OBJECT_HANDLE ckNewObjectHandle;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
jlong jNewObjectHandle = 0L;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckObjectHandle = jLongToCKULong(jObjectHandle);
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) { return 0L; }
rv = (*ckpFunctions->C_CopyObject)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength, &ckNewObjectHandle);
jNewObjectHandle = ckULongToJLong(ckNewObjectHandle);
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
return jNewObjectHandle ;
}
#endif
#ifdef P11_ENABLE_C_DESTROYOBJECT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_DestroyObject
* Signature: (JJ)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DestroyObject
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_OBJECT_HANDLE ckObjectHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckObjectHandle = jLongToCKULong(jObjectHandle);
rv = (*ckpFunctions->C_DestroyObject)(ckSessionHandle, ckObjectHandle);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_GETOBJECTSIZE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetObjectSize
* Signature: (JJ)J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
* @return jlong jObjectSize CK_ULONG_PTR pulSize
*/
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetObjectSize
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_OBJECT_HANDLE ckObjectHandle;
CK_ULONG ckObjectSize;
jlong jObjectSize = 0L;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckObjectHandle = jLongToCKULong(jObjectHandle);
rv = (*ckpFunctions->C_GetObjectSize)(ckSessionHandle, ckObjectHandle, &ckObjectSize);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
jObjectSize = ckULongToJLong(ckObjectSize);
return jObjectSize ;
}
#endif
#ifdef P11_ENABLE_C_GETATTRIBUTEVALUE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetAttributeValue
* Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetAttributeValue
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_OBJECT_HANDLE ckObjectHandle;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
CK_ULONG ckBufferLength;
CK_ULONG i;
jobject jAttribute;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
TRACE0("DEBUG: C_GetAttributeValue");
TRACE1(", hSession=%u", jSessionHandle);
TRACE1(", hObject=%u", jObjectHandle);
TRACE1(", pTemplate=%p", jTemplate);
TRACE0(" ... ");
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckObjectHandle = jLongToCKULong(jObjectHandle);
TRACE1("jAttributeArrayToCKAttributeArray now with jTemplate = %d", jTemplate);
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) { return; }
TRACE2("DEBUG: jAttributeArrayToCKAttributeArray finished with ckpAttribute = %d, Length = %d\n", ckpAttributes, ckAttributesLength);
/* first set all pValue to NULL, to get the needed buffer length */
for(i = 0; i < ckAttributesLength; i++) {
if (ckpAttributes[i].pValue != NULL_PTR) {
free(ckpAttributes[i].pValue);
ckpAttributes[i].pValue = NULL_PTR;
}
}
rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
free(ckpAttributes);
return ;
}
/* now, the ulValueLength field of each attribute should hold the exact buffer length needed
* allocate the needed buffers accordingly
*/
for (i = 0; i < ckAttributesLength; i++) {
ckBufferLength = sizeof(CK_BYTE) * ckpAttributes[i].ulValueLen;
ckpAttributes[i].pValue = (void *) malloc(ckBufferLength);
if (ckpAttributes[i].pValue == NULL) {
freeCKAttributeArray(ckpAttributes, i);
throwOutOfMemoryError(env, 0);
return;
}
ckpAttributes[i].ulValueLen = ckBufferLength;
}
/* now get the attributes with all values */
rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
/* copy back the values to the Java attributes */
for (i = 0; i < ckAttributesLength; i++) {
jAttribute = ckAttributePtrToJAttribute(env, &(ckpAttributes[i]));
if (jAttribute == NULL) {
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
return;
}
(*env)->SetObjectArrayElement(env, jTemplate, i, jAttribute);
if ((*env)->ExceptionCheck(env)) {
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
return;
}
}
}
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
TRACE0("FINISHED\n");
}
#endif
#ifdef P11_ENABLE_C_SETATTRIBUTEVALUE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SetAttributeValue
* Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jObjectHandle CK_OBJECT_HANDLE hObject
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetAttributeValue
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_OBJECT_HANDLE ckObjectHandle;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckObjectHandle = jLongToCKULong(jObjectHandle);
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_SetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_FINDOBJECTSINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_FindObjectsInit
* Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate
* CK_ULONG ulCount
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsInit
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
CK_ULONG ckAttributesLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
TRACE0("DEBUG: C_FindObjectsInit");
TRACE1(", hSession=%u", jSessionHandle);
TRACE1(", pTemplate=%p", jTemplate);
TRACE0(" ... ");
ckSessionHandle = jLongToCKULong(jSessionHandle);
jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_FindObjectsInit)(ckSessionHandle, ckpAttributes, ckAttributesLength);
freeCKAttributeArray(ckpAttributes, ckAttributesLength);
TRACE0("FINISHED\n");
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_FINDOBJECTS
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_FindObjects
* Signature: (JJ)[J
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jMaxObjectCount CK_ULONG ulMaxObjectCount
* @return jlongArray jObjectHandleArray CK_OBJECT_HANDLE_PTR phObject
* CK_ULONG_PTR pulObjectCount
*/
JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjects
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jMaxObjectCount)
{
CK_RV rv;
CK_SESSION_HANDLE ckSessionHandle;
CK_ULONG ckMaxObjectLength;
CK_OBJECT_HANDLE_PTR ckpObjectHandleArray;
CK_ULONG ckActualObjectCount;
jlongArray jObjectHandleArray = NULL;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckMaxObjectLength = jLongToCKULong(jMaxObjectCount);
ckpObjectHandleArray = (CK_OBJECT_HANDLE_PTR) malloc(sizeof(CK_OBJECT_HANDLE) * ckMaxObjectLength);
if (ckpObjectHandleArray == NULL) {
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_FindObjects)(ckSessionHandle, ckpObjectHandleArray, ckMaxObjectLength, &ckActualObjectCount);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jObjectHandleArray = ckULongArrayToJLongArray(env, ckpObjectHandleArray, ckActualObjectCount);
}
free(ckpObjectHandleArray);
return jObjectHandleArray ;
}
#endif
#ifdef P11_ENABLE_C_FINDOBJECTSFINAL
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_FindObjectsFinal
* Signature: (J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsFinal
(JNIEnv *env, jobject obj, jlong jSessionHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
rv = (*ckpFunctions->C_FindObjectsFinal)(ckSessionHandle);
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif

View file

@ -0,0 +1,634 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
/* The list of notify callback handles that are currently active and waiting
* for callbacks from their sessions.
*/
#ifndef NO_CALLBACKS
NotifyListNode *notifyListHead = NULL;
jobject notifyListLock = NULL;
#endif /* NO_CALLBACKS */
#ifdef P11_ENABLE_C_OPENSESSION
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_OpenSession
* Signature: (JJLjava/lang/Object;Lsun/security/pkcs11/wrapper/CK_NOTIFY;)J
* Parametermapping: *PKCS11*
* @param jlong jSlotID CK_SLOT_ID slotID
* @param jlong jFlags CK_FLAGS flags
* @param jobject jApplication CK_VOID_PTR pApplication
* @param jobject jNotify CK_NOTIFY Notify
* @return jlong jSessionHandle CK_SESSION_HANDLE_PTR phSession
*/
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1OpenSession
(JNIEnv *env, jobject obj, jlong jSlotID, jlong jFlags, jobject jApplication, jobject jNotify)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_SLOT_ID ckSlotID;
CK_FLAGS ckFlags;
CK_VOID_PTR ckpApplication;
CK_NOTIFY ckNotify;
jlong jSessionHandle;
CK_RV rv;
#ifndef NO_CALLBACKS
NotifyEncapsulation *notifyEncapsulation = NULL;
#endif /* NO_CALLBACKS */
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0L; }
ckSlotID = jLongToCKULong(jSlotID);
ckFlags = jLongToCKULong(jFlags);
#ifndef NO_CALLBACKS
if (jNotify != NULL) {
notifyEncapsulation = (NotifyEncapsulation *) malloc(sizeof(NotifyEncapsulation));
if (notifyEncapsulation == NULL) {
throwOutOfMemoryError(env, 0);
return 0L;
}
notifyEncapsulation->jApplicationData = (jApplication != NULL)
? (*env)->NewGlobalRef(env, jApplication)
: NULL;
notifyEncapsulation->jNotifyObject = (*env)->NewGlobalRef(env, jNotify);
ckpApplication = notifyEncapsulation;
ckNotify = (CK_NOTIFY) &notifyCallback;
} else {
ckpApplication = NULL_PTR;
ckNotify = NULL_PTR;
}
#else
ckpApplication = NULL_PTR;
ckNotify = NULL_PTR;
#endif /* NO_CALLBACKS */
TRACE0("DEBUG: C_OpenSession");
TRACE1(", slotID=%u", ckSlotID);
TRACE1(", flags=%x", ckFlags);
TRACE0(" ... ");
rv = (*ckpFunctions->C_OpenSession)(ckSlotID, ckFlags, ckpApplication, ckNotify, &ckSessionHandle);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
#ifndef NO_CALLBACKS
if (notifyEncapsulation != NULL) {
if (notifyEncapsulation->jApplicationData != NULL) {
(*env)->DeleteGlobalRef(env, jApplication);
}
(*env)->DeleteGlobalRef(env, jNotify);
free(notifyEncapsulation);
}
#endif /* NO_CALLBACKS */
return 0L;
}
TRACE0("got session");
TRACE1(", SessionHandle=%u", ckSessionHandle);
TRACE0(" ... ");
jSessionHandle = ckULongToJLong(ckSessionHandle);
#ifndef NO_CALLBACKS
if (notifyEncapsulation != NULL) {
/* store the notifyEncapsulation to enable later cleanup */
putNotifyEntry(env, ckSessionHandle, notifyEncapsulation);
}
#endif /* NO_CALLBACKS */
TRACE0("FINISHED\n");
return jSessionHandle ;
}
#endif
#ifdef P11_ENABLE_C_CLOSESESSION
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_CloseSession
* Signature: (J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession
(JNIEnv *env, jobject obj, jlong jSessionHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
#ifndef NO_CALLBACKS
NotifyEncapsulation *notifyEncapsulation;
jobject jApplicationData;
#endif /* NO_CALLBACKS */
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
rv = (*ckpFunctions->C_CloseSession)(ckSessionHandle);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
#ifndef NO_CALLBACKS
notifyEncapsulation = removeNotifyEntry(env, ckSessionHandle);
if (notifyEncapsulation != NULL) {
/* there was a notify object used with this session, now dump the
* encapsulation object
*/
(*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
jApplicationData = notifyEncapsulation->jApplicationData;
if (jApplicationData != NULL) {
(*env)->DeleteGlobalRef(env, jApplicationData);
}
free(notifyEncapsulation);
}
#endif /* NO_CALLBACKS */
}
#endif
#ifdef P11_ENABLE_C_CLOSEALLSESSIONS
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_CloseAllSessions
* Signature: (J)V
* Parametermapping: *PKCS11*
* @param jlong jSlotID CK_SLOT_ID slotID
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseAllSessions
(JNIEnv *env, jobject obj, jlong jSlotID)
{
CK_SLOT_ID ckSlotID;
CK_RV rv;
#ifndef NO_CALLBACKS
NotifyEncapsulation *notifyEncapsulation;
jobject jApplicationData;
#endif /* NO_CALLBACKS */
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSlotID = jLongToCKULong(jSlotID);
rv = (*ckpFunctions->C_CloseAllSessions)(ckSlotID);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
#ifndef NO_CALLBACKS
/* Remove all notify callback helper objects. */
while ((notifyEncapsulation = removeFirstNotifyEntry(env)) != NULL) {
/* there was a notify object used with this session, now dump the
* encapsulation object
*/
(*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
jApplicationData = notifyEncapsulation->jApplicationData;
if (jApplicationData != NULL) {
(*env)->DeleteGlobalRef(env, jApplicationData);
}
free(notifyEncapsulation);
}
#endif /* NO_CALLBACKS */
}
#endif
#ifdef P11_ENABLE_C_GETSESSIONINFO
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetSessionInfo
* Signature: (J)Lsun/security/pkcs11/wrapper/CK_SESSION_INFO;
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @return jobject jSessionInfo CK_SESSION_INFO_PTR pInfo
*/
JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionInfo
(JNIEnv *env, jobject obj, jlong jSessionHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_SESSION_INFO ckSessionInfo;
jobject jSessionInfo=NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
rv = (*ckpFunctions->C_GetSessionInfo)(ckSessionHandle, &ckSessionInfo);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jSessionInfo = ckSessionInfoPtrToJSessionInfo(env, &ckSessionInfo);
}
return jSessionInfo ;
}
#endif
#ifdef P11_ENABLE_C_GETOPERATIONSTATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_GetOperationState
* Signature: (J)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @return jbyteArray jState CK_BYTE_PTR pOperationState
* CK_ULONG_PTR pulOperationStateLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState
(JNIEnv *env, jobject obj, jlong jSessionHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpState;
CK_ULONG ckStateLength;
jbyteArray jState = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, NULL_PTR, &ckStateLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
ckpState = (CK_BYTE_PTR) malloc(ckStateLength);
if (ckpState == NULL) {
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, ckpState, &ckStateLength);
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jState = ckByteArrayToJByteArray(env, ckpState, ckStateLength);
}
free(ckpState);
return jState ;
}
#endif
#ifdef P11_ENABLE_C_SETOPERATIONSTATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SetOperationState
* Signature: (J[BJJ)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jOperationState CK_BYTE_PTR pOperationState
* CK_ULONG ulOperationStateLen
* @param jlong jEncryptionKeyHandle CK_OBJECT_HANDLE hEncryptionKey
* @param jlong jAuthenticationKeyHandle CK_OBJECT_HANDLE hAuthenticationKey
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jOperationState, jlong jEncryptionKeyHandle, jlong jAuthenticationKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpState = NULL_PTR;
CK_ULONG ckStateLength;
CK_OBJECT_HANDLE ckEncryptionKeyHandle;
CK_OBJECT_HANDLE ckAuthenticationKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jOperationState, &ckpState, &ckStateLength);
if ((*env)->ExceptionCheck(env)) { return; }
ckEncryptionKeyHandle = jLongToCKULong(jEncryptionKeyHandle);
ckAuthenticationKeyHandle = jLongToCKULong(jAuthenticationKeyHandle);
rv = (*ckpFunctions->C_SetOperationState)(ckSessionHandle, ckpState, ckStateLength, ckEncryptionKeyHandle, ckAuthenticationKeyHandle);
free(ckpState);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_LOGIN
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Login
* Signature: (JJ[C)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jlong jUserType CK_USER_TYPE userType
* @param jcharArray jPin CK_CHAR_PTR pPin
* CK_ULONG ulPinLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, jcharArray jPin)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_USER_TYPE ckUserType;
CK_CHAR_PTR ckpPinArray = NULL_PTR;
CK_ULONG ckPinLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
ckUserType = jLongToCKULong(jUserType);
jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength);
if ((*env)->ExceptionCheck(env)) { return; }
rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, ckPinLength);
free(ckpPinArray);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_LOGOUT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Logout
* Signature: (J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout
(JNIEnv *env, jobject obj, jlong jSessionHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
rv = (*ckpFunctions->C_Logout)(ckSessionHandle);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
/* ************************************************************************** */
/* Functions for keeping track of notify callbacks */
/* ************************************************************************** */
#ifndef NO_CALLBACKS
/*
* Add the given notify encapsulation object to the list of active notify
* objects.
* If notifyEncapsulation is NULL, this function does nothing.
*/
void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation) {
NotifyListNode *currentNode, *newNode;
if (notifyEncapsulation == NULL) {
return;
}
newNode = (NotifyListNode *) malloc(sizeof(NotifyListNode));
if (newNode == NULL) {
throwOutOfMemoryError(env, 0);
return;
}
newNode->hSession = hSession;
newNode->notifyEncapsulation = notifyEncapsulation;
newNode->next = NULL;
(*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
if (notifyListHead == NULL) {
/* this is the first entry */
notifyListHead = newNode;
} else {
/* go to the last entry; i.e. the first node which's 'next' is NULL.
*/
currentNode = notifyListHead;
while (currentNode->next != NULL) {
currentNode = currentNode->next;
}
currentNode->next = newNode;
}
(*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
}
/*
* Removes the active notifyEncapsulation object used with the given session and
* returns it. If there is no notifyEncapsulation active for this session, this
* function returns NULL.
*/
NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession) {
NotifyEncapsulation *notifyEncapsulation;
NotifyListNode *currentNode, *previousNode;
(*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
if (notifyListHead == NULL) {
/* this is the first entry */
notifyEncapsulation = NULL;
} else {
/* Find the node with the wanted session handle. Also stop, when we reach
* the last entry; i.e. the first node which's 'next' is NULL.
*/
currentNode = notifyListHead;
previousNode = NULL;
while ((currentNode->hSession != hSession) && (currentNode->next != NULL)) {
previousNode = currentNode;
currentNode = currentNode->next;
}
if (currentNode->hSession == hSession) {
/* We found a entry for the wanted session, now remove it. */
if (previousNode == NULL) {
/* it's the first node */
notifyListHead = currentNode->next;
} else {
previousNode->next = currentNode->next;
}
notifyEncapsulation = currentNode->notifyEncapsulation;
free(currentNode);
} else {
/* We did not find a entry for this session */
notifyEncapsulation = NULL;
}
}
(*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
return notifyEncapsulation ;
}
/*
* Removes the first notifyEncapsulation object. If there is no notifyEncapsulation,
* this function returns NULL.
*/
NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env) {
NotifyEncapsulation *notifyEncapsulation;
NotifyListNode *currentNode;
(*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
if (notifyListHead == NULL) {
/* this is the first entry */
notifyEncapsulation = NULL;
} else {
/* Remove the first entry. */
currentNode = notifyListHead;
notifyListHead = notifyListHead->next;
notifyEncapsulation = currentNode->notifyEncapsulation;
free(currentNode);
}
(*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
return notifyEncapsulation ;
}
#endif /* NO_CALLBACKS */
#ifndef NO_CALLBACKS
/*
* The function handling notify callbacks. It casts the pApplication parameter
* back to a NotifyEncapsulation structure and retrieves the Notify object and
* the application data from it.
*
* @param hSession The session, this callback is comming from.
* @param event The type of event that occurred.
* @param pApplication The application data as passed in upon OpenSession. In
this wrapper we always pass in a NotifyEncapsulation
object, which holds necessary information for delegating
the callback to the Java VM.
* @return
*/
CK_RV notifyCallback(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_NOTIFICATION event,
CK_VOID_PTR pApplication /* passed to C_OpenSession */
)
{
NotifyEncapsulation *notifyEncapsulation;
extern JavaVM *jvm;
JNIEnv *env;
jint returnValue;
jlong jSessionHandle;
jlong jEvent;
jclass ckNotifyClass;
jmethodID jmethod;
jthrowable pkcs11Exception;
jclass pkcs11ExceptionClass;
jlong errorCode;
CK_RV rv = CKR_OK;
int wasAttached = 1;
if (pApplication == NULL) { return rv ; } /* This should not occur in this wrapper. */
notifyEncapsulation = (NotifyEncapsulation *) pApplication;
/* Get the currently running Java VM */
if (jvm == NULL) { return rv ; } /* there is no VM running */
/* Determine, if current thread is already attached */
returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
if (returnValue == JNI_EDETACHED) {
/* thread detached, so attach it */
wasAttached = 0;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else if (returnValue == JNI_EVERSION) {
/* this version of JNI is not supported, so just try to attach */
/* we assume it was attached to ensure that this thread is not detached
* afterwards even though it should not
*/
wasAttached = 1;
returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
} else {
/* attached */
wasAttached = 1;
}
jSessionHandle = ckULongToJLong(hSession);
jEvent = ckULongToJLong(event);
ckNotifyClass = (*env)->FindClass(env, CLASS_NOTIFY);
if (ckNotifyClass == NULL) { return rv; }
jmethod = (*env)->GetMethodID(env, ckNotifyClass, "CK_NOTIFY", "(JJLjava/lang/Object;)V");
if (jmethod == NULL) { return rv; }
(*env)->CallVoidMethod(env, notifyEncapsulation->jNotifyObject, jmethod,
jSessionHandle, jEvent, notifyEncapsulation->jApplicationData);
/* check, if callback threw an exception */
pkcs11Exception = (*env)->ExceptionOccurred(env);
if (pkcs11Exception != NULL) {
/* TBD: clear the pending exception with ExceptionClear? */
/* The was an exception thrown, now we get the error-code from it */
pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
if (pkcs11ExceptionClass == NULL) { return rv; }
jmethod = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
if (jmethod == NULL) { return rv; }
errorCode = (*env)->CallLongMethod(env, pkcs11Exception, jmethod);
rv = jLongToCKULong(errorCode);
}
/* if we attached this thread to the VM just for callback, we detach it now */
if (wasAttached) {
returnValue = (*jvm)->DetachCurrentThread(jvm);
}
return rv ;
}
#endif /* NO_CALLBACKS */

View file

@ -0,0 +1,674 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "jlong.h"
#include "sun_security_pkcs11_wrapper_PKCS11.h"
#ifdef P11_ENABLE_C_SIGNINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SignInit
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @return jlong jKeyHandle CK_OBJECT_HANDLE hKey
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignInit
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return; }
ckKeyHandle = jLongToCKULong(jKeyHandle);
rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_SIGN
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Sign
* Signature: (J[B)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG ulDataLen
* @return jbyteArray jSignature CK_BYTE_PTR pSignature
* CK_ULONG_PTR pulSignatureLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpData = NULL_PTR;
CK_BYTE_PTR ckpSignature;
CK_ULONG ckDataLength;
CK_ULONG ckSignatureLength = 0;
jbyteArray jSignature = NULL;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
if ((*env)->ExceptionCheck(env)) { return NULL; }
/* START standard code */
/* first determine the length of the signature */
rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
free(ckpData);
return NULL;
}
ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
if (ckpSignature == NULL) {
free(ckpData);
throwOutOfMemoryError(env, 0);
return NULL;
}
/* now get the signature */
rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
/* END standard code */
/* START workaround code for operation abort bug in pkcs#11 of Datakey and iButton */
/*
ckpSignature = (CK_BYTE_PTR) malloc(256 * sizeof(CK_BYTE));
if (ckpSignature == NULL) {
free(ckpData);
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
if (rv == CKR_BUFFER_TOO_SMALL) {
free(ckpSignature);
ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
if (ckpSignature == NULL) {
free(ckpData);
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
}
*/
/* END workaround code */
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
}
free(ckpData);
free(ckpSignature);
return jSignature ;
}
#endif
#ifdef P11_ENABLE_C_SIGNUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SignUpdate
* Signature: (J[BII)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG ulPartLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR bufP;
CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
jsize bufLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (directIn != 0) {
rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, (CK_BYTE_PTR) jlong_to_ptr(directIn), jInLen);
ckAssertReturnValueOK(env, rv);
return;
}
if (jInLen <= MAX_STACK_BUFFER_LEN) {
bufLen = MAX_STACK_BUFFER_LEN;
bufP = BUF;
} else {
bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
if (bufP == NULL) {
throwOutOfMemoryError(env, 0);
return;
}
}
while (jInLen > 0) {
jsize chunkLen = min(bufLen, jInLen);
(*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
if (bufP != BUF) { free(bufP); }
return;
}
rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
if (bufP != BUF) {
free(bufP);
}
return;
}
jInOfs += chunkLen;
jInLen -= chunkLen;
}
if (bufP != BUF) { free(bufP); }
}
#endif
#ifdef P11_ENABLE_C_SIGNFINAL
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SignFinal
* Signature: (J)[B
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @return jbyteArray jSignature CK_BYTE_PTR pSignature
* CK_ULONG_PTR pulSignatureLen
*/
JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFinal
(JNIEnv *env, jobject obj, jlong jSessionHandle, jint jExpectedLength)
{
CK_SESSION_HANDLE ckSessionHandle;
jbyteArray jSignature = NULL;
CK_RV rv;
CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
CK_BYTE_PTR bufP = BUF;
CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return NULL; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if ((jExpectedLength > 0) && ((CK_ULONG)jExpectedLength < ckSignatureLength)) {
ckSignatureLength = jExpectedLength;
}
rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
if (rv == CKR_BUFFER_TOO_SMALL) {
bufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
if (bufP == NULL) {
throwOutOfMemoryError(env, 0);
return NULL;
}
rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
}
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength);
}
if (bufP != BUF) { free(bufP); }
return jSignature;
}
#endif
#ifdef P11_ENABLE_C_SIGNRECOVERINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SignRecoverInit
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @return jlong jKeyHandle CK_OBJECT_HANDLE hKey
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecoverInit
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return; }
ckKeyHandle = jLongToCKULong(jKeyHandle);
rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_SIGNRECOVER
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_SignRecover
* Signature: (J[BII[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG ulDataLen
* @return jbyteArray jSignature CK_BYTE_PTR pSignature
* CK_ULONG_PTR pulSignatureLen
*/
JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
CK_BYTE_PTR inBufP;
CK_BYTE_PTR outBufP = OUTBUF;
CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (jInLen <= MAX_STACK_BUFFER_LEN) {
inBufP = INBUF;
} else {
inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
if (inBufP == NULL) {
throwOutOfMemoryError(env, 0);
return 0;
}
}
(*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
if ((*env)->ExceptionCheck(env)) {
if (inBufP != INBUF) { free(inBufP); }
return 0;
}
rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
/* re-alloc larger buffer if it fits into our Java buffer */
if ((rv == CKR_BUFFER_TOO_SMALL) && (ckSignatureLength <= jIntToCKULong(jOutLen))) {
outBufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
if (outBufP == NULL) {
if (inBufP != INBUF) {
free(inBufP);
}
throwOutOfMemoryError(env, 0);
return 0;
}
rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
}
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
(*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckSignatureLength, (jbyte *)outBufP);
}
if (inBufP != INBUF) { free(inBufP); }
if (outBufP != OUTBUF) { free(outBufP); }
return ckSignatureLength;
}
#endif
#ifdef P11_ENABLE_C_VERIFYINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_VerifyInit
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @return jlong jKeyHandle CK_OBJECT_HANDLE hKey
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyInit
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return; }
ckKeyHandle = jLongToCKULong(jKeyHandle);
rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
if(ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_VERIFY
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_Verify
* Signature: (J[B[B)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG ulDataLen
* @param jbyteArray jSignature CK_BYTE_PTR pSignature
* CK_ULONG_PTR pulSignatureLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Verify
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpData = NULL_PTR;
CK_BYTE_PTR ckpSignature = NULL_PTR;
CK_ULONG ckDataLength;
CK_ULONG ckSignatureLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
if ((*env)->ExceptionCheck(env)) { return; }
jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
if ((*env)->ExceptionCheck(env)) {
free(ckpData);
return;
}
/* verify the signature */
rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength);
free(ckpData);
free(ckpSignature);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_VERIFYUPDATE
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_VerifyUpdate
* Signature: (J[BII)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jPart CK_BYTE_PTR pPart
* CK_ULONG ulPartLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyUpdate
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE_PTR bufP;
CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
jsize bufLen;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (directIn != 0) {
rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
ckAssertReturnValueOK(env, rv);
return;
}
if (jInLen <= MAX_STACK_BUFFER_LEN) {
bufLen = MAX_STACK_BUFFER_LEN;
bufP = BUF;
} else {
bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
if (bufP == NULL) {
throwOutOfMemoryError(env, 0);
return;
}
}
while (jInLen > 0) {
jsize chunkLen = min(bufLen, jInLen);
(*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
if ((*env)->ExceptionCheck(env)) {
if (bufP != BUF) { free(bufP); }
return;
}
rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, bufP, chunkLen);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
if (bufP != BUF) { free(bufP); }
return;
}
jInOfs += chunkLen;
jInLen -= chunkLen;
}
if (bufP != BUF) { free(bufP); }
}
#endif
#ifdef P11_ENABLE_C_VERIFYFINAL
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_VerifyFinal
* Signature: (J[B)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jSignature CK_BYTE_PTR pSignature
* CK_ULONG ulSignatureLen
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyFinal
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_BYTE_PTR ckpSignature = NULL_PTR;
CK_ULONG ckSignatureLength;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
if ((*env)->ExceptionCheck(env)) { return; }
/* verify the signature */
rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength);
free(ckpSignature);
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_VERIFYRECOVERINIT
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_VerifyRecoverInit
* Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jobject jMechanism CK_MECHANISM_PTR pMechanism
* @return jlong jKeyHandle CK_OBJECT_HANDLE hKey
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecoverInit
(JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_MECHANISM ckMechanism;
CK_OBJECT_HANDLE ckKeyHandle;
CK_RV rv;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
if ((*env)->ExceptionCheck(env)) { return; }
ckKeyHandle = jLongToCKULong(jKeyHandle);
rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
if (ckMechanism.pParameter != NULL_PTR) {
free(ckMechanism.pParameter);
}
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
#endif
#ifdef P11_ENABLE_C_VERIFYRECOVER
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: C_VerifyRecover
* Signature: (J[BII[BII)I
* Parametermapping: *PKCS11*
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
* @param jbyteArray jSignature CK_BYTE_PTR pSignature
* CK_ULONG ulSignatureLen
* @return jbyteArray jData CK_BYTE_PTR pData
* CK_ULONG_PTR pulDataLen
*/
JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover
(JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
{
CK_SESSION_HANDLE ckSessionHandle;
CK_RV rv;
CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
CK_BYTE_PTR inBufP;
CK_BYTE_PTR outBufP = OUTBUF;
CK_ULONG ckDataLength = MAX_STACK_BUFFER_LEN;
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
if (ckpFunctions == NULL) { return 0; }
ckSessionHandle = jLongToCKULong(jSessionHandle);
if (jInLen <= MAX_STACK_BUFFER_LEN) {
inBufP = INBUF;
} else {
inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
if (inBufP == NULL) {
throwOutOfMemoryError(env, 0);
return 0;
}
}
(*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
if ((*env)->ExceptionCheck(env)) {
if (inBufP != INBUF) { free(inBufP); }
return 0;
}
rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
/* re-alloc larger buffer if it fits into our Java buffer */
if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) {
outBufP = (CK_BYTE_PTR) malloc(ckDataLength);
if (outBufP == NULL) {
if (inBufP != INBUF) { free(inBufP); }
throwOutOfMemoryError(env, 0);
return 0;
}
rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
}
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
(*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP);
}
if (inBufP != INBUF) { free(inBufP); }
if (outBufP != OUTBUF) { free(outBufP); }
return ckDataLength;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,124 @@
/* pkcs-11v2-20a3.h include file for the PKCS #11 Version 2.20 Amendment 3
document. */
/* $Revision: 1.4 $ */
/* License to copy and use this software is granted provided that it is
* identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
* (Cryptoki) Version 2.20 Amendment 3" in all material mentioning or
* referencing this software.
* RSA Security Inc. makes no representations concerning either the
* merchantability of this software or the suitability of this software for
* any particular purpose. It is provided "as is" without express or implied
* warranty of any kind.
*/
/* This file is preferably included after inclusion of pkcs11.h */
#ifndef _PKCS_11V2_20A3_H_
#define _PKCS_11V2_20A3_H_ 1
/* Are the definitions of this file already included in pkcs11t.h ? */
#ifndef CKK_CAMELLIA
#ifdef __cplusplus
extern "C" {
#endif
/* Key types */
/* Camellia is new for PKCS #11 v2.20 amendment 3 */
#define CKK_CAMELLIA 0x00000025
/* ARIA is new for PKCS #11 v2.20 amendment 3 */
#define CKK_ARIA 0x00000026
/* Mask-generating functions */
/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
#define CKG_MGF1_SHA224 0x00000005
/* Mechanism Identifiers */
/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
#define CKM_SHA224 0x00000255
#define CKM_SHA224_HMAC 0x00000256
#define CKM_SHA224_HMAC_GENERAL 0x00000257
/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
#define CKM_SHA224_KEY_DERIVATION 0x00000396
/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
#define CKM_SHA224_RSA_PKCS 0x00000046
#define CKM_SHA224_RSA_PKCS_PSS 0x00000047
/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
#define CKM_AES_CTR 0x00001086
/* Camellia is new for PKCS #11 v2.20 amendment 3 */
#define CKM_CAMELLIA_KEY_GEN 0x00000550
#define CKM_CAMELLIA_ECB 0x00000551
#define CKM_CAMELLIA_CBC 0x00000552
#define CKM_CAMELLIA_MAC 0x00000553
#define CKM_CAMELLIA_MAC_GENERAL 0x00000554
#define CKM_CAMELLIA_CBC_PAD 0x00000555
#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556
#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557
#define CKM_CAMELLIA_CTR 0x00000558
/* ARIA is new for PKCS #11 v2.20 amendment 3 */
#define CKM_ARIA_KEY_GEN 0x00000560
#define CKM_ARIA_ECB 0x00000561
#define CKM_ARIA_CBC 0x00000562
#define CKM_ARIA_MAC 0x00000563
#define CKM_ARIA_MAC_GENERAL 0x00000564
#define CKM_ARIA_CBC_PAD 0x00000565
#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566
#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567
/* Mechanism parameters */
/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
typedef struct CK_AES_CTR_PARAMS {
CK_ULONG ulCounterBits;
CK_BYTE cb[16];
} CK_AES_CTR_PARAMS;
typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
typedef struct CK_CAMELLIA_CTR_PARAMS {
CK_ULONG ulCounterBits;
CK_BYTE cb[16];
} CK_CAMELLIA_CTR_PARAMS;
typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
CK_BYTE iv[16];
CK_BYTE_PTR pData;
CK_ULONG length;
} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
CK_BYTE iv[16];
CK_BYTE_PTR pData;
CK_ULONG length;
} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
#ifdef __cplusplus
}
#endif
#endif
#endif

View file

@ -0,0 +1,299 @@
/* pkcs11.h include file for PKCS #11. */
/* $Revision: 1.4 $ */
/* License to copy and use this software is granted provided that it is
* identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
* (Cryptoki)" in all material mentioning or referencing this software.
* License is also granted to make and use derivative works provided that
* such works are identified as "derived from the RSA Security Inc. PKCS #11
* Cryptographic Token Interface (Cryptoki)" in all material mentioning or
* referencing the derived work.
* RSA Security Inc. makes no representations concerning either the
* merchantability of this software or the suitability of this software for
* any particular purpose. It is provided "as is" without express or implied
* warranty of any kind.
*/
#ifndef _PKCS11_H_
#define _PKCS11_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* Before including this file (pkcs11.h) (or pkcs11t.h by
* itself), 6 platform-specific macros must be defined. These
* macros are described below, and typical definitions for them
* are also given. Be advised that these definitions can depend
* on both the platform and the compiler used (and possibly also
* on whether a Cryptoki library is linked statically or
* dynamically).
*
* In addition to defining these 6 macros, the packing convention
* for Cryptoki structures should be set. The Cryptoki
* convention on packing is that structures should be 1-byte
* aligned.
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, this might be done by using the following
* preprocessor directive before including pkcs11.h or pkcs11t.h:
*
* #pragma pack(push, cryptoki, 1)
*
* and using the following preprocessor directive after including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(pop, cryptoki)
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, this might be done by using
* the following preprocessor directive before including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(1)
*
* In a UNIX environment, you're on your own for this. You might
* not need to do (or be able to do!) anything.
*
*
* Now for the macros:
*
*
* 1. CK_PTR: The indirection string for making a pointer to an
* object. It can be used like this:
*
* typedef CK_BYTE CK_PTR CK_BYTE_PTR;
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, it might be defined by:
*
* #define CK_PTR *
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, it might be defined by:
*
* #define CK_PTR far *
*
* In a typical UNIX environment, it might be defined by:
*
* #define CK_PTR *
*
*
* 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
* an exportable Cryptoki library function definition out of a
* return type and a function name. It should be used in the
* following fashion to define the exposed Cryptoki functions in
* a Cryptoki library:
*
* CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
* CK_VOID_PTR pReserved
* )
* {
* ...
* }
*
* If you're using Microsoft Developer Studio 5.0 to define a
* function in a Win32 Cryptoki .dll, it might be defined by:
*
* #define CK_DEFINE_FUNCTION(returnType, name) \
* returnType __declspec(dllexport) name
*
* If you're using an earlier version of Microsoft Developer
* Studio to define a function in a Win16 Cryptoki .dll, it
* might be defined by:
*
* #define CK_DEFINE_FUNCTION(returnType, name) \
* returnType __export _far _pascal name
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DEFINE_FUNCTION(returnType, name) \
* returnType name
*
*
* 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
* an importable Cryptoki library function declaration out of a
* return type and a function name. It should be used in the
* following fashion:
*
* extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
* CK_VOID_PTR pReserved
* );
*
* If you're using Microsoft Developer Studio 5.0 to declare a
* function in a Win32 Cryptoki .dll, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __declspec(dllimport) name
*
* If you're using an earlier version of Microsoft Developer
* Studio to declare a function in a Win16 Cryptoki .dll, it
* might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __export _far _pascal name
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType name
*
*
* 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
* which makes a Cryptoki API function pointer declaration or
* function pointer type declaration out of a return type and a
* function name. It should be used in the following fashion:
*
* // Define funcPtr to be a pointer to a Cryptoki API function
* // taking arguments args and returning CK_RV.
* CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
*
* or
*
* // Define funcPtrType to be the type of a pointer to a
* // Cryptoki API function taking arguments args and returning
* // CK_RV, and then define funcPtr to be a variable of type
* // funcPtrType.
* typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
* funcPtrType funcPtr;
*
* If you're using Microsoft Developer Studio 5.0 to access
* functions in a Win32 Cryptoki .dll, in might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __declspec(dllimport) (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to access functions in a Win16 Cryptoki .dll, it might
* be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __export _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType (* name)
*
*
* 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
* a function pointer type for an application callback out of
* a return type for the callback and a name for the callback.
* It should be used in the following fashion:
*
* CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
*
* to declare a function pointer, myCallback, to a callback
* which takes arguments args and returns a CK_RV. It can also
* be used like this:
*
* typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
* myCallbackType myCallback;
*
* If you're using Microsoft Developer Studio 5.0 to do Win32
* Cryptoki development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to do Win16 development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
*
* 6. NULL_PTR: This macro is the value of a NULL pointer.
*
* In any ANSI/ISO C environment (and in many others as well),
* this should best be defined by
*
* #ifndef NULL_PTR
* #define NULL_PTR 0
* #endif
*/
/* All the various Cryptoki types and #define'd values are in the
* file pkcs11t.h. */
#include "pkcs11t.h"
#define __PASTE(x,y) x##y
/* ==============================================================
* Define the "extern" form of all the entry points.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
extern CK_DECLARE_FUNCTION(CK_RV, name)
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes. */
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define the typedef form of all the entry points. That is, for
* each Cryptoki function C_XXX, define a type CK_C_XXX which is
* a pointer to that kind of function.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes. */
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define structed vector of entry points. A CK_FUNCTION_LIST
* contains a CK_VERSION indicating a library's Cryptoki version
* and then a whole slew of function pointers to the routines in
* the library. This type was declared, but not defined, in
* pkcs11t.h.
* ==============================================================
*/
#define CK_PKCS11_FUNCTION_INFO(name) \
__PASTE(CK_,name) name;
struct CK_FUNCTION_LIST {
CK_VERSION version; /* Cryptoki version */
/* Pile all the function pointers into the CK_FUNCTION_LIST. */
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes. */
#include "pkcs11f.h"
};
#undef CK_PKCS11_FUNCTION_INFO
#undef __PASTE
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,912 @@
/* pkcs11f.h include file for PKCS #11. */
/* $Revision: 1.4 $ */
/* License to copy and use this software is granted provided that it is
* identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
* (Cryptoki)" in all material mentioning or referencing this software.
* License is also granted to make and use derivative works provided that
* such works are identified as "derived from the RSA Security Inc. PKCS #11
* Cryptographic Token Interface (Cryptoki)" in all material mentioning or
* referencing the derived work.
* RSA Security Inc. makes no representations concerning either the
* merchantability of this software or the suitability of this software for
* any particular purpose. It is provided "as is" without express or implied
* warranty of any kind.
*/
/* This header file contains pretty much everything about all the */
/* Cryptoki function prototypes. Because this information is */
/* used for more than just declaring function prototypes, the */
/* order of the functions appearing herein is important, and */
/* should not be altered. */
/* General-purpose */
/* C_Initialize initializes the Cryptoki library. */
CK_PKCS11_FUNCTION_INFO(C_Initialize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
* cast to CK_C_INITIALIZE_ARGS_PTR
* and dereferenced */
);
#endif
/* C_Finalize indicates that an application is done with the
* Cryptoki library. */
CK_PKCS11_FUNCTION_INFO(C_Finalize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
);
#endif
/* C_GetInfo returns general information about Cryptoki. */
CK_PKCS11_FUNCTION_INFO(C_GetInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_INFO_PTR pInfo /* location that receives information */
);
#endif
/* C_GetFunctionList returns the function list. */
CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
#ifdef CK_NEED_ARG_LIST
(
CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
* function list */
);
#endif
/* Slot and token management */
/* C_GetSlotList obtains a list of slots in the system. */
CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
#ifdef CK_NEED_ARG_LIST
(
CK_BBOOL tokenPresent, /* only slots with tokens? */
CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
CK_ULONG_PTR pulCount /* receives number of slots */
);
#endif
/* C_GetSlotInfo obtains information about a particular slot in
* the system. */
CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the ID of the slot */
CK_SLOT_INFO_PTR pInfo /* receives the slot information */
);
#endif
/* C_GetTokenInfo obtains information about a particular token
* in the system. */
CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_TOKEN_INFO_PTR pInfo /* receives the token information */
);
#endif
/* C_GetMechanismList obtains a list of mechanism types
* supported by a token. */
CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of token's slot */
CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
CK_ULONG_PTR pulCount /* gets # of mechs. */
);
#endif
/* C_GetMechanismInfo obtains information about a particular
* mechanism possibly supported by a token. */
CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_MECHANISM_TYPE type, /* type of mechanism */
CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
);
#endif
/* C_InitToken initializes a token. */
CK_PKCS11_FUNCTION_INFO(C_InitToken)
#ifdef CK_NEED_ARG_LIST
/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
CK_ULONG ulPinLen, /* length in bytes of the PIN */
CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
);
#endif
/* C_InitPIN initializes the normal user's PIN. */
CK_PKCS11_FUNCTION_INFO(C_InitPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
CK_ULONG ulPinLen /* length in bytes of the PIN */
);
#endif
/* C_SetPIN modifies the PIN of the user who is logged in. */
CK_PKCS11_FUNCTION_INFO(C_SetPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
CK_ULONG ulOldLen, /* length of the old PIN */
CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
CK_ULONG ulNewLen /* length of the new PIN */
);
#endif
/* Session management */
/* C_OpenSession opens a session between an application and a
* token. */
CK_PKCS11_FUNCTION_INFO(C_OpenSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the slot's ID */
CK_FLAGS flags, /* from CK_SESSION_INFO */
CK_VOID_PTR pApplication, /* passed to callback */
CK_NOTIFY Notify, /* callback function */
CK_SESSION_HANDLE_PTR phSession /* gets session handle */
);
#endif
/* C_CloseSession closes a session between an application and a
* token. */
CK_PKCS11_FUNCTION_INFO(C_CloseSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CloseAllSessions closes all sessions with a token. */
CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID /* the token's slot */
);
#endif
/* C_GetSessionInfo obtains information about the session. */
CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_SESSION_INFO_PTR pInfo /* receives session info */
);
#endif
/* C_GetOperationState obtains the state of the cryptographic operation
* in a session. */
CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* gets state */
CK_ULONG_PTR pulOperationStateLen /* gets state length */
);
#endif
/* C_SetOperationState restores the state of the cryptographic
* operation in a session. */
CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* holds state */
CK_ULONG ulOperationStateLen, /* holds state length */
CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
);
#endif
/* C_Login logs a user into a token. */
CK_PKCS11_FUNCTION_INFO(C_Login)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_USER_TYPE userType, /* the user type */
CK_UTF8CHAR_PTR pPin, /* the user's PIN */
CK_ULONG ulPinLen /* the length of the PIN */
);
#endif
/* C_Logout logs a user out from a token. */
CK_PKCS11_FUNCTION_INFO(C_Logout)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Object management */
/* C_CreateObject creates a new object. */
CK_PKCS11_FUNCTION_INFO(C_CreateObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
);
#endif
/* C_CopyObject copies an object, creating a new object for the
* copy. */
CK_PKCS11_FUNCTION_INFO(C_CopyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
);
#endif
/* C_DestroyObject destroys an object. */
CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject /* the object's handle */
);
#endif
/* C_GetObjectSize gets the size of an object in bytes. */
CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ULONG_PTR pulSize /* receives size of object */
);
#endif
/* C_GetAttributeValue obtains the value of one or more object
* attributes. */
CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_SetAttributeValue modifies the value of one or more object
* attributes */
CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_FindObjectsInit initializes a search for token and session
* objects that match a template. */
CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
CK_ULONG ulCount /* attrs in search template */
);
#endif
/* C_FindObjects continues a search for token and session
* objects that match a template, obtaining additional object
* handles. */
CK_PKCS11_FUNCTION_INFO(C_FindObjects)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
CK_ULONG ulMaxObjectCount, /* max handles to get */
CK_ULONG_PTR pulObjectCount /* actual # returned */
);
#endif
/* C_FindObjectsFinal finishes a search for token and session
* objects. */
CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Encryption and decryption */
/* C_EncryptInit initializes an encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of encryption key */
);
#endif
/* C_Encrypt encrypts single-part data. */
CK_PKCS11_FUNCTION_INFO(C_Encrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pData, /* the plaintext data */
CK_ULONG ulDataLen, /* bytes of plaintext */
CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
);
#endif
/* C_EncryptUpdate continues a multiple-part encryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext data len */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
);
#endif
/* C_EncryptFinal finishes a multiple-part encryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session handle */
CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
);
#endif
/* C_DecryptInit initializes a decryption operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of decryption key */
);
#endif
/* C_Decrypt decrypts encrypted data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Decrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedData, /* ciphertext */
CK_ULONG ulEncryptedDataLen, /* ciphertext length */
CK_BYTE_PTR pData, /* gets plaintext */
CK_ULONG_PTR pulDataLen /* gets p-text size */
);
#endif
/* C_DecryptUpdate continues a multiple-part decryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* encrypted data */
CK_ULONG ulEncryptedPartLen, /* input length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* p-text size */
);
#endif
/* C_DecryptFinal finishes a multiple-part decryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pLastPart, /* gets plaintext */
CK_ULONG_PTR pulLastPartLen /* p-text size */
);
#endif
/* Message digesting */
/* C_DigestInit initializes a message-digesting operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
);
#endif
/* C_Digest digests data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Digest)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* data to be digested */
CK_ULONG ulDataLen, /* bytes of data to digest */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets digest length */
);
#endif
/* C_DigestUpdate continues a multiple-part message-digesting
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* data to be digested */
CK_ULONG ulPartLen /* bytes of data to be digested */
);
#endif
/* C_DigestKey continues a multi-part message-digesting
* operation, by digesting the value of a secret key as part of
* the data already digested. */
CK_PKCS11_FUNCTION_INFO(C_DigestKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hKey /* secret key to digest */
);
#endif
/* C_DigestFinal finishes a multiple-part message-digesting
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
);
#endif
/* Signing and MACing */
/* C_SignInit initializes a signature (private key encryption)
* operation, where the signature is (will be) an appendix to
* the data, and plaintext cannot be recovered from the
*signature. */
CK_PKCS11_FUNCTION_INFO(C_SignInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of signature key */
);
#endif
/* C_Sign signs (encrypts with private key) data in a single
* part, where the signature is (will be) an appendix to the
* data, and plaintext cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_Sign)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignUpdate continues a multiple-part signature operation,
* where the signature is (will be) an appendix to the data,
* and plaintext cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* the data to sign */
CK_ULONG ulPartLen /* count of bytes to sign */
);
#endif
/* C_SignFinal finishes a multiple-part signature operation,
* returning the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignRecoverInit initializes a signature operation, where
* the data can be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of the signature key */
);
#endif
/* C_SignRecover signs data in a single operation, where the
* data can be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* Verifying signatures and MACs */
/* C_VerifyInit initializes a verification operation, where the
* signature is an appendix to the data, and plaintext cannot
* cannot be recovered from the signature (e.g. DSA). */
CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_Verify verifies a signature in a single-part operation,
* where the signature is an appendix to the data, and plaintext
* cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_Verify)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* signed data */
CK_ULONG ulDataLen, /* length of signed data */
CK_BYTE_PTR pSignature, /* signature */
CK_ULONG ulSignatureLen /* signature length*/
);
#endif
/* C_VerifyUpdate continues a multiple-part verification
* operation, where the signature is an appendix to the data,
* and plaintext cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* signed data */
CK_ULONG ulPartLen /* length of signed data */
);
#endif
/* C_VerifyFinal finishes a multiple-part verification
* operation, checking the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen /* signature length */
);
#endif
/* C_VerifyRecoverInit initializes a signature verification
* operation, where the data is recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_VerifyRecover verifies a signature in a single-part
* operation, where the data is recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen, /* signature length */
CK_BYTE_PTR pData, /* gets signed data */
CK_ULONG_PTR pulDataLen /* gets signed data len */
);
#endif
/* Dual-function cryptographic operations */
/* C_DigestEncryptUpdate continues a multiple-part digesting
* and encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptDigestUpdate continues a multiple-part decryption and
* digesting operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets plaintext len */
);
#endif
/* C_SignEncryptUpdate continues a multiple-part signing and
* encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptVerifyUpdate continues a multiple-part decryption and
* verify operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets p-text length */
);
#endif
/* Key management */
/* C_GenerateKey generates a secret key, creating a new key
* object. */
CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* key generation mech. */
CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
CK_ULONG ulCount, /* # of attrs in template */
CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
);
#endif
/* C_GenerateKeyPair generates a public-key/private-key pair,
* creating new key objects. */
CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session
* handle */
CK_MECHANISM_PTR pMechanism, /* key-gen
* mech. */
CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
* for pub.
* key */
CK_ULONG ulPublicKeyAttributeCount, /* # pub.
* attrs. */
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
* for priv.
* key */
CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
* attrs. */
CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
* key
* handle */
CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
* priv. key
* handle */
);
#endif
/* C_WrapKey wraps (i.e., encrypts) a key. */
CK_PKCS11_FUNCTION_INFO(C_WrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
CK_OBJECT_HANDLE hKey, /* key to be wrapped */
CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
);
#endif
/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
* key object. */
CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
CK_BYTE_PTR pWrappedKey, /* the wrapped key */
CK_ULONG ulWrappedKeyLen, /* wrapped key len */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* C_DeriveKey derives a key from a base key, creating a new key
* object. */
CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
CK_OBJECT_HANDLE hBaseKey, /* base key */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* Random number generation */
/* C_SeedRandom mixes additional seed material into the token's
* random number generator. */
CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSeed, /* the seed material */
CK_ULONG ulSeedLen /* length of seed material */
);
#endif
/* C_GenerateRandom generates random data. */
CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR RandomData, /* receives the random data */
CK_ULONG ulRandomLen /* # of bytes to generate */
);
#endif
/* Parallel function management */
/* C_GetFunctionStatus is a legacy function; it obtains an
* updated status of a function running in parallel with an
* application. */
CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CancelFunction is a legacy function; it cancels a function
* running in parallel. */
CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Functions added in for Cryptoki Version 2.01 or later */
/* C_WaitForSlotEvent waits for a slot event (token insertion,
* removal, etc.) to occur. */
CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
#ifdef CK_NEED_ARG_LIST
(
CK_FLAGS flags, /* blocking/nonblocking flag */
CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,473 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* pkcs11wrapper.h
* 18.05.2001
*
* declaration of all functions used by pkcs11wrapper.c
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
* @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
*/
#ifndef _PKCS11WRAPPER_H
#define _PKCS11WRAPPER_H 1
/* disable asserts in product mode */
#ifndef DEBUG
#ifndef NDEBUG
#define NDEBUG
#endif
#endif
/* extra PKCS#11 constants not in the standard include files */
#define CKA_NETSCAPE_BASE (0x80000000 + 0x4E534350)
#define CKA_NETSCAPE_TRUST_BASE (CKA_NETSCAPE_BASE + 0x2000)
#define CKA_NETSCAPE_TRUST_SERVER_AUTH (CKA_NETSCAPE_TRUST_BASE + 8)
#define CKA_NETSCAPE_TRUST_CLIENT_AUTH (CKA_NETSCAPE_TRUST_BASE + 9)
#define CKA_NETSCAPE_TRUST_CODE_SIGNING (CKA_NETSCAPE_TRUST_BASE + 10)
#define CKA_NETSCAPE_TRUST_EMAIL_PROTECTION (CKA_NETSCAPE_TRUST_BASE + 11)
/*
Define the PKCS#11 functions to include and exclude. Reduces the size
of the binary somewhat.
This list needs to be kept in sync with the mapfile and PKCS11.java
*/
#define P11_ENABLE_C_INITIALIZE
#define P11_ENABLE_C_FINALIZE
#define P11_ENABLE_C_GETINFO
#define P11_ENABLE_C_GETSLOTLIST
#define P11_ENABLE_C_GETSLOTINFO
#define P11_ENABLE_C_GETTOKENINFO
#define P11_ENABLE_C_GETMECHANISMLIST
#define P11_ENABLE_C_GETMECHANISMINFO
#undef P11_ENABLE_C_INITTOKEN
#undef P11_ENABLE_C_INITPIN
#undef P11_ENABLE_C_SETPIN
#define P11_ENABLE_C_OPENSESSION
#define P11_ENABLE_C_CLOSESESSION
#undef P11_ENABLE_C_CLOSEALLSESSIONS
#define P11_ENABLE_C_GETSESSIONINFO
#define P11_ENABLE_C_GETOPERATIONSTATE
#define P11_ENABLE_C_SETOPERATIONSTATE
#define P11_ENABLE_C_LOGIN
#define P11_ENABLE_C_LOGOUT
#define P11_ENABLE_C_CREATEOBJECT
#define P11_ENABLE_C_COPYOBJECT
#define P11_ENABLE_C_DESTROYOBJECT
#undef P11_ENABLE_C_GETOBJECTSIZE
#define P11_ENABLE_C_GETATTRIBUTEVALUE
#define P11_ENABLE_C_SETATTRIBUTEVALUE
#define P11_ENABLE_C_FINDOBJECTSINIT
#define P11_ENABLE_C_FINDOBJECTS
#define P11_ENABLE_C_FINDOBJECTSFINAL
#define P11_ENABLE_C_ENCRYPTINIT
#define P11_ENABLE_C_ENCRYPT
#define P11_ENABLE_C_ENCRYPTUPDATE
#define P11_ENABLE_C_ENCRYPTFINAL
#define P11_ENABLE_C_DECRYPTINIT
#define P11_ENABLE_C_DECRYPT
#define P11_ENABLE_C_DECRYPTUPDATE
#define P11_ENABLE_C_DECRYPTFINAL
#define P11_ENABLE_C_DIGESTINIT
#define P11_ENABLE_C_DIGEST
#define P11_ENABLE_C_DIGESTUPDATE
#define P11_ENABLE_C_DIGESTKEY
#define P11_ENABLE_C_DIGESTFINAL
#define P11_ENABLE_C_SIGNINIT
#define P11_ENABLE_C_SIGN
#define P11_ENABLE_C_SIGNUPDATE
#define P11_ENABLE_C_SIGNFINAL
#define P11_ENABLE_C_SIGNRECOVERINIT
#define P11_ENABLE_C_SIGNRECOVER
#define P11_ENABLE_C_VERIFYINIT
#define P11_ENABLE_C_VERIFY
#define P11_ENABLE_C_VERIFYUPDATE
#define P11_ENABLE_C_VERIFYFINAL
#define P11_ENABLE_C_VERIFYRECOVERINIT
#define P11_ENABLE_C_VERIFYRECOVER
#undef P11_ENABLE_C_DIGESTENCRYPTUPDATE
#undef P11_ENABLE_C_DECRYPTDIGESTUPDATE
#undef P11_ENABLE_C_SIGNENCRYPTUPDATE
#undef P11_ENABLE_C_DECRYPTVERIFYUPDATE
#define P11_ENABLE_C_GENERATEKEY
#define P11_ENABLE_C_GENERATEKEYPAIR
#define P11_ENABLE_C_WRAPKEY
#define P11_ENABLE_C_UNWRAPKEY
#define P11_ENABLE_C_DERIVEKEY
#define P11_ENABLE_C_SEEDRANDOM
#define P11_ENABLE_C_GENERATERANDOM
#undef P11_ENABLE_C_GETFUNCTIONSTATUS
#undef P11_ENABLE_C_CANCELFUNCTION
#undef P11_ENABLE_C_WAITFORSLOTEVENT
/* include the platform dependent part of the header */
#include "p11_md.h"
#include "pkcs11.h"
#include "pkcs-11v2-20a3.h"
#include <jni.h>
#include <jni_util.h>
#include <stdarg.h>
#define MAX_STACK_BUFFER_LEN (4 * 1024)
#define MAX_HEAP_BUFFER_LEN (64 * 1024)
#define MAX_DIGEST_LEN (64)
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#define ckBBoolToJBoolean(x) ((x == TRUE) ? JNI_TRUE : JNI_FALSE);
#define jBooleanToCKBBool(x) ((x == JNI_TRUE) ? TRUE : FALSE);
#define ckByteToJByte(x) ((jbyte) x)
#define jByteToCKByte(x) ((CK_BYTE) x)
#define ckLongToJLong(x) ((jlong) x)
#define jLongToCKLong(x) ((CK_LONG) x)
#define ckULongToJLong(x) ((jlong) x)
#define jLongToCKULong(x) ((CK_ULONG) x)
// For CK_UNAVAILABLE_INFORMATION, always return -1 to avoid 32/64 bit problems.
#define ckULongSpecialToJLong(x) (((x) == CK_UNAVAILABLE_INFORMATION) \
? (jlong)-1 : ((jlong) x))
#define ckCharToJChar(x) ((jchar) x)
#define jCharToCKChar(x) ((CK_CHAR) x)
#define ckUTF8CharToJChar(x) ((jchar) x)
#define jCharToCKUTF8Char(x) ((CK_UTF8CHAR) x)
#define ckFlageToJLong(x) ((jlong) x)
#define ckVoidPtrToJObject(x) ((jobject) x)
#define jObjectToCKVoidPtr(x) ((CK_VOID_PTR) x)
#define jIntToCKLong(x) ((CK_LONG) x)
#define jIntToCKULong(x) ((CK_ULONG) x)
#define ckLongToJInt(x) ((jint) x)
#define ckULongToJInt(x) ((jint) x)
#define ckULongToJSize(x) ((jsize) x)
#define unsignedIntToCKULong(x) ((CK_ULONG) x)
#ifdef P11_DEBUG
#define TRACE0(s) { printf(s); fflush(stdout); }
#define TRACE1(s, p1) { printf(s, p1); fflush(stdout); }
#define TRACE2(s, p1, p2) { printf(s, p1, p2); fflush(stdout); }
#define TRACE3(s, p1, p2, p3) { printf(s, p1, p2, p3); fflush(stdout); }
#else
#define TRACE0(s)
#define TRACE1(s, p1)
#define TRACE2(s, p1, p2)
#define TRACE3(s, p1, p2, p3)
#define TRACE_INTEND
#define TRACE_UNINTEND
#endif
/* debug output */
extern jboolean debug;
void printDebug(const char *format, ...);
#define CK_ASSERT_OK 0L
#define CLASS_INFO "sun/security/pkcs11/wrapper/CK_INFO"
#define CLASS_VERSION "sun/security/pkcs11/wrapper/CK_VERSION"
#define CLASS_SLOT_INFO "sun/security/pkcs11/wrapper/CK_SLOT_INFO"
#define CLASS_TOKEN_INFO "sun/security/pkcs11/wrapper/CK_TOKEN_INFO"
#define CLASS_MECHANISM "sun/security/pkcs11/wrapper/CK_MECHANISM"
#define CLASS_MECHANISM_INFO "sun/security/pkcs11/wrapper/CK_MECHANISM_INFO"
#define CLASS_SESSION_INFO "sun/security/pkcs11/wrapper/CK_SESSION_INFO"
#define CLASS_ATTRIBUTE "sun/security/pkcs11/wrapper/CK_ATTRIBUTE"
#define CLASS_DATE "sun/security/pkcs11/wrapper/CK_DATE"
#define CLASS_PKCS11EXCEPTION "sun/security/pkcs11/wrapper/PKCS11Exception"
#define CLASS_PKCS11RUNTIMEEXCEPTION "sun/security/pkcs11/wrapper/PKCS11RuntimeException"
#define CLASS_FILE_NOT_FOUND_EXCEPTION "java/io/FileNotFoundException"
#define CLASS_C_INITIALIZE_ARGS "sun/security/pkcs11/wrapper/CK_C_INITIALIZE_ARGS"
#define CLASS_CREATEMUTEX "sun/security/pkcs11/wrapper/CK_CREATEMUTEX"
#define CLASS_DESTROYMUTEX "sun/security/pkcs11/wrapper/CK_DESTROYMUTEX"
#define CLASS_LOCKMUTEX "sun/security/pkcs11/wrapper/CK_LOCKMUTEX"
#define CLASS_UNLOCKMUTEX "sun/security/pkcs11/wrapper/CK_UNLOCKMUTEX"
#define CLASS_NOTIFY "sun/security/pkcs11/wrapper/CK_NOTIFY"
/* mechanism parameter classes */
#define CLASS_RSA_PKCS_OAEP_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS"
#define CLASS_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_MAC_GENERAL_PARAMS"
#define CLASS_PBE_PARAMS "sun/security/pkcs11/wrapper/CK_PBE_PARAMS"
#define PBE_INIT_VECTOR_SIZE 8
#define CLASS_PKCS5_PBKD2_PARAMS "sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS"
#define CLASS_EXTRACT_PARAMS "sun/security/pkcs11/wrapper/CK_EXTRACT_PARAMS"
#define CLASS_RSA_PKCS_PSS_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS"
#define CLASS_ECDH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS"
#define CLASS_ECDH2_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH2_DERIVE_PARAMS"
#define CLASS_X9_42_DH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS"
#define CLASS_X9_42_DH2_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_X9_42_DH2_DERIVE_PARAMS"
/*
#define CLASS_KEA_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_KEA_DERIVE_PARAMS"
#define CLASS_RC2_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_PARAMS"
#define CLASS_RC2_CBC_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_CBC_PARAMS"
#define CLASS_RC2_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_MAC_GENERAL_PARAMS"
#define CLASS_RC5_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_PARAMS"
#define CLASS_RC5_CBC_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_CBC_PARAMS"
#define CLASS_RC5_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_MAC_GENERAL_PARAMS"
#define CLASS_SKIPJACK_PRIVATE_WRAP_PARAMS "sun/security/pkcs11/wrapper/CK_SKIPJACK_PRIVATE_WRAP_PARAMS"
#define CLASS_SKIPJACK_RELAYX_PARAMS "sun/security/pkcs11/wrapper/CK_SKIPJACK_RELAYX_PARAMS"
#define CLASS_KEY_WRAP_SET_OAEP_PARAMS "sun/security/pkcs11/wrapper/CK_KEY_WRAP_SET_OAEP_PARAMS"
#define CLASS_KEY_DERIVATION_STRING_DATA "sun/security/pkcs11/wrapper/CK_KEY_DERIVATION_STRING_DATA"
*/
#define CLASS_SSL3_RANDOM_DATA "sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA"
// CLASS_SSL3_RANDOM_DATA is used by CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS
#define CLASS_SSL3_KEY_MAT_OUT "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT"
// CLASS_SSL3_KEY_MAT_OUT is used by CLASS_SSL3_KEY_MAT_PARAMS
#define CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS"
#define CLASS_SSL3_KEY_MAT_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS"
#define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS"
#define CLASS_AES_CTR_PARAMS "sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS"
/* function to convert a PKCS#11 return value other than CK_OK into a Java Exception
* or to throw a PKCS11RuntimeException
*/
jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue);
void throwOutOfMemoryError(JNIEnv *env, const char *message);
void throwNullPointerException(JNIEnv *env, const char *message);
void throwIOException(JNIEnv *env, const char *message);
void throwPKCS11RuntimeException(JNIEnv *env, const char *message);
void throwDisconnectedRuntimeException(JNIEnv *env);
/* function to free CK_ATTRIBUTE array
*/
void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len);
/* funktions to convert Java arrays to a CK-type array and the array length */
void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckLength);
void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckLength);
void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckLength);
void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckLength);
void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckLength);
void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength);
void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jAArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength);
/*void jObjectArrayToCKVoidPtrArray(JNIEnv *env, const jobjectArray jArray, CK_VOID_PTR_PTR ckpArray, CK_ULONG_PTR ckpLength); */
/* funktions to convert a CK-type array and the array length to a Java array */
jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength);
jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength);
jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG length);
jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength);
/* funktions to convert a CK-type structure or a pointer to a CK-value to a Java object */
jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL* ckpValue);
jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue);
jobject ckDatePtrToJDateObject(JNIEnv *env, const CK_DATE *ckpValue);
jobject ckVersionPtrToJVersion(JNIEnv *env, const CK_VERSION_PTR ckpVersion);
jobject ckSessionInfoPtrToJSessionInfo(JNIEnv *env, const CK_SESSION_INFO_PTR ckpSessionInfo);
jobject ckAttributePtrToJAttribute(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute);
/* funktion to convert the CK-value used by the CK_ATTRIBUTE structure to a Java object */
jobject ckAttributeValueToJObject(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute);
/* funktions to convert a Java object to a CK-type structure or a pointer to a CK-value */
CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject);
CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject);
CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject);
CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject);
CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject);
CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion);
CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate);
CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute);
/*CK_MECHANISM jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism);*/
void jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism, CK_MECHANISM_PTR ckMechanismPtr);
/* funktions to convert Java objects used by the Mechanism and Attribute class to a CK-type structure */
void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *pLength);
void jMechanismParameterToCKMechanismParameter(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength);
/* functions to convert a specific Java mechanism parameter object to a CK-mechanism parameter structure */
CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam);
CK_KEA_DERIVE_PARAMS jKeaDeriveParamToCKKeaDeriveParam(JNIEnv *env, jobject jParam);
CK_RC2_CBC_PARAMS jRc2CbcParamToCKRc2CbcParam(JNIEnv *env, jobject jParam);
CK_RC2_MAC_GENERAL_PARAMS jRc2MacGeneralParamToCKRc2MacGeneralParam(JNIEnv *env, jobject jParam);
CK_RC5_PARAMS jRc5ParamToCKRc5Param(JNIEnv *env, jobject jParam);
CK_RC5_CBC_PARAMS jRc5CbcParamToCKRc5CbcParam(JNIEnv *env, jobject jParam);
CK_RC5_MAC_GENERAL_PARAMS jRc5MacGeneralParamToCKRc5MacGeneralParam(JNIEnv *env, jobject jParam);
CK_SKIPJACK_PRIVATE_WRAP_PARAMS jSkipjackPrivateWrapParamToCKSkipjackPrivateWrapParam(JNIEnv *env, jobject jParam);
CK_SKIPJACK_RELAYX_PARAMS jSkipjackRelayxParamToCKSkipjackRelayxParam(JNIEnv *env, jobject jParam);
CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam);
void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam);
CK_KEY_WRAP_SET_OAEP_PARAMS jKeyWrapSetOaepParamToCKKeyWrapSetOaepParam(JNIEnv *env, jobject jParam);
void copyBackSetUnwrappedKey(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam);
void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam);
void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam);
CK_RSA_PKCS_PSS_PARAMS jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam);
CK_ECDH1_DERIVE_PARAMS jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam);
CK_ECDH2_DERIVE_PARAMS jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam);
CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam);
CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam);
/* functions to convert the InitArgs object for calling the right Java mutex functions */
CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject pInitArgs);
#ifndef NO_CALLBACKS /* if the library should not make callbacks; e.g. no javai.lib or jvm.lib available */
CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex);
CK_RV callJDestroyMutex(CK_VOID_PTR pMutex);
CK_RV callJLockMutex(CK_VOID_PTR pMutex);
CK_RV callJUnlockMutex(CK_VOID_PTR pMutex);
#endif /* NO_CALLBACKS */
void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData);
ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation);
/* A structure to encapsulate the required data for a Notify callback */
struct NotifyEncapsulation {
/* The object that implements the CK_NOTIFY interface and which should be
* notified.
*/
jobject jNotifyObject;
/* The data object to pass back to the Notify object upon callback. */
jobject jApplicationData;
};
typedef struct NotifyEncapsulation NotifyEncapsulation;
/* The function for handling notify callbacks. */
CK_RV notifyCallback(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_NOTIFICATION event,
CK_VOID_PTR pApplication /* passed to C_OpenSession */
);
/* A node of the list of notify callbacks. To be able to free the resources after use. */
struct NotifyListNode {
/* The handle of the session this notify object is attached to*/
CK_SESSION_HANDLE hSession;
/* Reference to the Notify encapsulation object that was passed to C_OpenSession. */
NotifyEncapsulation *notifyEncapsulation;
/* Pointer to the next node in the list. */
struct NotifyListNode *next;
};
typedef struct NotifyListNode NotifyListNode;
void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation);
NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession);
NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env);
jobject createLockObject(JNIEnv *env);
void destroyLockObject(JNIEnv *env, jobject jLockObject);
extern jfieldID pNativeDataID;
extern jfieldID mech_mechanismID;
extern jfieldID mech_pParameterID;
extern jclass jByteArrayClass;
extern jclass jLongClass;
#ifndef NO_CALLBACKS
extern NotifyListNode *notifyListHead;
extern jobject notifyListLock;
extern jobject jInitArgsObject;
extern CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs;
#endif /* NO_CALLBACKS */
#ifdef P11_MEMORYDEBUG
#include <stdlib.h>
/* Simple malloc/free dumper */
void *p11malloc(size_t c, char *file, int line);
void p11free(void *p, char *file, int line);
/* Use THIS_FILE when it is available. */
#ifndef THIS_FILE
#define THIS_FILE __FILE__
#endif
#define malloc(c) (p11malloc((c), THIS_FILE, __LINE__))
#define free(c) (p11free((c), THIS_FILE, __LINE__))
#endif
#endif /* _PKCS11WRAPPER_H */

View file

@ -0,0 +1,23 @@
#
# Configuration file to allow the SunPKCS11 provider to utilize
# the Solaris Cryptographic Framework, if it is available
#
name = Solaris
description = SunPKCS11 accessing Solaris Cryptographic Framework
library = /usr/lib/$ISA/libpkcs11.so
handleStartupErrors = ignoreAll
# Use the X9.63 encoding for EC points (do not wrap in an ASN.1 OctetString).
useEcX963Encoding = true
attributes = compatibility
disabledMechanisms = {
CKM_DSA_KEY_PAIR_GEN
SecureRandom
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <jni_util.h>
#include "j2secmod.h"
#include "pkcs11wrapper.h"
void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
void *hModule = (void*)jlong_to_ptr(jHandle);
void *fAddress = dlsym(hModule, functionName);
if (fAddress == NULL) {
char errorMessage[256];
snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName);
throwNullPointerException(env, errorMessage);
return NULL;
}
return fAddress;
}
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
(JNIEnv *env, jclass thisClass, jstring jLibName)
{
void *hModule;
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
if (libName == NULL) {
return 0L;
}
// look up existing handle only, do not load
#if defined(AIX)
hModule = dlopen(libName, RTLD_LAZY);
#else
hModule = dlopen(libName, RTLD_NOLOAD);
#endif
dprintf2("-handle for %s: %u\n", libName, hModule);
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
return ptr_to_jlong(hModule);
}
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
(JNIEnv *env, jclass thisClass, jstring jLibName)
{
void *hModule;
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
if (libName == NULL) {
return 0L;
}
dprintf1("-lib %s\n", libName);
hModule = dlopen(libName, RTLD_LAZY);
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
dprintf2("-handle: %u (0X%X)\n", hModule, hModule);
if (hModule == NULL) {
throwIOException(env, dlerror());
return 0;
}
return ptr_to_jlong(hModule);
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2005, 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.
*/
// in nss.h:
// extern PRBool NSS_VersionCheck(const char *importedVersion);
// extern SECStatus NSS_Initialize(const char *configdir,
// const char *certPrefix, const char *keyPrefix,
// const char *secmodName, PRUint32 flags);
typedef int (*FPTR_VersionCheck)(const char *importedVersion);
typedef int (*FPTR_Initialize)(const char *configdir,
const char *certPrefix, const char *keyPrefix,
const char *secmodName, unsigned int flags);
// in secmod.h
//extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
// PRBool recurse);
//char **SECMOD_GetModuleSpecList(SECMODModule *module);
//extern SECMODModuleList *SECMOD_GetDBModuleList(void);
typedef void *(*FPTR_LoadModule)(char *moduleSpec, void *parent, int recurse);
typedef char **(*FPTR_GetModuleSpecList)(void *module);
typedef void *(*FPTR_GetDBModuleList)(void);

View file

@ -0,0 +1,183 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* pkcs11wrapper.c
* 18.05.2001
*
* This module contains the native functions of the Java to PKCS#11 interface
* which are platform dependent. This includes loading a dynamic link libary,
* retrieving the function list and unloading the dynamic link library.
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <dlfcn.h>
#include <jni.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: connect
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
(JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
{
void *hModule;
char *error;
CK_C_GetFunctionList C_GetFunctionList=NULL;
CK_RV rv;
ModuleData *moduleData;
jobject globalPKCS11ImplementationReference;
char *systemErrorMessage;
char *exceptionMessage;
const char *getFunctionListStr;
const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
if (libraryNameStr == NULL) {
return;
}
TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
/*
* Load the PKCS #11 DLL
*/
dlerror(); /* clear any old error message not fetched */
#ifdef DEBUG
hModule = dlopen(libraryNameStr, RTLD_NOW);
#else
hModule = dlopen(libraryNameStr, RTLD_LAZY);
#endif /* DEBUG */
if (hModule == NULL) {
systemErrorMessage = dlerror();
exceptionMessage = (char *) malloc(sizeof(char) * (strlen(systemErrorMessage) + strlen(libraryNameStr) + 1));
if (exceptionMessage == NULL) {
throwOutOfMemoryError(env, 0);
return;
}
strcpy(exceptionMessage, systemErrorMessage);
strcat(exceptionMessage, libraryNameStr);
throwIOException(env, exceptionMessage);
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
free(exceptionMessage);
return;
}
/*
* Get function pointer to C_GetFunctionList
*/
dlerror(); /* clear any old error message not fetched */
// with the old JAR file jGetFunctionList is null, temporarily check for that
if (jGetFunctionList != NULL) {
getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
if (getFunctionListStr == NULL) {
return;
}
C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr);
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
}
if (C_GetFunctionList == NULL) {
throwIOException(env, "ERROR: C_GetFunctionList == NULL");
return;
} else if ( (systemErrorMessage = dlerror()) != NULL ){
throwIOException(env, systemErrorMessage);
return;
}
/*
* Get function pointers to all PKCS #11 functions
*/
moduleData = (ModuleData *) malloc(sizeof(ModuleData));
if (moduleData == NULL) {
dlclose(hModule);
throwOutOfMemoryError(env, 0);
return;
}
moduleData->hModule = hModule;
moduleData->applicationMutexHandler = NULL;
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
TRACE0("FINISHED\n");
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: disconnect
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_disconnect
(JNIEnv *env, jobject obj)
{
ModuleData *moduleData;
TRACE0("DEBUG: disconnecting module...");
moduleData = removeModuleEntry(env, obj);
if (moduleData != NULL) {
dlclose(moduleData->hModule);
}
free(moduleData);
TRACE0("FINISHED\n");
}

View file

@ -0,0 +1,90 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* pkcs11wrapper.h
* 18.05.2001
*
* declaration of all functions used by pkcs11wrapper.c
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
/* defines for UNIX platforms *************************************************/
#ifndef _P11_MD_H
#define _P11_MD_H 1
#define CK_PTR *
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
#include "pkcs11.h"
#include "jni.h"
/* A data structure to hold required information about a PKCS#11 module. */
struct ModuleData {
/* the module (DLL or shared library) handle */
void *hModule;
/* The pointer to the PKCS#11 functions of this module. */
CK_FUNCTION_LIST_PTR ckFunctionListPtr;
/* Reference to the object to use for mutex handling. NULL, if not used. */
jobject applicationMutexHandler;
};
typedef struct ModuleData ModuleData;
#endif /* _P11_MD_H */

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jni_util.h>
#include "j2secmod.h"
extern void throwNullPointerException(JNIEnv *env, const char *message);
extern void throwIOException(JNIEnv *env, const char *message);
void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
HINSTANCE hModule = (HINSTANCE)jHandle;
void *fAddress = GetProcAddress(hModule, functionName);
if (fAddress == NULL) {
char errorMessage[256];
_snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName);
throwNullPointerException(env, errorMessage);
return NULL;
}
return fAddress;
}
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
(JNIEnv *env, jclass thisClass, jstring jLibName)
{
const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
HMODULE hModule = GetModuleHandle(libName);
dprintf2("-handle for %s: %d\n", libName, hModule);
(*env)->ReleaseStringUTFChars(env, jLibName, libName);
return (jlong)hModule;
}
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
(JNIEnv *env, jclass thisClass, jstring jName)
{
HINSTANCE hModule;
LPVOID lpMsgBuf;
const char *libName = (*env)->GetStringUTFChars(env, jName, NULL);
dprintf1("-lib %s\n", libName);
hModule = LoadLibrary(libName);
(*env)->ReleaseStringUTFChars(env, jName, libName);
if (hModule == NULL) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, /* Default language */
(LPTSTR) &lpMsgBuf,
0,
NULL
);
dprintf1("-error: %s\n", lpMsgBuf);
throwIOException(env, (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
return 0;
}
dprintf2("-handle: %d (0X%X)\n", hModule, hModule);
return (jlong)hModule;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2005, 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.
*/
#include <windows.h>
// in nss.h:
// extern PRBool NSS_VersionCheck(const char *importedVersion);
// extern SECStatus NSS_Initialize(const char *configdir,
// const char *certPrefix, const char *keyPrefix,
// const char *secmodName, PRUint32 flags);
typedef int __declspec(dllimport) (*FPTR_VersionCheck)(const char *importedVersion);
typedef int __declspec(dllimport) (*FPTR_Initialize)(const char *configdir,
const char *certPrefix, const char *keyPrefix,
const char *secmodName, unsigned int flags);
// in secmod.h
//extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
// PRBool recurse);
//char **SECMOD_GetModuleSpecList(SECMODModule *module);
//extern SECMODModuleList *SECMOD_GetDBModuleList(void);
typedef void __declspec(dllimport) *(*FPTR_LoadModule)(char *moduleSpec, void *parent, int recurse);
typedef char __declspec(dllimport) **(*FPTR_GetModuleSpecList)(void *module);
typedef void __declspec(dllimport) *(*FPTR_GetDBModuleList)(void);

View file

@ -0,0 +1,177 @@
/*
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* pkcs11wrapper.c
* 18.05.2001
*
* This module contains the native functions of the Java to PKCS#11 interface
* which are platform dependent. This includes loading a dynamic link libary,
* retrieving the function list and unloading the dynamic link library.
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
#include "pkcs11wrapper.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <windows.h>
#include <jni.h>
#include "sun_security_pkcs11_wrapper_PKCS11.h"
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: connect
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
(JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
{
HINSTANCE hModule;
CK_C_GetFunctionList C_GetFunctionList;
CK_RV rv;
ModuleData *moduleData;
jobject globalPKCS11ImplementationReference;
LPVOID lpMsgBuf;
char *exceptionMessage;
const char *getFunctionListStr;
const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
/*
* Load the PKCS #11 DLL
*/
hModule = LoadLibrary(libraryNameStr);
if (hModule == NULL) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, /* Default language */
(LPTSTR) &lpMsgBuf,
0,
NULL
);
exceptionMessage = (char *) malloc(sizeof(char) * (strlen((LPTSTR) lpMsgBuf) + strlen(libraryNameStr) + 1));
strcpy(exceptionMessage, (LPTSTR) lpMsgBuf);
strcat(exceptionMessage, libraryNameStr);
throwIOException(env, (LPTSTR) exceptionMessage);
/* Free the buffer. */
free(exceptionMessage);
LocalFree(lpMsgBuf);
return;
}
/*
* Get function pointer to C_GetFunctionList
*/
getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule, getFunctionListStr);
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
if (C_GetFunctionList == NULL) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0, /* Default language */
(LPTSTR) &lpMsgBuf,
0,
NULL
);
throwIOException(env, (LPTSTR) lpMsgBuf);
/* Free the buffer. */
LocalFree( lpMsgBuf );
return;
}
/*
* Get function pointers to all PKCS #11 functions
*/
moduleData = (ModuleData *) malloc(sizeof(ModuleData));
moduleData->hModule = hModule;
moduleData->applicationMutexHandler = NULL;
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
TRACE0("FINISHED\n");
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
}
/*
* Class: sun_security_pkcs11_wrapper_PKCS11
* Method: disconnect
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_disconnect
(JNIEnv *env, jobject obj)
{
ModuleData *moduleData;
TRACE0("DEBUG: disconnecting module...");
moduleData = removeModuleEntry(env, obj);
if (moduleData != NULL) {
FreeLibrary(moduleData->hModule);
}
free(moduleData);
TRACE0("FINISHED\n");
}

View file

@ -0,0 +1,98 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The end-user documentation included with the redistribution, if any, must
* include the following acknowledgment:
*
* "This product includes software developed by IAIK of Graz University of
* Technology."
*
* Alternately, this acknowledgment may appear in the software itself, if
* and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Graz University of Technology" and "IAIK of Graz University of
* Technology" must not be used to endorse or promote products derived from
* this software without prior written permission.
*
* 5. Products derived from this software may not be called
* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
* written permission of Graz University of Technology.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* platoform.h
* 10.12.2001
*
* declaration of all platform dependent functions used by pkcs11wrapper.c
*
* @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
*/
/* defines for WIN32 platform *************************************************/
#include <windows.h>
/* statement according to PKCS11 docu */
#pragma pack(push, cryptoki, 1)
/* definitions according to PKCS#11 docu for Win32 environment */
#define CK_PTR *
#define CK_DEFINE_FUNCTION(returnType, name) returnType __declspec(dllexport) name
#define CK_DECLARE_FUNCTION(returnType, name) returnType __declspec(dllimport) name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType __declspec(dllimport) (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
#ifndef NULL_PTR
#define NULL_PTR 0
#endif /* NULL_PTR */
/* to avoid clash with Win32 #define */
#ifdef CreateMutex
#undef CreateMutex
#endif /* CreateMutex */
#include "pkcs11.h"
/* statement according to PKCS11 docu */
#pragma pack(pop, cryptoki)
#include "jni.h"
/* A data structure to hold required information about a PKCS#11 module. */
struct ModuleData {
HINSTANCE hModule;
/* The pointer to the PKCS#11 functions of this module. */
CK_FUNCTION_LIST_PTR ckFunctionListPtr;
/* Reference to the object to use for mutex handling. NULL, if not used. */
jobject applicationMutexHandler;
};
typedef struct ModuleData ModuleData;