< prev index next >

src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java

Print this page




  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 sess = null;
1115         Token tkn = null;
1116         while (true) {
1117             SessionKeyRef next = (SessionKeyRef) refQueue.poll();
1118             if (next == null) {
1119                 break;
1120             }
1121 
1122             // If the token is still valid, try to remove the object
1123             if (next.session.token.isValid()) {
1124                 // If this key's token is the same as the previous key, the
1125                 // same session can be used for C_DestroyObject.
1126                 try {
1127                     if (next.session.token != tkn || sess == null) {
1128                         // Release session if not using previous token
1129                         if (tkn != null && sess != null) {
1130                             tkn.releaseSession(sess);
1131                             sess = null;
1132                         }
1133 
1134                         tkn = next.session.token;
1135                         sess = tkn.getOpSession();
1136                     }
1137 
1138                     next.disposeNative(sess);
1139                 } catch (PKCS11Exception e) {
1140                     // ignore
1141                 }
1142             }
1143             // Regardless of native results, dispose of java references
1144             next.dispose();
1145         }
1146 
1147         if (tkn != null && sess != null) {
1148             tkn.releaseSession(sess);
1149         }
1150     }
1151 
1152     // handle to the native key
1153     private long keyID;
1154     private Session session;
1155 
1156     SessionKeyRef(P11Key key , long keyID, Session session) {
1157         super(key, refQueue);
1158         this.keyID = keyID;
1159         this.session = session;
1160         this.session.addObject();
1161         refList.add(this);

1162         drainRefQueueBounded();
1163     }
1164 
1165     private void disposeNative(Session s) throws PKCS11Exception {
1166         session.token.p11.C_DestroyObject(s.id(), keyID);
1167     }
1168 
1169     private void dispose() {
1170         refList.remove(this);








1171         this.clear();

1172         session.removeObject();


1173     }
1174 
1175     public int compareTo(SessionKeyRef other) {
1176         if (this.keyID == other.keyID) {
1177             return 0;
1178         } else {
1179             return (this.keyID < other.keyID) ? -1 : 1;
1180         }
1181     }
1182 }
< prev index next >