28 import java.io.*;
29 import java.lang.ref.*;
30 import java.math.BigInteger;
31 import java.util.*;
32
33 import java.security.*;
34 import java.security.interfaces.*;
35 import java.security.spec.*;
36
37 import javax.crypto.*;
38 import javax.crypto.interfaces.*;
39 import javax.crypto.spec.*;
40
41 import sun.security.rsa.RSAPublicKeyImpl;
42
43 import sun.security.internal.interfaces.TlsMasterSecret;
44
45 import sun.security.pkcs11.wrapper.*;
46 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
47
48 import sun.security.util.DerValue;
49 import sun.security.util.Length;
50 import sun.security.util.ECUtil;
51
52 /**
53 * Key implementation classes.
54 *
55 * In PKCS#11, the components of private and secret keys may or may not
56 * be accessible. If they are, we use the algorithm specific key classes
57 * (e.g. DSAPrivateKey) for compatibility with existing applications.
58 * If the components are not accessible, we use a generic class that
59 * only implements PrivateKey (or SecretKey). Whether the components of a
60 * key are extractable is automatically determined when the key object is
61 * created.
62 *
63 * @author Andreas Sterbenz
64 * @since 1.5
65 */
66 abstract class P11Key implements Key, Length {
67
1093 }
1094 }
1095
1096 /*
1097 * NOTE: Must use PhantomReference here and not WeakReference
1098 * otherwise the key maybe cleared before other objects which
1099 * still use these keys during finalization such as SSLSocket.
1100 */
1101 final class SessionKeyRef extends PhantomReference<P11Key>
1102 implements Comparable<SessionKeyRef> {
1103 private static ReferenceQueue<P11Key> refQueue =
1104 new ReferenceQueue<P11Key>();
1105 private static Set<SessionKeyRef> refList =
1106 Collections.synchronizedSortedSet(new TreeSet<SessionKeyRef>());
1107
1108 static ReferenceQueue<P11Key> referenceQueue() {
1109 return refQueue;
1110 }
1111
1112 private static void drainRefQueueBounded() {
1113 while (true) {
1114 SessionKeyRef next = (SessionKeyRef) refQueue.poll();
1115 if (next == null) break;
1116 next.dispose();
1117 }
1118 }
1119
1120 // handle to the native key
1121 private long keyID;
1122 private Session session;
1123
1124 SessionKeyRef(P11Key key , long keyID, Session session) {
1125 super(key, refQueue);
1126 this.keyID = keyID;
1127 this.session = session;
1128 this.session.addObject();
1129 refList.add(this);
1130 // TBD: run at some interval and not every time?
1131 drainRefQueueBounded();
1132 }
1133
1134 private void dispose() {
1135 refList.remove(this);
1136 if (session.token.isValid()) {
1137 Session newSession = null;
1138 try {
1139 newSession = session.token.getOpSession();
1140 session.token.p11.C_DestroyObject(newSession.id(), keyID);
1141 } catch (PKCS11Exception e) {
1142 // ignore
1143 } finally {
1144 this.clear();
1145 session.token.releaseSession(newSession);
1146 session.removeObject();
1147 }
1148 }
1149 }
1150
1151 public int compareTo(SessionKeyRef other) {
1152 if (this.keyID == other.keyID) {
1153 return 0;
1154 } else {
1155 return (this.keyID < other.keyID) ? -1 : 1;
1156 }
1157 }
1158 }
|
28 import java.io.*;
29 import java.lang.ref.*;
30 import java.math.BigInteger;
31 import java.util.*;
32
33 import java.security.*;
34 import java.security.interfaces.*;
35 import java.security.spec.*;
36
37 import javax.crypto.*;
38 import javax.crypto.interfaces.*;
39 import javax.crypto.spec.*;
40
41 import sun.security.rsa.RSAPublicKeyImpl;
42
43 import sun.security.internal.interfaces.TlsMasterSecret;
44
45 import sun.security.pkcs11.wrapper.*;
46 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
47
48 import sun.security.util.Debug;
49 import sun.security.util.DerValue;
50 import sun.security.util.Length;
51 import sun.security.util.ECUtil;
52
53 /**
54 * Key implementation classes.
55 *
56 * In PKCS#11, the components of private and secret keys may or may not
57 * be accessible. If they are, we use the algorithm specific key classes
58 * (e.g. DSAPrivateKey) for compatibility with existing applications.
59 * If the components are not accessible, we use a generic class that
60 * only implements PrivateKey (or SecretKey). Whether the components of a
61 * key are extractable is automatically determined when the key object is
62 * created.
63 *
64 * @author Andreas Sterbenz
65 * @since 1.5
66 */
67 abstract class P11Key implements Key, Length {
68
1094 }
1095 }
1096
1097 /*
1098 * NOTE: Must use PhantomReference here and not WeakReference
1099 * otherwise the key maybe cleared before other objects which
1100 * still use these keys during finalization such as SSLSocket.
1101 */
1102 final class SessionKeyRef extends PhantomReference<P11Key>
1103 implements Comparable<SessionKeyRef> {
1104 private static ReferenceQueue<P11Key> refQueue =
1105 new ReferenceQueue<P11Key>();
1106 private static Set<SessionKeyRef> refList =
1107 Collections.synchronizedSortedSet(new TreeSet<SessionKeyRef>());
1108
1109 static ReferenceQueue<P11Key> referenceQueue() {
1110 return refQueue;
1111 }
1112
1113 private static void drainRefQueueBounded() {
1114 Session session = null;
1115 Token token = null;
1116 while (true) {
1117 SessionKeyRef next = (SessionKeyRef) refQueue.poll();
1118 if (next == null) {
1119 break;
1120 }
1121 try {
1122 // If this key's token is the same as the previous key, the
1123 // same session can be used for C_DestroyObject.
1124 if (next.session.token != token) {
1125 // If we have a previous token and session, release the session
1126 if (token != null && session != null)
1127 token.releaseSession(session);
1128 token = next.session.token;
1129 session = token.getOpSession();
1130 }
1131 next.dispose(session);
1132 } catch (PKCS11Exception e) {
1133 // ignore
1134 }
1135 }
1136 }
1137
1138 // handle to the native key
1139 private long keyID;
1140 private Session session;
1141
1142 SessionKeyRef(P11Key key , long keyID, Session session) {
1143 super(key, refQueue);
1144 this.keyID = keyID;
1145 this.session = session;
1146 this.session.addObject();
1147 refList.add(this);
1148 drainRefQueueBounded();
1149 }
1150
1151 private void dispose(Session s) {
1152 try {
1153 session.token.p11.C_DestroyObject(s.id(), keyID);
1154 } catch (PKCS11Exception e) {
1155 // ignore
1156 } finally {
1157 dispose();
1158 }
1159
1160 }
1161
1162 private void dispose() {
1163 refList.remove(this);
1164 this.clear();
1165 session.removeObject();
1166 }
1167
1168 public int compareTo(SessionKeyRef other) {
1169 if (this.keyID == other.keyID) {
1170 return 0;
1171 } else {
1172 return (this.keyID < other.keyID) ? -1 : 1;
1173 }
1174 }
1175 }
|