--- a/jdk/src/share/classes/sun/security/pkcs11/KeyCache.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/pkcs11/KeyCache.java Wed Oct 19 10:16:22 2011 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -48,7 +48,7 @@
*/
final class KeyCache {
- private final Cache strongCache;
+ private final Cache<IdentityWrapper, P11Key> strongCache;
private WeakReference<Map<Key,P11Key>> cacheReference;
@@ -77,7 +77,7 @@
}
synchronized P11Key get(Key key) {
- P11Key p11Key = (P11Key)strongCache.get(new IdentityWrapper(key));
+ P11Key p11Key = strongCache.get(new IdentityWrapper(key));
if (p11Key != null) {
return p11Key;
}
@@ -94,8 +94,8 @@
Map<Key,P11Key> map =
(cacheReference == null) ? null : cacheReference.get();
if (map == null) {
- map = new IdentityHashMap<Key,P11Key>();
- cacheReference = new WeakReference<Map<Key,P11Key>>(map);
+ map = new IdentityHashMap<>();
+ cacheReference = new WeakReference<>(map);
}
map.put(key, p11Key);
}
--- a/jdk/src/share/classes/sun/security/provider/X509Factory.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/provider/X509Factory.java Wed Oct 19 10:16:22 2011 -0400
@@ -64,8 +64,10 @@
private static final int ENC_MAX_LENGTH = 4096 * 1024; // 4 MB MAX
- private static final Cache certCache = Cache.newSoftMemoryCache(750);
- private static final Cache crlCache = Cache.newSoftMemoryCache(750);
+ private static final Cache<Object, X509CertImpl> certCache
+ = Cache.newSoftMemoryCache(750);
+ private static final Cache<Object, X509CRLImpl> crlCache
+ = Cache.newSoftMemoryCache(750);
/**
* Generates an X.509 certificate object and initializes it with
@@ -90,7 +92,7 @@
try {
byte[] encoding = readOneBlock(is);
if (encoding != null) {
- X509CertImpl cert = (X509CertImpl)getFromCache(certCache, encoding);
+ X509CertImpl cert = getFromCache(certCache, encoding);
if (cert != null) {
return cert;
}
@@ -151,7 +153,7 @@
} else {
encoding = c.getEncoded();
}
- X509CertImpl newC = (X509CertImpl)getFromCache(certCache, encoding);
+ X509CertImpl newC = getFromCache(certCache, encoding);
if (newC != null) {
return newC;
}
@@ -181,7 +183,7 @@
} else {
encoding = c.getEncoded();
}
- X509CRLImpl newC = (X509CRLImpl)getFromCache(crlCache, encoding);
+ X509CRLImpl newC = getFromCache(crlCache, encoding);
if (newC != null) {
return newC;
}
@@ -198,18 +200,17 @@
/**
* Get the X509CertImpl or X509CRLImpl from the cache.
*/
- private static synchronized Object getFromCache(Cache cache,
+ private static synchronized <K,V> V getFromCache(Cache<K,V> cache,
byte[] encoding) {
Object key = new Cache.EqualByteArray(encoding);
- Object value = cache.get(key);
- return value;
+ return cache.get(key);
}
/**
* Add the X509CertImpl or X509CRLImpl to the cache.
*/
- private static synchronized void addToCache(Cache cache, byte[] encoding,
- Object value) {
+ private static synchronized <V> void addToCache(Cache<Object, V> cache,
+ byte[] encoding, V value) {
if (encoding.length > ENC_MAX_LENGTH) {
return;
}
@@ -361,7 +362,7 @@
try {
byte[] encoding = readOneBlock(is);
if (encoding != null) {
- X509CRLImpl crl = (X509CRLImpl)getFromCache(crlCache, encoding);
+ X509CRLImpl crl = getFromCache(crlCache, encoding);
if (crl != null) {
return crl;
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/CertStoreHelper.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CertStoreHelper.java Wed Oct 19 10:16:22 2011 -0400
@@ -59,12 +59,13 @@
"SSLServer",
"sun.security.provider.certpath.ssl.SSLServerCertStoreHelper");
};
- private static Cache cache = Cache.newSoftMemoryCache(NUM_TYPES);
+ private static Cache<String, CertStoreHelper> cache
+ = Cache.newSoftMemoryCache(NUM_TYPES);
public static CertStoreHelper getInstance(final String type)
throws NoSuchAlgorithmException
{
- CertStoreHelper helper = (CertStoreHelper)cache.get(type);
+ CertStoreHelper helper = cache.get(type);
if (helper != null) {
return helper;
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java Wed Oct 19 10:16:22 2011 -0400
@@ -100,8 +100,7 @@
private final CertificateFactory factory;
// cached Collection of X509Certificates (may be empty, never null)
- private Collection<X509Certificate> certs =
- Collections.<X509Certificate>emptySet();
+ private Collection<X509Certificate> certs = Collections.emptySet();
// cached X509CRL (may be null)
private X509CRL crl;
@@ -157,14 +156,14 @@
* Returns a URI CertStore. This method consults a cache of
* CertStores (shared per JVM) using the URI as a key.
*/
- private static final Cache certStoreCache =
- Cache.newSoftMemoryCache(CACHE_SIZE);
+ private static final Cache<URICertStoreParameters, CertStore>
+ certStoreCache = Cache.newSoftMemoryCache(CACHE_SIZE);
static synchronized CertStore getInstance(URICertStoreParameters params)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
if (debug != null) {
debug.println("CertStore URI:" + params.uri);
}
- CertStore ucs = (CertStore) certStoreCache.get(params);
+ CertStore ucs = certStoreCache.get(params);
if (ucs == null) {
ucs = new UCS(new URICertStore(params), null, "URI", params);
certStoreCache.put(params, ucs);
@@ -287,7 +286,7 @@
}
// exception, forget previous values
lastModified = 0;
- certs = Collections.<X509Certificate>emptySet();
+ certs = Collections.emptySet();
return certs;
}
@@ -394,7 +393,7 @@
// exception, forget previous values
lastModified = 0;
crl = null;
- return Collections.<X509CRL>emptyList();
+ return Collections.emptyList();
}
/**
@@ -404,9 +403,9 @@
private static Collection<X509CRL> getMatchingCRLs
(X509CRL crl, CRLSelector selector) {
if (selector == null || (crl != null && selector.match(crl))) {
- return Collections.<X509CRL>singletonList(crl);
+ return Collections.singletonList(crl);
} else {
- return Collections.<X509CRL>emptyList();
+ return Collections.emptyList();
}
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/X509CertificatePair.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/provider/certpath/X509CertificatePair.java Wed Oct 19 10:16:22 2011 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -79,7 +79,8 @@
private X509Certificate reverse;
private byte[] encoded;
- private static final Cache cache = Cache.newSoftMemoryCache(750);
+ private static final Cache<Object, X509CertificatePair> cache
+ = Cache.newSoftMemoryCache(750);
/**
* Creates an empty instance of X509CertificatePair.
@@ -114,7 +115,7 @@
*
* For internal use only, external code should use generateCertificatePair.
*/
- private X509CertificatePair(byte[] encoded)throws CertificateException {
+ private X509CertificatePair(byte[] encoded) throws CertificateException {
try {
parse(new DerValue(encoded));
this.encoded = encoded;
@@ -138,7 +139,7 @@
public static synchronized X509CertificatePair generateCertificatePair
(byte[] encoded) throws CertificateException {
Object key = new Cache.EqualByteArray(encoded);
- X509CertificatePair pair = (X509CertificatePair)cache.get(key);
+ X509CertificatePair pair = cache.get(key);
if (pair != null) {
return pair;
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java Wed Oct 19 10:16:22 2011 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -160,7 +160,7 @@
*/
private boolean prefetchCRLs = false;
- private final Cache valueCache;
+ private final Cache<String, byte[][]> valueCache;
private int cacheHits = 0;
private int cacheMisses = 0;
@@ -207,10 +207,11 @@
* Returns an LDAP CertStore. This method consults a cache of
* CertStores (shared per JVM) using the LDAP server/port as a key.
*/
- private static final Cache certStoreCache = Cache.newSoftMemoryCache(185);
+ private static final Cache<LDAPCertStoreParameters, CertStore>
+ certStoreCache = Cache.newSoftMemoryCache(185);
static synchronized CertStore getInstance(LDAPCertStoreParameters params)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
- CertStore lcs = (CertStore) certStoreCache.get(params);
+ CertStore lcs = certStoreCache.get(params);
if (lcs == null) {
lcs = CertStore.getInstance("LDAP", params);
certStoreCache.put(params, lcs);
@@ -232,7 +233,7 @@
private void createInitialDirContext(String server, int port)
throws InvalidAlgorithmParameterException {
String url = "ldap://" + server + ":" + port;
- Hashtable<String,Object> env = new Hashtable<String,Object>();
+ Hashtable<String,Object> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, url);
@@ -283,7 +284,7 @@
LDAPRequest(String name) {
this.name = name;
- requestedAttributes = new ArrayList<String>(5);
+ requestedAttributes = new ArrayList<>(5);
}
String getName() {
@@ -311,7 +312,7 @@
+ cacheMisses);
}
String cacheKey = name + "|" + attrId;
- byte[][] values = (byte[][])valueCache.get(cacheKey);
+ byte[][] values = valueCache.get(cacheKey);
if (values != null) {
cacheHits++;
return values;
@@ -347,7 +348,7 @@
System.out.println("LDAP requests: " + requests);
}
}
- valueMap = new HashMap<String, byte[][]>(8);
+ valueMap = new HashMap<>(8);
String[] attrIds = requestedAttributes.toArray(STRING0);
Attributes attrs;
try {
@@ -429,10 +430,10 @@
int n = encodedCert.length;
if (n == 0) {
- return Collections.<X509Certificate>emptySet();
+ return Collections.emptySet();
}
- List<X509Certificate> certs = new ArrayList<X509Certificate>(n);
+ List<X509Certificate> certs = new ArrayList<>(n);
/* decode certs and check if they satisfy selector */
for (int i = 0; i < n; i++) {
ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert[i]);
@@ -477,11 +478,10 @@
int n = encodedCertPair.length;
if (n == 0) {
- return Collections.<X509CertificatePair>emptySet();
+ return Collections.emptySet();
}
- List<X509CertificatePair> certPairs =
- new ArrayList<X509CertificatePair>(n);
+ List<X509CertificatePair> certPairs = new ArrayList<>(n);
/* decode each cert pair and add it to the Collection */
for (int i = 0; i < n; i++) {
try {
@@ -528,8 +528,7 @@
getCertPairs(request, CROSS_CERT);
// Find Certificates that match and put them in a list
- ArrayList<X509Certificate> matchingCerts =
- new ArrayList<X509Certificate>();
+ ArrayList<X509Certificate> matchingCerts = new ArrayList<>();
for (X509CertificatePair certPair : certPairs) {
X509Certificate cert;
if (forward != null) {
@@ -587,7 +586,7 @@
int basicConstraints = xsel.getBasicConstraints();
String subject = xsel.getSubjectAsString();
String issuer = xsel.getIssuerAsString();
- HashSet<X509Certificate> certs = new HashSet<X509Certificate>();
+ HashSet<X509Certificate> certs = new HashSet<>();
if (debug != null) {
debug.println("LDAPCertStore.engineGetCertificates() basicConstraints: "
+ basicConstraints);
@@ -706,10 +705,10 @@
int n = encodedCRL.length;
if (n == 0) {
- return Collections.<X509CRL>emptySet();
+ return Collections.emptySet();
}
- List<X509CRL> crls = new ArrayList<X509CRL>(n);
+ List<X509CRL> crls = new ArrayList<>(n);
/* decode each crl and check if it matches selector */
for (int i = 0; i < n; i++) {
try {
@@ -765,13 +764,13 @@
throw new CertStoreException("need X509CRLSelector to find CRLs");
}
X509CRLSelector xsel = (X509CRLSelector) selector;
- HashSet<X509CRL> crls = new HashSet<X509CRL>();
+ HashSet<X509CRL> crls = new HashSet<>();
// Look in directory entry for issuer of cert we're checking.
Collection<Object> issuerNames;
X509Certificate certChecking = xsel.getCertificateChecking();
if (certChecking != null) {
- issuerNames = new HashSet<Object>();
+ issuerNames = new HashSet<>();
X500Principal issuer = certChecking.getIssuerX500Principal();
issuerNames.add(issuer.getName(X500Principal.RFC2253));
} else {
@@ -796,7 +795,7 @@
issuerName = (String)nameObject;
}
// If all we want is CA certs, try to get the (probably shorter) ARL
- Collection<X509CRL> entryCRLs = Collections.<X509CRL>emptySet();
+ Collection<X509CRL> entryCRLs = Collections.emptySet();
if (certChecking == null || certChecking.getBasicConstraints() != -1) {
LDAPRequest request = new LDAPRequest(issuerName);
request.addRequestedAttribute(CROSS_CERT);
@@ -1028,9 +1027,9 @@
throws IOException {
this.selector = selector == null ? new X509CRLSelector() : selector;
this.certIssuers = certIssuers;
- issuerNames = new HashSet<Object>();
+ issuerNames = new HashSet<>();
issuerNames.add(ldapDN);
- issuers = new HashSet<X500Principal>();
+ issuers = new HashSet<>();
issuers.add(new X500Name(ldapDN).asX500Principal());
}
// we only override the get (accessor methods) since the set methods
--- a/jdk/src/share/classes/sun/security/ssl/CipherBox.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/CipherBox.java Wed Oct 19 10:16:22 2011 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -305,9 +305,11 @@
byte[] buf = null;
int limit = bb.limit();
if (bb.hasArray()) {
+ int arrayOffset = bb.arrayOffset();
buf = bb.array();
- System.arraycopy(buf, pos,
- buf, pos + prefix.length, limit - pos);
+ System.arraycopy(buf, arrayOffset + pos,
+ buf, arrayOffset + pos + prefix.length,
+ limit - pos);
bb.limit(limit + prefix.length);
} else {
buf = new byte[limit - pos];
@@ -491,9 +493,10 @@
byte[] buf = null;
int limit = bb.limit();
if (bb.hasArray()) {
+ int arrayOffset = bb.arrayOffset();
buf = bb.array();
- System.arraycopy(buf, pos + blockSize,
- buf, pos, limit - pos - blockSize);
+ System.arraycopy(buf, arrayOffset + pos + blockSize,
+ buf, arrayOffset + pos, limit - pos - blockSize);
bb.limit(limit - blockSize);
} else {
buf = new byte[limit - pos - blockSize];
--- a/jdk/src/share/classes/sun/security/ssl/SSLSessionContextImpl.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSessionContextImpl.java Wed Oct 19 10:16:22 2011 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -43,11 +43,14 @@
import javax.net.ssl.SSLSession;
import sun.security.util.Cache;
+import sun.security.util.Cache.CacheVisitor;
final class SSLSessionContextImpl implements SSLSessionContext {
- private Cache sessionCache; // session cache, session id as key
- private Cache sessionHostPortCache; // session cache, "host:port" as key
+ private Cache<SessionId, SSLSessionImpl> sessionCache;
+ // session cache, session id as key
+ private Cache<String, SSLSessionImpl> sessionHostPortCache;
+ // session cache, "host:port" as key
private int cacheLimit; // the max cache size
private int timeout; // timeout in seconds
@@ -71,8 +74,7 @@
throw new NullPointerException("session id cannot be null");
}
- SSLSessionImpl sess =
- (SSLSessionImpl)sessionCache.get(new SessionId(sessionId));
+ SSLSessionImpl sess = sessionCache.get(new SessionId(sessionId));
if (!isTimedout(sess)) {
return sess;
}
@@ -157,8 +159,7 @@
return null;
}
- SSLSessionImpl sess =
- (SSLSessionImpl)sessionHostPortCache.get(getKey(hostname, port));
+ SSLSessionImpl sess = sessionHostPortCache.get(getKey(hostname, port));
if (!isTimedout(sess)) {
return sess;
}
@@ -193,7 +194,7 @@
// package-private method, remove a cached SSLSession
void remove(SessionId key) {
- SSLSessionImpl s = (SSLSessionImpl)sessionCache.get(key);
+ SSLSessionImpl s = sessionCache.get(key);
if (s != null) {
sessionCache.remove(key);
sessionHostPortCache.remove(
@@ -233,17 +234,17 @@
}
final class SessionCacheVisitor
- implements sun.security.util.Cache.CacheVisitor {
+ implements Cache.CacheVisitor<SessionId, SSLSessionImpl> {
Vector<byte[]> ids = null;
- // public void visit(java.util.Map<Object, Object> map) {}
- public void visit(java.util.Map<Object, Object> map) {
- ids = new Vector<byte[]>(map.size());
+ // public void visit(java.util.Map<K,V> map) {}
+ public void visit(java.util.Map<SessionId, SSLSessionImpl> map) {
+ ids = new Vector<>(map.size());
- for (Object key : map.keySet()) {
- SSLSessionImpl value = (SSLSessionImpl)map.get(key);
+ for (SessionId key : map.keySet()) {
+ SSLSessionImpl value = map.get(key);
if (!isTimedout(value)) {
- ids.addElement(((SessionId)key).getId());
+ ids.addElement(key.getId());
}
}
}
--- a/jdk/src/share/classes/sun/security/util/Cache.java Wed Oct 19 10:15:23 2011 -0400
+++ b/jdk/src/share/classes/sun/security/util/Cache.java Wed Oct 19 10:16:22 2011 -0400
@@ -43,7 +43,7 @@
*
* . optional lifetime, specified in seconds.
*
- * . save for concurrent use by multiple threads
+ * . safe for concurrent use by multiple threads
*
* . values are held by either standard references or via SoftReferences.
* SoftReferences have the advantage that they are automatically cleared
@@ -69,7 +69,7 @@
*
* @author Andreas Sterbenz
*/
-public abstract class Cache {
+public abstract class Cache<K,V> {
protected Cache() {
// empty
@@ -88,12 +88,12 @@
/**
* Add an entry to the cache.
*/
- public abstract void put(Object key, Object value);
+ public abstract void put(K key, V value);
/**
* Get a value from the cache.
*/
- public abstract Object get(Object key);
+ public abstract V get(Object key);
/**
* Remove an entry from the cache.
@@ -113,14 +113,14 @@
/**
* accept a visitor
*/
- public abstract void accept(CacheVisitor visitor);
+ public abstract void accept(CacheVisitor<K,V> visitor);
/**
* Return a new memory cache with the specified maximum size, unlimited
* lifetime for entries, with the values held by SoftReferences.
*/
- public static Cache newSoftMemoryCache(int size) {
- return new MemoryCache(true, size);
+ public static <K,V> Cache<K,V> newSoftMemoryCache(int size) {
+ return new MemoryCache<>(true, size);
}
/**
@@ -128,23 +128,24 @@
* specified maximum lifetime (in seconds), with the values held
* by SoftReferences.
*/
- public static Cache newSoftMemoryCache(int size, int timeout) {
- return new MemoryCache(true, size, timeout);
+ public static <K,V> Cache<K,V> newSoftMemoryCache(int size, int timeout) {
+ return new MemoryCache<>(true, size, timeout);
}
/**
* Return a new memory cache with the specified maximum size, unlimited
* lifetime for entries, with the values held by standard references.
*/
- public static Cache newHardMemoryCache(int size) {
- return new MemoryCache(false, size);
+ public static <K,V> Cache<K,V> newHardMemoryCache(int size) {
+ return new MemoryCache<>(false, size);
}
/**
* Return a dummy cache that does nothing.
*/
- public static Cache newNullCache() {
- return NullCache.INSTANCE;
+ @SuppressWarnings("unchecked")
+ public static <K,V> Cache<K,V> newNullCache() {
+ return (Cache<K,V>) NullCache.INSTANCE;
}
/**
@@ -152,8 +153,8 @@
* specified maximum lifetime (in seconds), with the values held
* by standard references.
*/
- public static Cache newHardMemoryCache(int size, int timeout) {
- return new MemoryCache(false, size, timeout);
+ public static <K,V> Cache<K,V> newHardMemoryCache(int size, int timeout) {
+ return new MemoryCache<>(false, size, timeout);
}
/**
@@ -193,15 +194,15 @@
}
}
- public interface CacheVisitor {
- public void visit(Map<Object, Object> map);
+ public interface CacheVisitor<K,V> {
+ public void visit(Map<K,V> map);
}
}
-class NullCache extends Cache {
+class NullCache<K,V> extends Cache<K,V> {
- final static Cache INSTANCE = new NullCache();
+ final static Cache<Object,Object> INSTANCE = new NullCache<>();
private NullCache() {
// empty
@@ -215,11 +216,11 @@
// empty
}
- public void put(Object key, Object value) {
+ public void put(K key, V value) {
// empty
}
- public Object get(Object key) {
+ public V get(Object key) {
return null;
}
@@ -235,23 +236,26 @@
// empty
}
- public void accept(CacheVisitor visitor) {
+ public void accept(CacheVisitor<K,V> visitor) {
// empty
}
}
-class MemoryCache extends Cache {
+class MemoryCache<K,V> extends Cache<K,V> {
private final static float LOAD_FACTOR = 0.75f;
// XXXX
private final static boolean DEBUG = false;
- private final Map<Object, CacheEntry> cacheMap;
+ private final Map<K, CacheEntry<K,V>> cacheMap;
private int maxSize;
private long lifetime;
- private final ReferenceQueue<Object> queue;
+
+ // ReferenceQueue is of type V instead of Cache<K,V>
+ // to allow SoftCacheEntry to extend SoftReference<V>
+ private final ReferenceQueue<V> queue;
public MemoryCache(boolean soft, int maxSize) {
this(soft, maxSize, 0);
@@ -260,10 +264,13 @@
public MemoryCache(boolean soft, int maxSize, int lifetime) {
this.maxSize = maxSize;
this.lifetime = lifetime * 1000;
- this.queue = soft ? new ReferenceQueue<Object>() : null;
+ if (soft)
+ this.queue = new ReferenceQueue<>();
+ else
+ this.queue = null;
+
int buckets = (int)(maxSize / LOAD_FACTOR) + 1;
- cacheMap = new LinkedHashMap<Object, CacheEntry>(buckets,
- LOAD_FACTOR, true);
+ cacheMap = new LinkedHashMap<>(buckets, LOAD_FACTOR, true);
}
/**
@@ -279,16 +286,17 @@
}
int startSize = cacheMap.size();
while (true) {
- CacheEntry entry = (CacheEntry)queue.poll();
+ @SuppressWarnings("unchecked")
+ CacheEntry<K,V> entry = (CacheEntry<K,V>)queue.poll();
if (entry == null) {
break;
}
- Object key = entry.getKey();
+ K key = entry.getKey();
if (key == null) {
// key is null, entry has already been removed
continue;
}
- CacheEntry currentEntry = cacheMap.remove(key);
+ CacheEntry<K,V> currentEntry = cacheMap.remove(key);
// check if the entry in the map corresponds to the expired
// entry. If not, readd the entry
if ((currentEntry != null) && (entry != currentEntry)) {
@@ -314,9 +322,9 @@
}
int cnt = 0;
long time = System.currentTimeMillis();
- for (Iterator<CacheEntry> t = cacheMap.values().iterator();
+ for (Iterator<CacheEntry<K,V>> t = cacheMap.values().iterator();
t.hasNext(); ) {
- CacheEntry entry = t.next();
+ CacheEntry<K,V> entry = t.next();
if (entry.isValid(time) == false) {
t.remove();
cnt++;
@@ -339,7 +347,7 @@
if (queue != null) {
// if this is a SoftReference cache, first invalidate() all
// entries so that GC does not have to enqueue them
- for (CacheEntry entry : cacheMap.values()) {
+ for (CacheEntry<K,V> entry : cacheMap.values()) {
entry.invalidate();
}
while (queue.poll() != null) {
@@ -349,12 +357,12 @@
cacheMap.clear();
}
- public synchronized void put(Object key, Object value) {
+ public synchronized void put(K key, V value) {
emptyQueue();
long expirationTime = (lifetime == 0) ? 0 :
System.currentTimeMillis() + lifetime;
- CacheEntry newEntry = newEntry(key, value, expirationTime, queue);
- CacheEntry oldEntry = cacheMap.put(key, newEntry);
+ CacheEntry<K,V> newEntry = newEntry(key, value, expirationTime, queue);
+ CacheEntry<K,V> oldEntry = cacheMap.put(key, newEntry);
if (oldEntry != null) {
oldEntry.invalidate();
return;
@@ -362,8 +370,8 @@
if (maxSize > 0 && cacheMap.size() > maxSize) {
expungeExpiredEntries();
if (cacheMap.size() > maxSize) { // still too large?
- Iterator<CacheEntry> t = cacheMap.values().iterator();
- CacheEntry lruEntry = t.next();
+ Iterator<CacheEntry<K,V>> t = cacheMap.values().iterator();
+ CacheEntry<K,V> lruEntry = t.next();
if (DEBUG) {
System.out.println("** Overflow removal "
+ lruEntry.getKey() + " | " + lruEntry.getValue());
@@ -374,9 +382,9 @@
}
}
- public synchronized Object get(Object key) {
+ public synchronized V get(Object key) {
emptyQueue();
- CacheEntry entry = cacheMap.get(key);
+ CacheEntry<K,V> entry = cacheMap.get(key);
if (entry == null) {
return null;
}
@@ -393,7 +401,7 @@
public synchronized void remove(Object key) {
emptyQueue();
- CacheEntry entry = cacheMap.remove(key);
+ CacheEntry<K,V> entry = cacheMap.remove(key);
if (entry != null) {
entry.invalidate();
}
@@ -402,9 +410,9 @@
public synchronized void setCapacity(int size) {
expungeExpiredEntries();
if (size > 0 && cacheMap.size() > size) {
- Iterator<CacheEntry> t = cacheMap.values().iterator();
+ Iterator<CacheEntry<K,V>> t = cacheMap.values().iterator();
for (int i = cacheMap.size() - size; i > 0; i--) {
- CacheEntry lruEntry = t.next();
+ CacheEntry<K,V> lruEntry = t.next();
if (DEBUG) {
System.out.println("** capacity reset removal "
+ lruEntry.getKey() + " | " + lruEntry.getValue());
@@ -431,60 +439,61 @@
}
// it is a heavyweight method.
- public synchronized void accept(CacheVisitor visitor) {
+ public synchronized void accept(CacheVisitor<K,V> visitor) {
expungeExpiredEntries();
- Map<Object, Object> cached = getCachedEntries();
+ Map<K,V> cached = getCachedEntries();
visitor.visit(cached);
}
- private Map<Object, Object> getCachedEntries() {
- Map<Object,Object> kvmap = new HashMap<Object,Object>(cacheMap.size());
+ private Map<K,V> getCachedEntries() {
+ Map<K,V> kvmap = new HashMap<>(cacheMap.size());
- for (CacheEntry entry : cacheMap.values()) {
+ for (CacheEntry<K,V> entry : cacheMap.values()) {
kvmap.put(entry.getKey(), entry.getValue());
}
return kvmap;
}
- protected CacheEntry newEntry(Object key, Object value,
- long expirationTime, ReferenceQueue<Object> queue) {
+ protected CacheEntry<K,V> newEntry(K key, V value,
+ long expirationTime, ReferenceQueue<V> queue) {
if (queue != null) {
- return new SoftCacheEntry(key, value, expirationTime, queue);
+ return new SoftCacheEntry<>(key, value, expirationTime, queue);
} else {
- return new HardCacheEntry(key, value, expirationTime);
+ return new HardCacheEntry<>(key, value, expirationTime);
}
}
- private static interface CacheEntry {
+ private static interface CacheEntry<K,V> {
boolean isValid(long currentTime);
void invalidate();
- Object getKey();
+ K getKey();
- Object getValue();
+ V getValue();
}
- private static class HardCacheEntry implements CacheEntry {
+ private static class HardCacheEntry<K,V> implements CacheEntry<K,V> {
- private Object key, value;
+ private K key;
+ private V value;
private long expirationTime;
- HardCacheEntry(Object key, Object value, long expirationTime) {
+ HardCacheEntry(K key, V value, long expirationTime) {
this.key = key;
this.value = value;
this.expirationTime = expirationTime;
}
- public Object getKey() {
+ public K getKey() {
return key;
}
- public Object getValue() {
+ public V getValue() {
return value;
}
@@ -503,24 +512,25 @@
}
}
- private static class SoftCacheEntry
- extends SoftReference<Object> implements CacheEntry {
+ private static class SoftCacheEntry<K,V>
+ extends SoftReference<V>
+ implements CacheEntry<K,V> {
- private Object key;
+ private K key;
private long expirationTime;
- SoftCacheEntry(Object key, Object value, long expirationTime,
- ReferenceQueue<Object> queue) {
+ SoftCacheEntry(K key, V value, long expirationTime,
+ ReferenceQueue<V> queue) {
super(value, queue);
this.key = key;
this.expirationTime = expirationTime;
}
- public Object getKey() {
+ public K getKey() {
return key;
}
- public Object getValue() {
+ public V getValue() {
return get();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineBadBufferArrayAccess.java Wed Oct 19 10:16:22 2011 -0400
@@ -0,0 +1,479 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 7031830
+ * @summary bad_record_mac failure on TLSv1.2 enabled connection with SSLEngine
+ * @run main/othervm SSLEngineBadBufferArrayAccess
+ *
+ * SunJSSE does not support dynamic system properties, no way to re-use
+ * system properties in samevm/agentvm mode.
+ */
+
+/**
+ * A SSLSocket/SSLEngine interop test case. This is not the way to
+ * code SSLEngine-based servers, but works for what we need to do here,
+ * which is to make sure that SSLEngine/SSLSockets can talk to each other.
+ * SSLEngines can use direct or indirect buffers, and different code
+ * is used to get at the buffer contents internally, so we test that here.
+ *
+ * The test creates one SSLSocket (client) and one SSLEngine (server).
+ * The SSLSocket talks to a raw ServerSocket, and the server code
+ * does the translation between byte [] and ByteBuffers that the SSLEngine
+ * can use. The "transport" layer consists of a Socket Input/OutputStream
+ * and two byte buffers for the SSLEngines: think of them
+ * as directly connected pipes.
+ *
+ * Again, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ *
+ * client server message
+ * ====== ====== =======
+ * write() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * read() ... ServerHello/Certificate
+ * write() ... ClientKeyExchange
+ * write() ... ChangeCipherSpec
+ * write() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * read() ... ChangeCipherSpec
+ * read() ... Finished
+ *
+ * This particular bug had a problem where byte buffers backed by an
+ * array didn't offset correctly, and we got bad MAC errors.
+ */
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.nio.*;
+
+public class SSLEngineBadBufferArrayAccess {
+
+ /*
+ * Enables logging of the SSL/TLS operations.
+ */
+ private static boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static boolean debug = false;
+ private SSLContext sslc;
+ private SSLEngine serverEngine; // server-side SSLEngine
+ private SSLSocket sslSocket; // client-side socket
+ private ServerSocket serverSocket; // server-side Socket, generates the...
+ private Socket socket; // server-side socket that will read
+
+ private final byte[] serverMsg = "Hi there Client, I'm a Server".getBytes();
+ private final byte[] clientMsg = "Hello Server, I'm a Client".getBytes();
+
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ private volatile Exception clientException;
+ private volatile Exception serverException;
+
+ /*
+ * For data transport, this example uses local ByteBuffers.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores/trust material.
+ */
+ private static final String pathToStores = "../../../../../../../etc/";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final String passwd = "passphrase";
+ private static String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + keyStoreFile;
+ private static String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores
+ + "/" + trustStoreFile;
+
+ /*
+ * Main entry point for this test.
+ */
+ public static void main(String args[]) throws Exception {
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ String [] protocols = new String [] {
+ "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" };
+
+ for (String protocol : protocols) {
+ log("Testing " + protocol);
+ /*
+ * Run the tests with direct and indirect buffers.
+ */
+ SSLEngineBadBufferArrayAccess test =
+ new SSLEngineBadBufferArrayAccess(protocol);
+ test.runTest(true);
+ test.runTest(false);
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for these tests.
+ */
+ public SSLEngineBadBufferArrayAccess(String protocol) throws Exception {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ ks.load(new FileInputStream(keyFilename), passphrase);
+ ts.load(new FileInputStream(trustFilename), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance(protocol);
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+ }
+
+ /*
+ * Run the test.
+ *
+ * Sit in a tight loop, with the server engine calling wrap/unwrap
+ * regardless of whether data is available or not. We do this until
+ * we get the application data. Then we shutdown and go to the next one.
+ *
+ * The main loop handles all of the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+ private void runTest(boolean direct) throws Exception {
+ boolean serverClose = direct;
+
+ serverSocket = new ServerSocket(0);
+ int port = serverSocket.getLocalPort();
+ Thread thread = createClientThread(port, serverClose);
+
+ socket = serverSocket.accept();
+ socket.setSoTimeout(500);
+ serverSocket.close();
+
+ createSSLEngine();
+ createBuffers(direct);
+
+ try {
+ boolean closed = false;
+
+ InputStream is = socket.getInputStream();
+ OutputStream os = socket.getOutputStream();
+
+ SSLEngineResult serverResult; // results from last operation
+
+ /*
+ * Examining the SSLEngineResults could be much more involved,
+ * and may alter the overall flow of the application.
+ *
+ * For example, if we received a BUFFER_OVERFLOW when trying
+ * to write to the output pipe, we could reallocate a larger
+ * pipe, but instead we wait for the peer to drain it.
+ */
+ byte[] inbound = new byte[8192];
+ byte[] outbound = new byte[8192];
+
+ while (!isEngineClosed(serverEngine)) {
+ int len = 0;
+
+ // Inbound data
+ log("================");
+
+ // Read from the Client side.
+ try {
+ len = is.read(inbound);
+ if (len == -1) {
+ throw new Exception("Unexpected EOF");
+ }
+ cTOs.put(inbound, 0, len);
+ } catch (SocketTimeoutException ste) {
+ // swallow. Nothing yet, probably waiting on us.
+ }
+
+ cTOs.flip();
+
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ cTOs.compact();
+
+ // Outbound data
+ log("----");
+
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+
+ sTOc.flip();
+
+ if ((len = sTOc.remaining()) != 0) {
+ sTOc.get(outbound, 0, len);
+ os.write(outbound, 0, len);
+ // Give the other side a chance to process
+ }
+
+ sTOc.compact();
+
+ if (!closed && (serverOut.remaining() == 0)) {
+ closed = true;
+
+ /*
+ * We'll alternate initiatating the shutdown.
+ * When the server initiates, it will take one more
+ * loop, but tests the orderly shutdown.
+ */
+ if (serverClose) {
+ serverEngine.closeOutbound();
+ }
+ serverIn.flip();
+
+ /*
+ * A sanity check to ensure we got what was sent.
+ */
+ if (serverIn.remaining() != clientMsg.length) {
+ throw new Exception("Client: Data length error");
+ }
+
+ for (int i = 0; i < clientMsg.length; i++) {
+ if (clientMsg[i] != serverIn.get()) {
+ throw new Exception("Client: Data content error");
+ }
+ }
+ serverIn.compact();
+ }
+ }
+ return;
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ socket.close();
+
+ // Wait for the client to join up with us.
+ thread.join();
+ if (serverException != null) {
+ throw serverException;
+ }
+ if (clientException != null) {
+ throw clientException;
+ }
+ }
+ }
+
+ /*
+ * Create a client thread which does simple SSLSocket operations.
+ * We'll write and read one data packet.
+ */
+ private Thread createClientThread(final int port,
+ final boolean serverClose) throws Exception {
+
+ Thread t = new Thread("ClientThread") {
+
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(1000); // Give server time to finish setup.
+
+ sslSocket = (SSLSocket) sslc.getSocketFactory().
+ createSocket("localhost", port);
+ OutputStream os = sslSocket.getOutputStream();
+ InputStream is = sslSocket.getInputStream();
+
+ // write(byte[]) goes in one shot.
+ os.write(clientMsg);
+
+ byte[] inbound = new byte[2048];
+ int pos = 0;
+
+ int len;
+done:
+ while ((len = is.read(inbound, pos, 2048 - pos)) != -1) {
+ pos += len;
+ // Let the client do the closing.
+ if ((pos == serverMsg.length) && !serverClose) {
+ sslSocket.close();
+ break done;
+ }
+ }
+
+ if (pos != serverMsg.length) {
+ throw new Exception("Client: Data length error");
+ }
+
+ for (int i = 0; i < serverMsg.length; i++) {
+ if (inbound[i] != serverMsg[i]) {
+ throw new Exception("Client: Data content error");
+ }
+ }
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ };
+ t.start();
+ return t;
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this test.
+ */
+ private void createSSLEngine() throws Exception {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ serverEngine.getNeedClientAuth();
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+ private void createBuffers(boolean direct) {
+
+ SSLSession session = serverEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ if (direct) {
+ serverIn = ByteBuffer.allocateDirect(appBufferMax + 50);
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+ } else {
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+ cTOs = ByteBuffer.allocate(netBufferMax);
+ sTOc = ByteBuffer.allocate(netBufferMax);
+ }
+
+ serverOut = ByteBuffer.wrap(serverMsg);
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine) {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result) {
+ if (!logging) {
+ return;
+ }
+ if (resultOnce) {
+ resultOnce = false;
+ System.out.println("The format of the SSLEngineResult is: \n"
+ + "\t\"getStatus() / getHandshakeStatus()\" +\n"
+ + "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str
+ + result.getStatus() + "/" + hsStatus + ", "
+ + result.bytesConsumed() + "/" + result.bytesProduced()
+ + " bytes");
+ if (hsStatus == HandshakeStatus.FINISHED) {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str) {
+ if (logging) {
+ System.out.println(str);
+ }
+ }
+}