src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java
Print this page
7191662: JCE providers should be located via ServiceLoader
*** 1,7 ****
/*
! * Copyright (c) 2014, 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) 2014, 2015, 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,38 ****
*/
package com.oracle.security.ucrypto;
import java.io.IOException;
! import java.util.HashMap;
! import java.util.StringTokenizer;
import java.security.*;
- import sun.security.action.PutAllAction;
- import sun.security.action.GetPropertyAction;
/**
* OracleUcrypto provider main class.
*
* @since 1.9
--- 24,36 ----
*/
package com.oracle.security.ucrypto;
import java.io.IOException;
! import java.io.File;
! import java.util.*;
import java.security.*;
/**
* OracleUcrypto provider main class.
*
* @since 1.9
*** 39,134 ****
*/
public final class UcryptoProvider extends Provider {
private static final long serialVersionUID = 351251234302833L;
! private static boolean DEBUG;
! private static HashMap<String, String> provProp;
static {
try {
- DEBUG = Boolean.parseBoolean(AccessController.doPrivileged
- (new GetPropertyAction("com.oracle.security.ucrypto.debug")));
-
// cannot use LoadLibraryAction because that would make the native
// library available to the bootclassloader, but we run in the
// extension classloader.
provProp = AccessController.doPrivileged
! (new PrivilegedAction<HashMap<String, String>>() {
! public HashMap<String, String> run() {
try {
System.loadLibrary("j2ucrypto");
! String osname = System.getProperty("os.name");
! if (osname.startsWith("SunOS")) {
! return new HashMap<String, String>();
! } else return null;
} catch (Error err) {
return null;
} catch (SecurityException se) {
return null;
}
}
});
if (provProp != null) {
boolean[] result = loadLibraries();
if (result.length == 2) {
if (result[0]) { // successfully loaded libmd
provProp.put("MessageDigest.MD5",
! "com.oracle.security.ucrypto.NativeDigest$MD5");
provProp.put("MessageDigest.SHA",
! "com.oracle.security.ucrypto.NativeDigest$SHA1");
! provProp.put("Alg.Alias.MessageDigest.SHA-1", "SHA");
! provProp.put("Alg.Alias.MessageDigest.SHA1", "SHA");
provProp.put("MessageDigest.SHA-256",
! "com.oracle.security.ucrypto.NativeDigest$SHA256");
! provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256");
! provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.1", "SHA-256");
provProp.put("MessageDigest.SHA-384",
! "com.oracle.security.ucrypto.NativeDigest$SHA384");
! provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384");
! provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.2", "SHA-384");
provProp.put("MessageDigest.SHA-512",
! "com.oracle.security.ucrypto.NativeDigest$SHA512");
! provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512");
! provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3", "SHA-512");
!
! }
if (result[1]) { // successfully loaded libsoftcrypto
String supportedMechs = getMechList();
debug("Prov: supported mechs = " + supportedMechs);
for (UcryptoMech m : UcryptoMech.values()) {
if (supportedMechs.indexOf(m.name() + ",") != -1) {
! String[] jceProps = m.jceProperties();
// skip unsupported UcryptoMech
! if (jceProps == null) continue;
! for (int p = 0; p < jceProps.length; p++) {
! StringTokenizer st =
! new StringTokenizer(jceProps[p], ";");
! if (st.countTokens() != 2) {
! throw new RuntimeException("Wrong format: " + jceProps[p]);
}
- provProp.put(st.nextToken(), st.nextToken());
}
}
- }
// NOTE: GCM support is only available since jdk 7
provProp.put("AlgorithmParameters.GCM",
! "com.oracle.security.ucrypto.GCMParameters");
}
} else {
debug("Prov: unexpected ucrypto library loading error, got " + result.length);
}
}
} catch (AccessControlException ace) {
// disable Ucrypto provider
- DEBUG = false;
provProp = null;
}
}
static Provider provider = null;
private static native boolean[] loadLibraries();
private static native String getMechList();
static void debug(String msg) {
--- 37,220 ----
*/
public final class UcryptoProvider extends Provider {
private static final long serialVersionUID = 351251234302833L;
! private static boolean DEBUG = false;
! private static HashMap<String, ServiceDesc> provProp = null;
! private static String defConfigName = "";
static {
try {
// cannot use LoadLibraryAction because that would make the native
// library available to the bootclassloader, but we run in the
// extension classloader.
+ String osname = System.getProperty("os.name");
+ if (osname.startsWith("SunOS")) {
provProp = AccessController.doPrivileged
! (new PrivilegedAction<HashMap<String, ServiceDesc>>() {
! public HashMap<String, ServiceDesc> run() {
try {
+ DEBUG = Boolean.parseBoolean(System.getProperty("com.oracle.security.ucrypto.debug"));
+ String javaHome = System.getProperty("java.home");
+ String sep = System.getProperty("file.separator");
+ defConfigName = javaHome + sep + "conf" + sep + "security" + sep +
+ "ucrypto-solaris.cfg";
System.loadLibrary("j2ucrypto");
! return new HashMap<>();
} catch (Error err) {
+ if (DEBUG) err.printStackTrace();
return null;
} catch (SecurityException se) {
+ if (DEBUG) se.printStackTrace();
return null;
}
}
});
+ }
if (provProp != null) {
boolean[] result = loadLibraries();
if (result.length == 2) {
if (result[0]) { // successfully loaded libmd
provProp.put("MessageDigest.MD5",
! sd("MessageDigest", "MD5",
! "com.oracle.security.ucrypto.NativeDigest$MD5"));
provProp.put("MessageDigest.SHA",
! sd("MessageDigest", "SHA",
! "com.oracle.security.ucrypto.NativeDigest$SHA1",
! "SHA-1", "SHA1"));
provProp.put("MessageDigest.SHA-256",
! sd("MessageDigest", "SHA-256",
! "com.oracle.security.ucrypto.NativeDigest$SHA256",
! "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"));
provProp.put("MessageDigest.SHA-384",
! sd("MessageDigest", "SHA-384",
! "com.oracle.security.ucrypto.NativeDigest$SHA384",
! "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"));
provProp.put("MessageDigest.SHA-512",
! sd("MessageDigest", "SHA-512",
! "com.oracle.security.ucrypto.NativeDigest$SHA512",
! "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"));
! };
if (result[1]) { // successfully loaded libsoftcrypto
String supportedMechs = getMechList();
debug("Prov: supported mechs = " + supportedMechs);
for (UcryptoMech m : UcryptoMech.values()) {
if (supportedMechs.indexOf(m.name() + ",") != -1) {
! ServiceDesc[] services = m.getServiceDescriptions();
// skip unsupported UcryptoMech
! if (services == null || services.length == 0) continue;
! for (int p = 0; p < services.length; p++) {
! ServiceDesc entry = services[p];
! provProp.put(entry.getType() + "." + entry.getAlgorithm(),
! entry);
}
}
}
// NOTE: GCM support is only available since jdk 7
provProp.put("AlgorithmParameters.GCM",
! sd("AlgorithmParameters", "GCM", "com.oracle.security.ucrypto.GCMParameters"));
}
} else {
debug("Prov: unexpected ucrypto library loading error, got " + result.length);
}
}
} catch (AccessControlException ace) {
+ if (DEBUG) ace.printStackTrace();
// disable Ucrypto provider
provProp = null;
}
}
+ private static ServiceDesc sd(String type, String algo, String cn,
+ String... aliases) {
+ return new ServiceDesc(type, algo, cn, aliases);
+ }
+
+ private static final class ProviderService extends Provider.Service {
+ ProviderService(Provider p, ServiceDesc sd) {
+ super(p, sd.getType(), sd.getAlgorithm(), sd.getClassName(),
+ sd.getAliases(), null);
+ }
+
+ @Override
+ public Object newInstance(Object ctrParamObj)
+ throws NoSuchAlgorithmException {
+ String type = getType();
+ if (ctrParamObj != null) {
+ throw new InvalidParameterException
+ ("constructorParameter not used with " + type + " engines");
+ }
+ String algo = getAlgorithm();
+ try {
+ if (type.equals("Cipher")) {
+ int keySize = -1;
+ if (algo.charAt(3) == '_') {
+ keySize = Integer.parseInt(algo.substring(4, 7))/8;
+ algo = algo.substring(0, 3) + algo.substring(7);
+ }
+ if (algo.equals("AES/ECB/NoPadding")) {
+ return new NativeCipher.AesEcbNoPadding(keySize);
+ } else if (algo.equals("AES/ECB/PKCS5Padding")) {
+ return new NativeCipherWithJavaPadding.AesEcbPKCS5();
+ } else if (algo.equals("AES/CBC/NoPadding")) {
+ return new NativeCipher.AesCbcNoPadding(keySize);
+ } else if (algo.equals("AES/CBC/PKCS5Padding")) {
+ return new NativeCipherWithJavaPadding.AesCbcPKCS5();
+ } else if (algo.equals("AES/CTR/NoPadding")) {
+ return new NativeCipher.AesCtrNoPadding();
+ } else if (algo.equals("AES/GCM/NoPadding")) {
+ return new NativeGCMCipher.AesGcmNoPadding(keySize);
+ } else if (algo.equals("AES/CFB128/NoPadding")) {
+ return new NativeCipher.AesCfb128NoPadding();
+ } else if (algo.equals("AES/CFB128/PKCS5Padding")) {
+ return new NativeCipherWithJavaPadding.AesCfb128PKCS5();
+ } else if (algo.equals("RSA/ECB/NoPadding")) {
+ return new NativeRSACipher.NoPadding();
+ } else if (algo.equals("RSA/ECB/PKCS1Padding")) {
+ return new NativeRSACipher.PKCS1Padding();
+ }
+ } else if (type.equals("Signature")) {
+ if (algo.equals("SHA1withRSA")) {
+ return new NativeRSASignature.SHA1();
+ } else if (algo.equals("SHA256withRSA")) {
+ return new NativeRSASignature.SHA256();
+ } else if (algo.equals("SHA384withRSA")) {
+ return new NativeRSASignature.SHA384();
+ } else if (algo.equals("SHA512withRSA")) {
+ return new NativeRSASignature.SHA512();
+ } else if (algo.equals("MD5withRSA")) {
+ return new NativeRSASignature.MD5();
+ }
+ } else if (type.equals("MessageDigest")) {
+ if (algo.equals("SHA")) {
+ return new NativeDigest.SHA1();
+ } else if (algo.equals("SHA-256")) {
+ return new NativeDigest.SHA256();
+ } else if (algo.equals("SHA-384")) {
+ return new NativeDigest.SHA384();
+ } else if (algo.equals("SHA-512")) {
+ return new NativeDigest.SHA512();
+ } else if (algo.equals("MD5")) {
+ return new NativeDigest.MD5();
+ }
+ } else if (type.equals("AlgorithmParameters")) {
+ if (algo.equals("GCM")) {
+ return new GCMParameters();
+ }
+ }
+ } catch (Exception ex) {
+ throw new NoSuchAlgorithmException("Error constructing " +
+ type + " for " + algo + " using OracleUcrypto", ex);
+ }
+ throw new ProviderException("No impl for " + algo +
+ " " + type);
+ }
+ }
+
static Provider provider = null;
private static native boolean[] loadLibraries();
private static native String getMechList();
static void debug(String msg) {
*** 137,176 ****
}
}
public UcryptoProvider() {
super("OracleUcrypto", 1.9d, "Provider using Oracle Ucrypto API");
! if (provProp != null) {
! AccessController.doPrivileged(new PutAllAction(this, provProp));
}
if (provider == null) provider = this;
}
! public UcryptoProvider(String configName) {
! super("OracleUcrypto", 1.9d, "Provider using Oracle Ucrypto API");
! try {
if (provProp != null) {
! HashMap<String, String> customProvProp =
! new HashMap<String, String>(provProp);
! Config c = new Config(configName);
String[] disabledServices = c.getDisabledServices();
! for (int i = 0; i < disabledServices.length; i++) {
! if (customProvProp.remove(disabledServices[i]) != null) {
! debug("Prov: remove config-disabled service " + disabledServices[i]);
} else {
! debug("Prov: ignore unsupported config-disabled service " +
! disabledServices[i]);
}
}
! AccessController.doPrivileged(new PutAllAction(this, customProvProp));
}
- } catch (IOException ioe) { // thrown by Config
- throw new UcryptoException("Error parsing Config", ioe);
}
- if (provider == null) provider = this;
}
public boolean equals(Object obj) {
return this == obj;
}
public int hashCode() {
--- 223,289 ----
}
}
public UcryptoProvider() {
super("OracleUcrypto", 1.9d, "Provider using Oracle Ucrypto API");
!
! AccessController.doPrivileged(new PrivilegedAction<>() {
! public Void run() {
! init(defConfigName);
! return null;
}
+ });
if (provider == null) provider = this;
}
! private void init(final String configName) {
if (provProp != null) {
! debug("Prov: configuration file " + configName);
! Config c;
! try {
! c = new Config(configName);
! } catch (Exception ex) {
! throw new UcryptoException("Error parsing Config", ex);
! }
!
String[] disabledServices = c.getDisabledServices();
! for (String ds : disabledServices) {
! if (provProp.remove(ds) != null) {
! debug("Prov: remove config-disabled service " + ds);
} else {
! debug("Prov: ignore unsupported service " + ds);
}
}
!
! for (ServiceDesc s: provProp.values()) {
! debug("Prov: add service for " + s);
! putService(new ProviderService(this, s));
}
}
}
+ @Override
+ public Provider configure(String configArg) throws InvalidParameterException {
+ if (!defConfigName.equals(configArg)) {
+ throw new InvalidParameterException("Ucrypto provider can only be " +
+ "configured with default configuration file");
+ }
+ return this;
+ }
+
+ @Override
+ public String getArgument() {
+ try {
+ if (new File(defConfigName).canRead()) {
+ return defConfigName;
+ }
+ } catch (SecurityException se) {
+ debug("Prov: no perm to read config");
+ }
+ return "";
+ }
+
public boolean equals(Object obj) {
return this == obj;
}
public int hashCode() {