|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.pkcs11; |
|
|
|
import java.util.*; |
|
import java.util.concurrent.*; |
|
|
|
import sun.security.pkcs11.wrapper.*; |
|
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final class TemplateManager { |
|
|
|
private final static boolean DEBUG = false; |
|
|
|
|
|
final static String O_ANY = "*"; |
|
|
|
final static String O_IMPORT = "import"; |
|
|
|
final static String O_GENERATE = "generate"; |
|
|
|
private static class KeyAndTemplate { |
|
final TemplateKey key; |
|
final Template template; |
|
|
|
KeyAndTemplate(TemplateKey key, Template template) { |
|
this.key = key; |
|
this.template = template; |
|
} |
|
} |
|
|
|
// primitive templates contains the individual template configuration |
|
|
|
private final List<KeyAndTemplate> primitiveTemplates; |
|
|
|
// composite templates is a cache of the exact configuration template for |
|
// each specific TemplateKey (no wildcards). the entries are created |
|
// on demand during first use by compositing all applicable |
|
// primitive template entries. the result is then stored in this map |
|
|
|
private final Map<TemplateKey,Template> compositeTemplates; |
|
|
|
TemplateManager() { |
|
primitiveTemplates = new ArrayList<KeyAndTemplate>(); |
|
compositeTemplates = new ConcurrentHashMap<TemplateKey,Template>(); |
|
} |
|
|
|
|
|
void addTemplate(String op, long objectClass, long keyAlgorithm, |
|
CK_ATTRIBUTE[] attrs) { |
|
TemplateKey key = new TemplateKey(op, objectClass, keyAlgorithm); |
|
Template template = new Template(attrs); |
|
if (DEBUG) { |
|
System.out.println("Adding " + key + " -> " + template); |
|
} |
|
primitiveTemplates.add(new KeyAndTemplate(key, template)); |
|
} |
|
|
|
private Template getTemplate(TemplateKey key) { |
|
Template template = compositeTemplates.get(key); |
|
if (template == null) { |
|
template = buildCompositeTemplate(key); |
|
compositeTemplates.put(key, template); |
|
} |
|
return template; |
|
} |
|
|
|
// Get the attributes for the requested op and combine them with attrs. |
|
// This is the method called by the implementation to obtain the |
|
|
|
CK_ATTRIBUTE[] getAttributes(String op, long type, long alg, |
|
CK_ATTRIBUTE[] attrs) { |
|
TemplateKey key = new TemplateKey(op, type, alg); |
|
Template template = getTemplate(key); |
|
CK_ATTRIBUTE[] newAttrs = template.getAttributes(attrs); |
|
if (DEBUG) { |
|
System.out.println(key + " -> " + Arrays.asList(newAttrs)); |
|
} |
|
return newAttrs; |
|
} |
|
|
|
|
|
private Template buildCompositeTemplate(TemplateKey key) { |
|
Template comp = new Template(); |
|
|
|
for (KeyAndTemplate entry : primitiveTemplates) { |
|
if (entry.key.appliesTo(key)) { |
|
comp.add(entry.template); |
|
} |
|
} |
|
return comp; |
|
} |
|
|
|
|
|
|
|
*/ |
|
private static final class TemplateKey { |
|
final String operation; |
|
final long keyType; |
|
final long keyAlgorithm; |
|
TemplateKey(String operation, long keyType, long keyAlgorithm) { |
|
this.operation = operation; |
|
this.keyType = keyType; |
|
this.keyAlgorithm = keyAlgorithm; |
|
} |
|
public boolean equals(Object obj) { |
|
if (this == obj) { |
|
return true; |
|
} |
|
if (obj instanceof TemplateKey == false) { |
|
return false; |
|
} |
|
TemplateKey other = (TemplateKey)obj; |
|
boolean match = this.operation.equals(other.operation) |
|
&& (this.keyType == other.keyType) |
|
&& (this.keyAlgorithm == other.keyAlgorithm); |
|
return match; |
|
} |
|
public int hashCode() { |
|
return operation.hashCode() + (int)keyType + (int)keyAlgorithm; |
|
} |
|
boolean appliesTo(TemplateKey key) { |
|
if (operation.equals(O_ANY) || operation.equals(key.operation)) { |
|
if ((keyType == PCKO_ANY) || (keyType == key.keyType)) { |
|
if ((keyAlgorithm == PCKK_ANY) |
|
|| (keyAlgorithm == key.keyAlgorithm)) { |
|
return true; |
|
} |
|
} |
|
} |
|
return false; |
|
} |
|
public String toString() { |
|
return "(" + operation + "," |
|
+ Functions.getObjectClassName(keyType) |
|
+ "," + Functions.getKeyName(keyAlgorithm) + ")"; |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
private static final class Template { |
|
|
|
private final static CK_ATTRIBUTE[] A0 = new CK_ATTRIBUTE[0]; |
|
|
|
private CK_ATTRIBUTE[] attributes; |
|
|
|
Template() { |
|
attributes = A0; |
|
} |
|
|
|
Template(CK_ATTRIBUTE[] attributes) { |
|
this.attributes = attributes; |
|
} |
|
|
|
void add(Template template) { |
|
attributes = getAttributes(template.attributes); |
|
} |
|
|
|
CK_ATTRIBUTE[] getAttributes(CK_ATTRIBUTE[] attrs) { |
|
return combine(attributes, attrs); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static CK_ATTRIBUTE[] combine(CK_ATTRIBUTE[] attrs1, |
|
CK_ATTRIBUTE[] attrs2) { |
|
List<CK_ATTRIBUTE> attrs = new ArrayList<CK_ATTRIBUTE>(); |
|
for (CK_ATTRIBUTE attr : attrs1) { |
|
if (attr.pValue != null) { |
|
attrs.add(attr); |
|
} |
|
} |
|
for (CK_ATTRIBUTE attr2 : attrs2) { |
|
long type = attr2.type; |
|
for (CK_ATTRIBUTE attr1 : attrs1) { |
|
if (attr1.type == type) { |
|
attrs.remove(attr1); |
|
} |
|
} |
|
if (attr2.pValue != null) { |
|
attrs.add(attr2); |
|
} |
|
} |
|
return attrs.toArray(A0); |
|
} |
|
|
|
public String toString() { |
|
return Arrays.asList(attributes).toString(); |
|
} |
|
|
|
} |
|
|
|
} |