001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.commons.crypto; 019 020import java.io.IOException; 021import java.io.InputStream; 022import java.net.URL; 023import java.util.Properties; 024 025import org.apache.commons.crypto.cipher.CryptoCipher; 026import org.apache.commons.crypto.cipher.CryptoCipherFactory; 027import org.apache.commons.crypto.random.CryptoRandom; 028import org.apache.commons.crypto.random.CryptoRandomFactory; 029 030/** 031 * Provides diagnostic information about Commons Crypto and keys for native 032 * class loading 033 */ 034public final class Crypto { 035 036 private static class ComponentPropertiesHolder { 037 038 static final Properties PROPERTIES = getComponentProperties(); 039 040 /** 041 * Get component properties from component.properties. 042 * 043 * @return Properties contains project version. 044 */ 045 private static Properties getComponentProperties() { 046 final URL url = Crypto.class.getResource("/org/apache/commons/crypto/component.properties"); 047 final Properties versionData = new Properties(); 048 if (url != null) { 049 try (InputStream inputStream = url.openStream()) { 050 versionData.load(inputStream); 051 return versionData; 052 } catch (final IOException e) { // NOPMD 053 } 054 } 055 return versionData; 056 } 057 } 058 059 /** 060 * The prefix of all crypto configuration keys. 061 */ 062 public static final String CONF_PREFIX = "commons.crypto."; 063 064 /** 065 * The configuration key of the file name for loading crypto library. 066 */ 067 068 public static final String LIB_NAME_KEY = Crypto.CONF_PREFIX + "lib.name"; 069 070 // native lib related configuration keys 071 /** 072 * The configuration key of the path for loading crypto library. 073 */ 074 public static final String LIB_PATH_KEY = Crypto.CONF_PREFIX + "lib.path"; 075 076 /** 077 * The configuration key of temp directory for extracting crypto library. 078 * Defaults to "java.io.tempdir" if not found. 079 */ 080 public static final String LIB_TEMPDIR_KEY = Crypto.CONF_PREFIX + "lib.tempdir"; 081 082 /** 083 * Gets the component version of Apache Commons Crypto. 084 * <p> 085 * This implementation relies on the VERSION properties file which must be set 086 * up with the correct contents by the build process. This is done automatically 087 * by Maven. 088 * </p> 089 * 090 * @return the version; may be null if not found 091 */ 092 public static String getComponentName() { 093 // Note: the component properties file allows the method to work without needing 094 // the jar 095 return ComponentPropertiesHolder.PROPERTIES.getProperty("NAME"); 096 } 097 098 /** 099 * Gets the component version of Apache Commons Crypto. 100 * <p> 101 * This implementation relies on the VERSION properties file which must be set 102 * up with the correct contents by the build process. This is done automatically 103 * by Maven. 104 * </p> 105 * 106 * @return the version; may be null if not found 107 */ 108 public static String getComponentVersion() { 109 // Note: the component properties file allows the method to work without needing 110 // the jar 111 return ComponentPropertiesHolder.PROPERTIES.getProperty("VERSION"); 112 } 113 114 /** 115 * The loading error throwable, if loading failed. 116 * 117 * @return null, unless loading failed. 118 */ 119 public static Throwable getLoadingError() { 120 return NativeCodeLoader.getLoadingError(); 121 } 122 123 /** 124 * Logs info-level messages. 125 * 126 * @param format See {@link String#format(String, Object...)}. 127 * @param args See {@link String#format(String, Object...)}. 128 */ 129 private static void info(final String format, final Object... args) { 130 // TODO Find a better way to do this later. 131 System.out.println(String.format(format, args)); 132 } 133 134 /** 135 * Checks whether the native code has been successfully loaded for the platform. 136 * 137 * @return true if the native code has been loaded successfully. 138 */ 139 public static boolean isNativeCodeLoaded() { 140 return NativeCodeLoader.isNativeCodeLoaded(); 141 } 142 143 /** 144 * The Main of Crypto. 145 * 146 * @param args Not used. 147 * @throws Exception if getCryptoRandom or getCryptoCipher get error. 148 */ 149 public static void main(final String args[]) throws Exception { 150 info("%s %s", getComponentName(), getComponentVersion()); 151 if (isNativeCodeLoaded()) { 152 info("Native code loaded OK: %s", OpenSslInfoNative.NativeVersion()); 153 info("Native name: %s", OpenSslInfoNative.NativeName()); 154 info("Native built: %s", OpenSslInfoNative.NativeTimeStamp()); 155 info("OpenSSL library loaded OK, version: 0x%s", Long.toHexString(OpenSslInfoNative.OpenSSL())); 156 info("OpenSSL library info: %s", OpenSslInfoNative.OpenSSLVersion(0)); 157 { // CryptoRandom 158 final Properties props = new Properties(); 159 props.setProperty(CryptoRandomFactory.CLASSES_KEY, 160 CryptoRandomFactory.RandomProvider.OPENSSL.getClassName()); 161 try (CryptoRandom cryptoRandom = CryptoRandomFactory.getCryptoRandom(props)) { 162 info("Random instance created OK: %s", cryptoRandom); 163 } 164 } 165 { // CryptoCipher 166 final Properties props = new Properties(); 167 props.setProperty(CryptoCipherFactory.CLASSES_KEY, 168 CryptoCipherFactory.CipherProvider.OPENSSL.getClassName()); 169 final String transformation = "AES/CTR/NoPadding"; 170 try (CryptoCipher cryptoCipher = CryptoCipherFactory.getCryptoCipher(transformation, props)) { 171 info("Cipher %s instance created OK: %s", transformation, cryptoCipher); 172 } 173 } 174 info("Additional OpenSSL_version(n) details:"); 175 for (int j = 1; j < 6; j++) { 176 info("%s: %s", j, OpenSslInfoNative.OpenSSLVersion(j)); 177 } 178 } else { 179 info("Native load failed: %s", getLoadingError()); 180 } 181 } 182 183}