提交 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -37,6 +37,7 @@
package com.sun.crypto.provider;
import java.security.InvalidKeyException;
import java.util.Arrays;
/**
* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
......@@ -54,7 +55,12 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
private Object[] sessionK = 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;
AESCrypt() {
......@@ -82,41 +88,45 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
key.length + " bytes");
}
// generate session key and reset sub key.
sessionK = makeKey(key);
setSubKey(decrypting);
if (!Arrays.equals(key, lastKey)) {
// re-generate session key 'sessionK' when cipher key changes
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];
int rounds = Kd.length;
this.K = new int[rounds*4];
for(int i=0; i<rounds; i++) {
/**
* Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4].
* For decryption round keys, need to rotate right by 4 ints.
* @param kr The round keys for encryption or decryption.
* @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++) {
K[i*4 + j] = Kd[i][j];
expK[j] = kr[total-1][j];
}
}
if (decrypting) {
int j0 = K[K.length-4];
int j1 = K[K.length-3];
int j2 = K[K.length-2];
int j3 = K[K.length-1];
for (int i=this.K.length-1; i>3; i--) {
this.K[i] = this.K[i-4];
for(int i=1; i<total; i++) {
for(int j=0; j<4; j++) {
expK[i*4 + j] = kr[i-1][j];
}
}
} else {
// encrypting, straight expansion
for(int i=0; i<total; i++) {
for(int j=0; j<4; j++) {
expK[i*4 + j] = kr[i][j];
}
}
K[0] = j0;
K[1] = j1;
K[2] = j2;
K[3] = j3;
}
ROUNDS_12 = (rounds>=13);
ROUNDS_14 = (rounds==15);
rounds--;
limit=rounds*4;
return expK;
}
private static int[]
......@@ -566,10 +576,10 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
/**
* 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.
*/
private static Object[] makeKey(byte[] k) throws InvalidKeyException {
private void makeSessionKey(byte[] k) throws InvalidKeyException {
if (k == null) {
throw new InvalidKeyException("Empty key");
}
......@@ -639,10 +649,18 @@ final class AESCrypt extends SymmetricCipher implements AESConstants
U4[ tt & 0xFF];
}
}
// assemble the encryption (Ke) and decryption (Kd) round keys into
// one sessionKey object
Object[] result = new Object[] {Ke, Kd};
return result;
// assemble the encryption (Ke) and decryption (Kd) round keys
// and expand them into arrays of ints.
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -30,10 +30,16 @@ import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import java.io.Serializable;
import java.io.InputStream;
import java.io.InputStreamReader;
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;
/**
......@@ -61,15 +67,24 @@ implements Serializable {
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
* no CryptoPermissionCollections.
*/
CryptoPermissions() {
perms = new Hashtable<String, PermissionCollection>(7);
perms = new ConcurrentHashMap<>(7);
}
/**
......@@ -132,9 +147,7 @@ implements Serializable {
getPermissionCollection(cryptoPerm);
pc.add(cryptoPerm);
String alg = cryptoPerm.getAlgorithm();
if (!perms.containsKey(alg)) {
perms.put(alg, pc);
}
perms.putIfAbsent(alg, pc);
}
/**
......@@ -377,18 +390,17 @@ implements Serializable {
PermissionCollection getPermissionCollection(String alg) {
// If this CryptoPermissions includes CryptoAllPermission,
// we should return CryptoAllPermission.
if (perms.containsKey(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.
PermissionCollection pc = perms.get(CryptoAllPermission.ALG_NAME);
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;
}
......@@ -414,6 +426,28 @@ implements Serializable {
}
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> {
......@@ -456,7 +490,6 @@ final class PermissionsEnumerator implements Enumeration<Permission> {
} else {
throw new NoSuchElementException("PermissionsEnumerator");
}
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,6 +28,8 @@ package javax.crypto;
import java.security.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* The JCE security manager.
......@@ -51,8 +53,10 @@ final class JceSecurityManager extends SecurityManager {
private static final CryptoAllPermission allPerm;
private static final Vector<Class<?>> TrustedCallersCache =
new Vector<>(2);
private static final Map<URL, CryptoPermissions> exemptCache =
new HashMap<>();
private static final ConcurrentMap<URL,CryptoPermissions> exemptCache =
new ConcurrentHashMap<>();
private static final CryptoPermissions CACHE_NULL_MARK =
new CryptoPermissions();
// singleton instance
static final JceSecurityManager INSTANCE;
......@@ -117,17 +121,19 @@ final class JceSecurityManager extends SecurityManager {
return defaultPerm;
}
CryptoPermissions appPerms;
synchronized (this.getClass()) {
if (exemptCache.containsKey(callerCodeBase)) {
CryptoPermissions appPerms = exemptCache.get(callerCodeBase);
if (appPerms == null) {
// no match found in cache
synchronized (this.getClass()) {
appPerms = exemptCache.get(callerCodeBase);
} else {
appPerms = getAppPermissions(callerCodeBase);
exemptCache.put(callerCodeBase, appPerms);
if (appPerms == null) {
appPerms = getAppPermissions(callerCodeBase);
exemptCache.putIfAbsent(callerCodeBase,
(appPerms == null? CACHE_NULL_MARK:appPerms));
}
}
}
if (appPerms == null) {
if (appPerms == null || appPerms == CACHE_NULL_MARK) {
return defaultPerm;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册