< prev index next >

src/share/classes/javax/crypto/Cipher.java

Print this page
rev 1386 : 7092825: javax.crypto.Cipher.Transform.patternCache is synchronizedMap and became scalability bottleneck.
Summary: Changed patternCache from synchronizedMap to ConcurrentHashMap.
Reviewed-by: mullan
rev 1387 : 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
Reviewed-by: xuelei, mullan
Contributed-by: alexandre.boulgakov@oracle.com

*** 1,7 **** /* ! * Copyright (c) 1997, 2007, 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. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1997, 2012, 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. Oracle designates this
*** 24,36 **** */ package javax.crypto; import java.util.*; import java.util.regex.*; - import static java.util.Locale.ENGLISH; import java.security.*; import java.security.Provider.Service; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; --- 24,37 ---- */ package javax.crypto; import java.util.*; + import java.util.concurrent.ConcurrentHashMap; + import java.util.concurrent.ConcurrentMap; import java.util.regex.*; import java.security.*; import java.security.Provider.Service; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException;
*** 42,52 **** import java.nio.ByteBuffer; import java.nio.ReadOnlyBufferException; import sun.security.util.Debug; import sun.security.jca.*; - import sun.security.jca.GetInstance.Instance; /** * This class provides the functionality of a cryptographic cipher for * encryption and decryption. It forms the core of the Java Cryptographic * Extension (JCE) framework. --- 43,52 ----
*** 171,184 **** // null once provider is selected private Service firstService; // remaining services to try in provider selection // null once provider is selected ! private Iterator serviceIterator; // list of transform Strings to lookup in the provider ! private List transforms; private final Object lock; /** * Creates a Cipher object. --- 171,184 ---- // null once provider is selected private Service firstService; // remaining services to try in provider selection // null once provider is selected ! private Iterator<Service> serviceIterator; // list of transform Strings to lookup in the provider ! private List<Transform> transforms; private final Object lock; /** * Creates a Cipher object.
*** 215,225 **** this.cryptoPerm = CryptoAllPermission.INSTANCE; this.lock = null; } private Cipher(CipherSpi firstSpi, Service firstService, ! Iterator serviceIterator, String transformation, List transforms) { this.firstSpi = firstSpi; this.firstService = firstService; this.serviceIterator = serviceIterator; this.transforms = transforms; this.transformation = transformation; --- 215,226 ---- this.cryptoPerm = CryptoAllPermission.INSTANCE; this.lock = null; } private Cipher(CipherSpi firstSpi, Service firstService, ! Iterator<Service> serviceIterator, String transformation, ! List<Transform> transforms) { this.firstSpi = firstSpi; this.firstService = firstService; this.serviceIterator = serviceIterator; this.transforms = transforms; this.transformation = transformation;
*** 334,360 **** return S_MAYBE; } return matches(regexp, value) ? S_YES : S_NO; } ! // Map<String,Pattern> for previously compiled patterns ! // XXX use ConcurrentHashMap once available ! private final static Map patternCache = ! Collections.synchronizedMap(new HashMap()); private static boolean matches(String regexp, String str) { ! Pattern pattern = (Pattern)patternCache.get(regexp); if (pattern == null) { pattern = Pattern.compile(regexp); ! patternCache.put(regexp, pattern); } return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches(); } } ! private static List getTransforms(String transformation) throws NoSuchAlgorithmException { String[] parts = tokenizeTransformation(transformation); String alg = parts[0]; String mode = parts[1]; --- 335,360 ---- return S_MAYBE; } return matches(regexp, value) ? S_YES : S_NO; } ! // ConcurrentMap<String,Pattern> for previously compiled patterns ! private final static ConcurrentMap<String, Pattern> patternCache = ! new ConcurrentHashMap<String, Pattern>(); private static boolean matches(String regexp, String str) { ! Pattern pattern = patternCache.get(regexp); if (pattern == null) { pattern = Pattern.compile(regexp); ! patternCache.putIfAbsent(regexp, pattern); } return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches(); } } ! private static List<Transform> getTransforms(String transformation) throws NoSuchAlgorithmException { String[] parts = tokenizeTransformation(transformation); String alg = parts[0]; String mode = parts[1];
*** 370,393 **** // DES Transform tr = new Transform(alg, "", null, null); return Collections.singletonList(tr); } else { // if ((mode != null) && (pad != null)) { // DES/CBC/PKCS5Padding ! List list = new ArrayList(4); list.add(new Transform(alg, "/" + mode + "/" + pad, null, null)); list.add(new Transform(alg, "/" + mode, null, pad)); list.add(new Transform(alg, "//" + pad, mode, null)); list.add(new Transform(alg, "", mode, pad)); return list; } } // get the transform matching the specified service ! private static Transform getTransform(Service s, List transforms) { String alg = s.getAlgorithm().toUpperCase(Locale.ENGLISH); ! for (Iterator t = transforms.iterator(); t.hasNext(); ) { ! Transform tr = (Transform)t.next(); if (alg.endsWith(tr.suffix)) { return tr; } } return null; --- 370,393 ---- // DES Transform tr = new Transform(alg, "", null, null); return Collections.singletonList(tr); } else { // if ((mode != null) && (pad != null)) { // DES/CBC/PKCS5Padding ! List<Transform> list = new ArrayList<Transform>(4); list.add(new Transform(alg, "/" + mode + "/" + pad, null, null)); list.add(new Transform(alg, "/" + mode, null, pad)); list.add(new Transform(alg, "//" + pad, mode, null)); list.add(new Transform(alg, "", mode, pad)); return list; } } // get the transform matching the specified service ! private static Transform getTransform(Service s, ! List<Transform> transforms) { String alg = s.getAlgorithm().toUpperCase(Locale.ENGLISH); ! for (Transform tr : transforms) { if (alg.endsWith(tr.suffix)) { return tr; } } return null;
*** 427,449 **** * @see java.security.Provider */ public static final Cipher getInstance(String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException { ! List transforms = getTransforms(transformation); ! List cipherServices = new ArrayList(transforms.size()); ! for (Iterator t = transforms.iterator(); t.hasNext(); ) { ! Transform transform = (Transform)t.next(); cipherServices.add(new ServiceId("Cipher", transform.transform)); } ! List services = GetInstance.getServices(cipherServices); // make sure there is at least one service from a signed provider // and that it can use the specified mode and padding ! Iterator t = services.iterator(); Exception failure = null; while (t.hasNext()) { ! Service s = (Service)t.next(); if (JceSecurity.canUseProvider(s.getProvider()) == false) { continue; } Transform tr = getTransform(s, transforms); if (tr == null) { --- 427,448 ---- * @see java.security.Provider */ public static final Cipher getInstance(String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException { ! List<Transform> transforms = getTransforms(transformation); ! List<ServiceId> cipherServices = new ArrayList<ServiceId>(transforms.size()); ! for (Transform transform : transforms) { cipherServices.add(new ServiceId("Cipher", transform.transform)); } ! List<Service> services = GetInstance.getServices(cipherServices); // make sure there is at least one service from a signed provider // and that it can use the specified mode and padding ! Iterator<Service> t = services.iterator(); Exception failure = null; while (t.hasNext()) { ! Service s = t.next(); if (JceSecurity.canUseProvider(s.getProvider()) == false) { continue; } Transform tr = getTransform(s, transforms); if (tr == null) {
*** 567,581 **** { if (provider == null) { throw new IllegalArgumentException("Missing provider"); } Exception failure = null; ! List transforms = getTransforms(transformation); boolean providerChecked = false; String paddingError = null; ! for (Iterator t = transforms.iterator(); t.hasNext();) { ! Transform tr = (Transform)t.next(); Service s = provider.getService("Cipher", tr.transform); if (s == null) { continue; } if (providerChecked == false) { --- 566,579 ---- { if (provider == null) { throw new IllegalArgumentException("Missing provider"); } Exception failure = null; ! List<Transform> transforms = getTransforms(transformation); boolean providerChecked = false; String paddingError = null; ! for (Transform tr : transforms) { Service s = provider.getService("Cipher", tr.transform); if (s == null) { continue; } if (providerChecked == false) {
*** 674,684 **** s = firstService; thisSpi = firstSpi; firstService = null; firstSpi = null; } else { ! s = (Service)serviceIterator.next(); thisSpi = null; } if (JceSecurity.canUseProvider(s.getProvider()) == false) { continue; } --- 672,682 ---- s = firstService; thisSpi = firstSpi; firstService = null; firstSpi = null; } else { ! s = serviceIterator.next(); thisSpi = null; } if (JceSecurity.canUseProvider(s.getProvider()) == false) { continue; }
*** 768,778 **** s = firstService; thisSpi = firstSpi; firstService = null; firstSpi = null; } else { ! s = (Service)serviceIterator.next(); thisSpi = null; } // if provider says it does not support this key, ignore it if (s.supportsParameter(key) == false) { continue; --- 766,776 ---- s = firstService; thisSpi = firstSpi; firstService = null; firstSpi = null; } else { ! s = serviceIterator.next(); thisSpi = null; } // if provider says it does not support this key, ignore it if (s.supportsParameter(key) == false) { continue;
*** 1530,1540 **** // type X.509. if (certificate instanceof java.security.cert.X509Certificate) { // Check whether the cert has a key usage extension // marked as a critical extension. X509Certificate cert = (X509Certificate)certificate; ! Set critSet = cert.getCriticalExtensionOIDs(); if (critSet != null && !critSet.isEmpty() && critSet.contains(KEY_USAGE_EXTENSION_OID)) { boolean[] keyUsageInfo = cert.getKeyUsage(); // keyUsageInfo[2] is for keyEncipherment; --- 1528,1538 ---- // type X.509. if (certificate instanceof java.security.cert.X509Certificate) { // Check whether the cert has a key usage extension // marked as a critical extension. X509Certificate cert = (X509Certificate)certificate; ! Set<String> critSet = cert.getCriticalExtensionOIDs(); if (critSet != null && !critSet.isEmpty() && critSet.contains(KEY_USAGE_EXTENSION_OID)) { boolean[] keyUsageInfo = cert.getKeyUsage(); // keyUsageInfo[2] is for keyEncipherment;
< prev index next >