1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.apache.commons.crypto.utils;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.net.URL;
24 import java.security.GeneralSecurityException;
25 import java.util.ArrayList;
26 import java.util.Enumeration;
27 import java.util.List;
28 import java.util.Objects;
29 import java.util.Properties;
30
31 import org.apache.commons.crypto.Crypto;
32 import org.apache.commons.crypto.cipher.CryptoCipher;
33 import org.apache.commons.crypto.cipher.CryptoCipherFactory;
34
35 /**
36 * General utility methods.
37 */
38 public final class Utils {
39
40 private static class DefaultPropertiesHolder {
41 static final Properties DEFAULT_PROPERTIES = createDefaultProperties();
42
43 /**
44 * Loads system properties when configuration file of the name
45 * {@link #SYSTEM_PROPERTIES_FILE} is found.
46 *
47 * @return the default properties
48 */
49 private static Properties createDefaultProperties() {
50 // default to system
51 final Properties defaultedProps = new Properties(System.getProperties());
52 final URL url = Thread.currentThread().getContextClassLoader().getResource(SYSTEM_PROPERTIES_FILE);
53 if (url == null) {
54 // Fail early when the resource is not found which makes SpotBugs happy on Java 17.
55 return defaultedProps;
56 }
57 try {
58 final Properties fileProps = new Properties();
59 try (InputStream is = url.openStream()) {
60 fileProps.load(is);
61 }
62 final Enumeration<?> names = fileProps.propertyNames();
63 while (names.hasMoreElements()) {
64 final String name = (String) names.nextElement();
65 // ensure System properties override ones in the file so one can override the file on the command line
66 if (System.getProperty(name) == null) {
67 defaultedProps.setProperty(name, fileProps.getProperty(name));
68 }
69 }
70 } catch (final Exception ex) {
71 System.err.println("Could not load '" + SYSTEM_PROPERTIES_FILE + "' from classpath: " + ex.toString());
72 }
73 return defaultedProps;
74 }
75 }
76
77 /**
78 * The file name of configuration file.
79 */
80 private static final String SYSTEM_PROPERTIES_FILE = Crypto.CONF_PREFIX + "properties";
81
82 /**
83 * Ensures the truth of an expression involving one or more parameters to
84 * the calling method.
85 *
86 * @param expression a boolean expression.
87 * @throws IllegalArgumentException if expression is false.
88 */
89 public static void checkArgument(final boolean expression) {
90 if (!expression) {
91 throw new IllegalArgumentException();
92 }
93 }
94
95 /**
96 * Checks the truth of an expression.
97 *
98 * @param expression a boolean expression.
99 * @param errorMessage the exception message to use if the check fails; will
100 * be converted to a string using <code>String
101 * .valueOf(Object)</code>.
102 * @throws IllegalArgumentException if expression is false.
103 */
104 public static void checkArgument(final boolean expression, final Object errorMessage) {
105 if (!expression) {
106 throw new IllegalArgumentException(String.valueOf(errorMessage));
107 }
108 }
109
110 /**
111 * Ensures that an object reference passed as a parameter to the calling
112 * method is not null.
113 *
114 * @param <T> the type of the object reference to be checked.
115 * @param reference an object reference.
116 * @return the non-null reference that was validated.
117 * @throws NullPointerException if reference is null.
118 * @deprecated Use {@link Objects#requireNonNull(Object)}.
119 */
120 @Deprecated
121 public static <T> T checkNotNull(final T reference) {
122 return Objects.requireNonNull(reference, "reference");
123 }
124
125 /**
126 * Ensures the truth of an expression involving the state of the calling
127 * instance, but not involving any parameters to the calling method.
128 *
129 * @param expression a boolean expression.
130 * @throws IllegalStateException if expression is false.
131 */
132 public static void checkState(final boolean expression) {
133 checkState(expression, null);
134 }
135
136 /**
137 * Ensures the truth of an expression involving the state of the calling
138 * instance, but not involving any parameters to the calling method.
139 *
140 * @param expression a boolean expression.
141 * @param message Error message for the exception when the expression is false.
142 * @throws IllegalStateException if expression is false.
143 */
144 public static void checkState(final boolean expression, final String message) {
145 if (!expression) {
146 throw new IllegalStateException(message);
147 }
148 }
149
150 /**
151 * Helper method to create a CryptoCipher instance and throws only
152 * IOException.
153 *
154 * @param properties The {@code Properties} class represents a set of
155 * properties.
156 * @param transformation the name of the transformation, e.g.,
157 * <i>AES/CBC/PKCS5Padding</i>.
158 * See the Java Cryptography Architecture Standard Algorithm Name Documentation
159 * for information about standard transformation names.
160 * @return the CryptoCipher instance.
161 * @throws IOException if an I/O error occurs.
162 */
163 public static CryptoCipher getCipherInstance(final String transformation, final Properties properties) throws IOException {
164 try {
165 return CryptoCipherFactory.getCryptoCipher(transformation, properties);
166 } catch (final GeneralSecurityException e) {
167 throw new IOException(e);
168 }
169 }
170
171 /**
172 * Gets a properties instance that defaults to the System Properties
173 * plus any other properties found in the file
174 * {@link #SYSTEM_PROPERTIES_FILE}
175 * @return a Properties instance with defaults
176 */
177 public static Properties getDefaultProperties() {
178 return new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES);
179 }
180
181 /**
182 * Gets the properties merged with default properties.
183 * @param newProp User-defined properties
184 * @return User-defined properties with the default properties
185 */
186 public static Properties getProperties(final Properties newProp) {
187 final Properties properties = new Properties(DefaultPropertiesHolder.DEFAULT_PROPERTIES);
188 properties.putAll(newProp);
189 return properties;
190 }
191
192 /*
193 * Override the default DLL name if jni.library.path is a valid directory
194 * @param name - the default name, passed from native code
195 * @return the updated library path
196 * This method is designed for use from the DynamicLoader native code.
197 * Although it could all be implemented in native code, this hook method
198 * makes maintenance easier.
199 * The code is intended for use with macOS where SIP makes it hard to override
200 * the environment variables needed to override the DLL search path. It also
201 * works for Linux, but is not (currently) used or needed for Windows.
202 * Do not change the method name or its signature!
203 */
204 static String libraryPath(final String name) {
205 final String override = System.getProperty("jni.library.path");
206 if (override != null && new File(override).isDirectory()) {
207 return new File(override, name).getPath();
208 }
209 return name;
210 }
211
212 /**
213 * Splits class names sequence into substrings, Trim each substring into an
214 * entry,and returns an list of the entries.
215 *
216 * @param clazzNames a string consist of a list of the entries joined by a
217 * delimiter, may be null or empty in which case an empty list is returned.
218 * @param separator a delimiter for the input string.
219 * @return a list of class entries.
220 */
221 public static List<String> splitClassNames(final String clazzNames, final String separator) {
222 final List<String> res = new ArrayList<>();
223 if (clazzNames == null || clazzNames.isEmpty()) {
224 return res;
225 }
226
227 for (String clazzName : clazzNames.split(separator)) {
228 clazzName = clazzName.trim();
229 if (!clazzName.isEmpty()) {
230 res.add(clazzName);
231 }
232 }
233 return res;
234 }
235
236 /**
237 * The private constructor of {@link Utils}.
238 */
239 private Utils() {
240 }
241
242 }