< prev index next >
src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java
Print this page
@@ -23,11 +23,10 @@
* questions.
*/
package sun.security.pkcs11;
-import java.util.*;
import java.nio.ByteBuffer;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
@@ -52,31 +51,16 @@
* @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;
@@ -85,22 +69,21 @@
private P11Key p11Key;
// associated session, if any
private Session session;
- // state, one of S_* above
- private int state;
+ // initialization status
+ private boolean initialized;
// 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;
@@ -129,101 +112,105 @@
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();
+ // reset the states to the pre-initialized values
+ private void reset(boolean doCancel) {
+ if (!initialized) {
+ return;
+ }
+ initialized = false;
+ try {
+ if (session == null) {
+ return;
+ }
+ if (doCancel && token.explicitCancel) {
+ cancelOperation();
+ }
+ } finally {
+ p11Key.decNativeKeyRef();
+ session = token.releaseSession(session);
}
}
private void cancelOperation() {
token.ensureValid();
- if (state == S_UNINIT) {
- return;
- }
- state = S_UNINIT;
- if ((session == null) || (token.explicitCancel == false)) {
+ if (session.hasObjects() == false) {
+ session = token.killSession(session);
return;
- }
+ } else {
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) {
+ private void ensureInitialized() throws PKCS11Exception {
+ if (initialized) {
return;
}
+ if (p11Key == null) {
+ throw new ProviderException(
+ "Operation cannot be performed without calling engineInit first");
+ }
+ token.ensureValid();
+ p11Key.incNativeKeyRef();
+ try {
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;
+ } catch (Throwable t) {
+ p11Key.decNativeKeyRef();
+ session = token.releaseSession(session);
+ throw t;
}
+ initialized = true;
}
// 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);
- }
+ reset(true);
}
// see JCE spec
protected void engineInit(Key key, AlgorithmParameterSpec params)
throws InvalidKeyException, InvalidAlgorithmParameterException {
if (params != null) {
throw new InvalidAlgorithmParameterException
("Parameters not supported");
}
- cancelOperation();
+ reset(true);
p11Key = P11SecretKeyFactory.convertKey(token, key, algorithm);
try {
- initialize();
+ ensureInitialized();
} 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;
+ return token.p11.C_SignFinal(session.id(), 0);
} catch (PKCS11Exception e) {
+ reset(true);
throw new ProviderException("doFinal() failed", e);
} finally {
- session = token.releaseSession(session);
+ reset(false);
}
}
// see JCE spec
protected void engineUpdate(byte input) {
@@ -237,11 +224,10 @@
// 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);
}
}
@@ -259,11 +245,10 @@
}
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);
}
}
}
< prev index next >