1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.oracle.security.ucrypto; 27 28 import java.io.IOException; 29 import java.util.HashMap; 30 import java.util.StringTokenizer; 31 import java.security.*; 32 import sun.security.action.PutAllAction; 33 import sun.security.action.GetPropertyAction; 34 35 /** 36 * OracleUcrypto provider main class. 37 * 38 * @since 1.9 39 */ 40 public final class UcryptoProvider extends Provider { 41 42 private static final long serialVersionUID = 351251234302833L; 43 44 private static boolean DEBUG; 45 private static HashMap<String, String> provProp; 46 47 static { 48 try { 49 DEBUG = Boolean.parseBoolean(AccessController.doPrivileged 50 (new GetPropertyAction("com.oracle.security.ucrypto.debug"))); 51 52 // cannot use LoadLibraryAction because that would make the native 53 // library available to the bootclassloader, but we run in the 54 // extension classloader. 55 provProp = AccessController.doPrivileged 56 (new PrivilegedAction<HashMap<String, String>>() { 57 public HashMap<String, String> run() { 58 try { 59 System.loadLibrary("j2ucrypto"); 60 String osname = System.getProperty("os.name"); 61 if (osname.startsWith("SunOS")) { 62 return new HashMap<String, String>(); 63 } else return null; 64 } catch (Error err) { 65 return null; 66 } catch (SecurityException se) { 67 return null; 68 } 69 } 70 }); 71 if (provProp != null) { 72 boolean[] result = loadLibraries(); 73 if (result.length == 2) { 74 if (result[0]) { // successfully loaded libmd 75 provProp.put("MessageDigest.MD5", 76 "com.oracle.security.ucrypto.NativeDigest$MD5"); 77 provProp.put("MessageDigest.SHA", 78 "com.oracle.security.ucrypto.NativeDigest$SHA1"); 79 provProp.put("Alg.Alias.MessageDigest.SHA-1", "SHA"); 80 provProp.put("Alg.Alias.MessageDigest.SHA1", "SHA"); 81 provProp.put("MessageDigest.SHA-256", 82 "com.oracle.security.ucrypto.NativeDigest$SHA256"); 83 provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.1", "SHA-256"); 84 provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.1", "SHA-256"); 85 86 provProp.put("MessageDigest.SHA-384", 87 "com.oracle.security.ucrypto.NativeDigest$SHA384"); 88 provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.2", "SHA-384"); 89 provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.2", "SHA-384"); 90 91 provProp.put("MessageDigest.SHA-512", 92 "com.oracle.security.ucrypto.NativeDigest$SHA512"); 93 provProp.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.3", "SHA-512"); 94 provProp.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.3", "SHA-512"); 95 96 } 97 if (result[1]) { // successfully loaded libsoftcrypto 98 String supportedMechs = getMechList(); 99 debug("Prov: supported mechs = " + supportedMechs); 100 for (UcryptoMech m : UcryptoMech.values()) { 101 if (supportedMechs.indexOf(m.name() + ",") != -1) { 102 String[] jceProps = m.jceProperties(); 103 // skip unsupported UcryptoMech 104 if (jceProps == null) continue; 105 for (int p = 0; p < jceProps.length; p++) { 106 StringTokenizer st = 107 new StringTokenizer(jceProps[p], ";"); 108 if (st.countTokens() != 2) { 109 throw new RuntimeException("Wrong format: " + jceProps[p]); 110 } 111 provProp.put(st.nextToken(), st.nextToken()); 112 } 113 } 114 } 115 // NOTE: GCM support is only available since jdk 7 116 provProp.put("AlgorithmParameters.GCM", 117 "com.oracle.security.ucrypto.GCMParameters"); 118 } 119 } else { 120 debug("Prov: unexpected ucrypto library loading error, got " + result.length); 121 } 122 } 123 } catch (AccessControlException ace) { 124 // disable Ucrypto provider 125 DEBUG = false; 126 provProp = null; 127 } 128 } 129 130 static Provider provider = null; 131 private static native boolean[] loadLibraries(); 132 private static native String getMechList(); 133 134 static void debug(String msg) { 135 if (DEBUG) { 136 System.out.println("UCrypto/" + msg); 137 } 138 } 139 140 public UcryptoProvider() { 141 super("OracleUcrypto", 1.9d, "Provider using Oracle Ucrypto API"); 142 if (provProp != null) { 143 AccessController.doPrivileged(new PutAllAction(this, provProp)); 144 } 145 if (provider == null) provider = this; 146 } 147 148 public UcryptoProvider(String configName) { 149 super("OracleUcrypto", 1.9d, "Provider using Oracle Ucrypto API"); 150 try { 151 if (provProp != null) { 152 HashMap<String, String> customProvProp = 153 new HashMap<String, String>(provProp); 154 Config c = new Config(configName); 155 String[] disabledServices = c.getDisabledServices(); 156 for (int i = 0; i < disabledServices.length; i++) { 157 if (customProvProp.remove(disabledServices[i]) != null) { 158 debug("Prov: remove config-disabled service " + disabledServices[i]); 159 } else { 160 debug("Prov: ignore unsupported config-disabled service " + 161 disabledServices[i]); 162 } 163 } 164 AccessController.doPrivileged(new PutAllAction(this, customProvProp)); 165 } 166 } catch (IOException ioe) { // thrown by Config 167 throw new UcryptoException("Error parsing Config", ioe); 168 } 169 if (provider == null) provider = this; 170 } 171 172 public boolean equals(Object obj) { 173 return this == obj; 174 } 175 176 public int hashCode() { 177 return System.identityHashCode(this); 178 } 179 }