< 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 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 }
< prev index next >