View Javadoc
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  
19  package org.apache.commons.crypto.jna;
20  
21  import java.nio.ByteBuffer;
22  
23  import org.apache.commons.crypto.Crypto;
24  
25  import com.sun.jna.Function;
26  import com.sun.jna.NativeLibrary;
27  import com.sun.jna.NativeLong;
28  import com.sun.jna.ptr.PointerByReference;
29  
30  final class OpenSslNativeJna {
31  
32      static final int OPENSSL_INIT_ENGINE_RDRAND = 0x00000200;
33  
34      static final int OOSL_JNA_ENCRYPT_MODE = 1;
35      static final int OOSL_JNA_DECRYPT_MODE = 0;
36  
37      static final boolean INIT_OK;
38  
39      static final Throwable INIT_ERROR;
40  
41      /** Full version from JNA call. */
42      static final long VERSION;
43  
44      /** Major Minor version from JNA call, without the maintenance level. */
45      static final long VERSION_X_Y;
46  
47      static final long VERSION_1_0_X = 0x10000000;
48      static final long VERSION_1_1_X = 0x10100000;
49      static final long VERSION_2_0_X = 0x20000000;
50      static final long VERSION_3_0_X = 0x30000000;
51  
52      private static final OpenSslInterfaceNativeJna JnaImplementation;
53  
54      static {
55          OpenSslJna.debug("OpenSslNativeJna static init start");
56          final String libraryName = System.getProperty(Crypto.CONF_PREFIX + OpenSslNativeJna.class.getSimpleName(), "crypto");
57          OpenSslJna.debug("OpenSslNativeJna NativeLibrary.getInstance('%s')", libraryName);
58          @SuppressWarnings("resource") // NativeLibrary.getInstance returns a singleton
59          final NativeLibrary crypto = NativeLibrary.getInstance(libraryName);
60          OpenSslJna.debug("OpenSslNativeJna NativeLibrary.getInstance('%s') -> %s", libraryName, crypto);
61          Function versionFunction = null;
62          try {
63              versionFunction = crypto.getFunction("SSLeay");
64          } catch (final UnsatisfiedLinkError e) {
65              versionFunction = crypto.getFunction("OpenSSL_version_num");
66          }
67          // Must find one of the above two functions; else give up
68  
69          VERSION = versionFunction.invokeLong(new Object[]{});
70          OpenSslJna.debug(String.format("OpenSslNativeJna detected version 0x%x", VERSION));
71  
72          VERSION_X_Y = VERSION & 0xffff0000; // keep only major.minor
73          if (VERSION_X_Y == VERSION_1_0_X) {
74              OpenSslJna.debug("Creating OpenSsl10XNativeJna");
75              JnaImplementation = new OpenSsl10XNativeJna();
76          } else if (VERSION_X_Y == VERSION_1_1_X) {
77              OpenSslJna.debug("Creating OpenSsl11XNativeJna");
78              JnaImplementation = new OpenSsl11XNativeJna();
79          } else if (VERSION_X_Y == VERSION_2_0_X) {
80              OpenSslJna.debug("Creating OpenSsl20XNativeJna");
81              JnaImplementation = new OpenSsl20XNativeJna();
82  //        } else if (VERSION_X_Y == VERSION_3_0_X) {
83  //            OpenSslJna.debug("Creating OpenSsl30XNativeJna");
84  //            JnaImplementation = new OpenSsl30XNativeJna();
85          } else {
86              // TODO: Throw error?
87              OpenSslJna.debug("Creating OpenSsl10XNativeJna");
88              JnaImplementation = new OpenSsl10XNativeJna();
89          }
90  
91          INIT_OK = JnaImplementation._INIT_OK();
92  
93          INIT_ERROR = INIT_OK ? null : JnaImplementation._INIT_ERROR();
94          OpenSslJna.debug("OpenSslNativeJna INIT_OK = %s, INIT_ERROR = '%s', JnaImplementation = %s", INIT_OK, INIT_ERROR, JnaImplementation.getClass());
95          OpenSslJna.debug("OpenSslNativeJna static init end");
96      }
97  
98      public static PointerByReference ENGINE_by_id(final String string) {
99          return JnaImplementation._ENGINE_by_id(string);
100     }
101 
102     public static int ENGINE_cleanup() {
103         return JnaImplementation._ENGINE_cleanup();
104     }
105 
106     public static int ENGINE_finish(final PointerByReference rdrandEngine) {
107         return JnaImplementation._ENGINE_finish(rdrandEngine);
108     }
109 
110     public static int ENGINE_free(final PointerByReference rdrandEngine) {
111         return JnaImplementation._ENGINE_free(rdrandEngine);
112     }
113 
114     public static int ENGINE_init(final PointerByReference rdrandEngine) {
115         return JnaImplementation._ENGINE_init(rdrandEngine);
116     }
117 
118     public static void ENGINE_load_rdrand() {
119         JnaImplementation._ENGINE_load_rdrand();
120     }
121 
122     public static int ENGINE_set_default(final PointerByReference rdrandEngine, final int eNGINE_METHOD_RAND) {
123         return JnaImplementation._ENGINE_set_default(rdrandEngine, eNGINE_METHOD_RAND);
124     }
125 
126     public static String ERR_error_string(final NativeLong err, final char[] object) {
127         return JnaImplementation._ERR_error_string(err, null);
128     }
129 
130     public static NativeLong ERR_peek_error() {
131         return JnaImplementation._ERR_peek_error();
132     }
133 
134     public static PointerByReference EVP_aes_128_cbc() {
135         return JnaImplementation._EVP_aes_128_cbc();
136     }
137 
138     public static PointerByReference EVP_aes_128_ctr() {
139         return JnaImplementation._EVP_aes_128_ctr();
140     }
141 
142     public static PointerByReference EVP_aes_192_cbc() {
143         return JnaImplementation._EVP_aes_192_cbc();
144     }
145 
146     public static PointerByReference EVP_aes_192_ctr() {
147         return JnaImplementation._EVP_aes_192_ctr();
148     }
149 
150     public static PointerByReference EVP_aes_256_cbc() {
151         return JnaImplementation._EVP_aes_256_cbc();
152     }
153 
154     public static PointerByReference EVP_aes_256_ctr() {
155         return JnaImplementation._EVP_aes_256_ctr();
156     }
157 
158     public static void EVP_CIPHER_CTX_cleanup(final PointerByReference context) {
159         JnaImplementation._EVP_CIPHER_CTX_cleanup(context);
160     }
161 
162     public static void EVP_CIPHER_CTX_free(final PointerByReference context) {
163         JnaImplementation._EVP_CIPHER_CTX_free(context);
164     }
165 
166     public static PointerByReference EVP_CIPHER_CTX_new() {
167         return JnaImplementation._EVP_CIPHER_CTX_new();
168     }
169 
170     public static int EVP_CIPHER_CTX_set_padding(final PointerByReference context, final int padding) {
171         return JnaImplementation._EVP_CIPHER_CTX_set_padding(context, padding);
172     }
173 
174     public static int EVP_CipherFinal_ex(final PointerByReference context, final ByteBuffer outBuffer,
175             final int[] outlen) {
176         return JnaImplementation._EVP_CipherFinal_ex(context, outBuffer, outlen);
177     }
178 
179     public static int EVP_CipherInit_ex(final PointerByReference context, final PointerByReference algo,
180             final Object object, final byte[] encoded, final byte[] iv, final int cipherMode) {
181         return JnaImplementation._EVP_CipherInit_ex(context, algo, null, encoded, iv, cipherMode);
182     }
183 
184     public static int EVP_CipherUpdate(final PointerByReference context, final ByteBuffer outBuffer,
185             final int[] outlen, final ByteBuffer inBuffer, final int remaining) {
186         return JnaImplementation._EVP_CipherUpdate(context, outBuffer, outlen, inBuffer, remaining);
187     }
188 
189     public static String OpenSSLVersion(final int i) {
190         return JnaImplementation._OpenSSL_version(i);
191     }
192 
193     public static int RAND_bytes(final ByteBuffer buf, final int length) {
194         return JnaImplementation._RAND_bytes(buf, length);
195     }
196 
197     public static PointerByReference RAND_get_rand_method() {
198         return JnaImplementation._RAND_get_rand_method();
199     }
200 
201     public static PointerByReference RAND_SSLeay() {
202         return JnaImplementation._RAND_SSLeay();
203     }
204 
205     private OpenSslNativeJna() {
206     }
207 }