提交 845c4665 编写于 作者: L lana

Merge

/* /*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.util.Arrays;
/** /**
* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
...@@ -54,7 +55,12 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -54,7 +55,12 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
private Object[] sessionK = null; private Object[] sessionK = null;
private int[] K = null; private int[] K = null;
/** (ROUNDS-1) * 4 */ /** Cipher encryption/decryption key */
// skip re-generating Session and Sub keys if the cipher key is
// the same
private byte[] lastKey = null;
/** ROUNDS * 4 */
private int limit = 0; private int limit = 0;
AESCrypt() { AESCrypt() {
...@@ -82,41 +88,45 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -82,41 +88,45 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
key.length + " bytes"); key.length + " bytes");
} }
// generate session key and reset sub key. if (!Arrays.equals(key, lastKey)) {
sessionK = makeKey(key); // re-generate session key 'sessionK' when cipher key changes
setSubKey(decrypting); makeSessionKey(key);
lastKey = key.clone(); // save cipher key
}
// set sub key to the corresponding session Key
this.K = (int[]) sessionK[(decrypting? 1:0)];
} }
private void setSubKey(boolean decrypting) { /**
int[][] Kd = (int[][]) sessionK[decrypting ? 1 : 0]; * Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4].
int rounds = Kd.length; * For decryption round keys, need to rotate right by 4 ints.
this.K = new int[rounds*4]; * @param kr The round keys for encryption or decryption.
for(int i=0; i<rounds; i++) { * @param decrypting True if 'kr' is for decryption and false otherwise.
*/
private static final int[] expandToSubKey(int[][] kr, boolean decrypting) {
int total = kr.length;
int[] expK = new int[total*4];
if (decrypting) {
// decrypting, rotate right by 4 ints
// i.e. i==0
for(int j=0; j<4; j++) { for(int j=0; j<4; j++) {
K[i*4 + j] = Kd[i][j]; expK[j] = kr[total-1][j];
} }
} for(int i=1; i<total; i++) {
for(int j=0; j<4; j++) {
if (decrypting) { expK[i*4 + j] = kr[i-1][j];
int j0 = K[K.length-4]; }
int j1 = K[K.length-3]; }
int j2 = K[K.length-2]; } else {
int j3 = K[K.length-1]; // encrypting, straight expansion
for(int i=0; i<total; i++) {
for (int i=this.K.length-1; i>3; i--) { for(int j=0; j<4; j++) {
this.K[i] = this.K[i-4]; expK[i*4 + j] = kr[i][j];
}
} }
K[0] = j0;
K[1] = j1;
K[2] = j2;
K[3] = j3;
} }
return expK;
ROUNDS_12 = (rounds>=13);
ROUNDS_14 = (rounds==15);
rounds--;
limit=rounds*4;
} }
private static int[] private static int[]
...@@ -566,10 +576,10 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -566,10 +576,10 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
/** /**
* Expand a user-supplied key material into a session key. * Expand a user-supplied key material into a session key.
* *
* @param key The 128/192/256-bit user-key to use. * @param k The 128/192/256-bit cipher key to use.
* @exception InvalidKeyException If the key is invalid. * @exception InvalidKeyException If the key is invalid.
*/ */
private static Object[] makeKey(byte[] k) throws InvalidKeyException { private void makeSessionKey(byte[] k) throws InvalidKeyException {
if (k == null) { if (k == null) {
throw new InvalidKeyException("Empty key"); throw new InvalidKeyException("Empty key");
} }
...@@ -639,10 +649,18 @@ final class AESCrypt extends SymmetricCipher implements AESConstants ...@@ -639,10 +649,18 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
U4[ tt & 0xFF]; U4[ tt & 0xFF];
} }
} }
// assemble the encryption (Ke) and decryption (Kd) round keys into
// one sessionKey object // assemble the encryption (Ke) and decryption (Kd) round keys
Object[] result = new Object[] {Ke, Kd}; // and expand them into arrays of ints.
return result; int[] expandedKe = expandToSubKey(Ke, false); // decrypting==false
int[] expandedKd = expandToSubKey(Kd, true); // decrypting==true
ROUNDS_12 = (ROUNDS>=12);
ROUNDS_14 = (ROUNDS==14);
limit = ROUNDS*4;
// store the expanded sub keys into 'sessionK'
sessionK = new Object[] { expandedKe, expandedKd };
} }
......
/* /*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,10 +30,16 @@ import java.util.Enumeration; ...@@ -30,10 +30,16 @@ import java.util.Enumeration;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Vector; import java.util.Vector;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import java.io.Serializable; import java.io.Serializable;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ObjectStreamField;
import java.io.ObjectInputStream;
import java.io.ObjectInputStream.GetField;
import java.io.ObjectOutputStream;
import java.io.ObjectOutputStream.PutField;
import java.io.IOException; import java.io.IOException;
/** /**
...@@ -61,15 +67,24 @@ implements Serializable { ...@@ -61,15 +67,24 @@ implements Serializable {
private static final long serialVersionUID = 4946547168093391015L; private static final long serialVersionUID = 4946547168093391015L;
// This class is similar to java.security.Permissions /**
private Hashtable<String, PermissionCollection> perms; * @serialField perms java.util.Hashtable
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("perms", Hashtable.class),
};
// Switched from Hashtable to ConcurrentHashMap to improve scalability.
// To maintain serialization compatibility, this field is made transient
// and custom readObject/writeObject methods are used.
private transient ConcurrentHashMap<String,PermissionCollection> perms;
/** /**
* Creates a new CryptoPermissions object containing * Creates a new CryptoPermissions object containing
* no CryptoPermissionCollections. * no CryptoPermissionCollections.
*/ */
CryptoPermissions() { CryptoPermissions() {
perms = new Hashtable<String, PermissionCollection>(7); perms = new ConcurrentHashMap<>(7);
} }
/** /**
...@@ -132,9 +147,7 @@ implements Serializable { ...@@ -132,9 +147,7 @@ implements Serializable {
getPermissionCollection(cryptoPerm); getPermissionCollection(cryptoPerm);
pc.add(cryptoPerm); pc.add(cryptoPerm);
String alg = cryptoPerm.getAlgorithm(); String alg = cryptoPerm.getAlgorithm();
if (!perms.containsKey(alg)) { perms.putIfAbsent(alg, pc);
perms.put(alg, pc);
}
} }
/** /**
...@@ -377,18 +390,17 @@ implements Serializable { ...@@ -377,18 +390,17 @@ implements Serializable {
PermissionCollection getPermissionCollection(String alg) { PermissionCollection getPermissionCollection(String alg) {
// If this CryptoPermissions includes CryptoAllPermission, // If this CryptoPermissions includes CryptoAllPermission,
// we should return CryptoAllPermission. // we should return CryptoAllPermission.
if (perms.containsKey(CryptoAllPermission.ALG_NAME)) { PermissionCollection pc = perms.get(CryptoAllPermission.ALG_NAME);
return perms.get(CryptoAllPermission.ALG_NAME);
}
PermissionCollection pc = perms.get(alg);
// If there isn't a PermissionCollection for
// the given algorithm,we should return the
// PermissionCollection for the wildcard
// if there is one.
if (pc == null) { if (pc == null) {
pc = perms.get(CryptoPermission.ALG_NAME_WILDCARD); pc = perms.get(alg);
// If there isn't a PermissionCollection for
// the given algorithm,we should return the
// PermissionCollection for the wildcard
// if there is one.
if (pc == null) {
pc = perms.get(CryptoPermission.ALG_NAME_WILDCARD);
}
} }
return pc; return pc;
} }
...@@ -414,6 +426,28 @@ implements Serializable { ...@@ -414,6 +426,28 @@ implements Serializable {
} }
return pc; return pc;
} }
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = s.readFields();
@SuppressWarnings("unchecked")
Hashtable<String,PermissionCollection> permTable =
(Hashtable<String,PermissionCollection>)
(fields.get("perms", null));
if (permTable != null) {
perms = new ConcurrentHashMap<>(permTable);
} else {
perms = new ConcurrentHashMap<>();
}
}
private void writeObject(ObjectOutputStream s) throws IOException {
Hashtable<String,PermissionCollection> permTable =
new Hashtable<>(perms);
ObjectOutputStream.PutField fields = s.putFields();
fields.put("perms", permTable);
s.writeFields();
}
} }
final class PermissionsEnumerator implements Enumeration<Permission> { final class PermissionsEnumerator implements Enumeration<Permission> {
...@@ -456,7 +490,6 @@ final class PermissionsEnumerator implements Enumeration<Permission> { ...@@ -456,7 +490,6 @@ final class PermissionsEnumerator implements Enumeration<Permission> {
} else { } else {
throw new NoSuchElementException("PermissionsEnumerator"); throw new NoSuchElementException("PermissionsEnumerator");
} }
} }
private Enumeration<Permission> getNextEnumWithMore() { private Enumeration<Permission> getNextEnumWithMore() {
......
/* /*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,6 +28,8 @@ package javax.crypto; ...@@ -28,6 +28,8 @@ package javax.crypto;
import java.security.*; import java.security.*;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/** /**
* The JCE security manager. * The JCE security manager.
...@@ -51,8 +53,10 @@ final class JceSecurityManager extends SecurityManager { ...@@ -51,8 +53,10 @@ final class JceSecurityManager extends SecurityManager {
private static final CryptoAllPermission allPerm; private static final CryptoAllPermission allPerm;
private static final Vector<Class<?>> TrustedCallersCache = private static final Vector<Class<?>> TrustedCallersCache =
new Vector<>(2); new Vector<>(2);
private static final Map<URL, CryptoPermissions> exemptCache = private static final ConcurrentMap<URL,CryptoPermissions> exemptCache =
new HashMap<>(); new ConcurrentHashMap<>();
private static final CryptoPermissions CACHE_NULL_MARK =
new CryptoPermissions();
// singleton instance // singleton instance
static final JceSecurityManager INSTANCE; static final JceSecurityManager INSTANCE;
...@@ -117,17 +121,19 @@ final class JceSecurityManager extends SecurityManager { ...@@ -117,17 +121,19 @@ final class JceSecurityManager extends SecurityManager {
return defaultPerm; return defaultPerm;
} }
CryptoPermissions appPerms; CryptoPermissions appPerms = exemptCache.get(callerCodeBase);
synchronized (this.getClass()) { if (appPerms == null) {
if (exemptCache.containsKey(callerCodeBase)) { // no match found in cache
synchronized (this.getClass()) {
appPerms = exemptCache.get(callerCodeBase); appPerms = exemptCache.get(callerCodeBase);
} else { if (appPerms == null) {
appPerms = getAppPermissions(callerCodeBase); appPerms = getAppPermissions(callerCodeBase);
exemptCache.put(callerCodeBase, appPerms); exemptCache.putIfAbsent(callerCodeBase,
(appPerms == null? CACHE_NULL_MARK:appPerms));
}
} }
} }
if (appPerms == null || appPerms == CACHE_NULL_MARK) {
if (appPerms == null) {
return defaultPerm; return defaultPerm;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册