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.Native;
26  import com.sun.jna.NativeLong;
27  import com.sun.jna.ptr.PointerByReference;
28  
29  final class OpenSsl11XNativeJna  implements OpenSslInterfaceNativeJna {
30  
31      static final boolean INIT_OK;
32  
33      static final Throwable INIT_ERROR;
34  
35      static {
36          boolean ok = false;
37          Throwable thrown = null;
38          try {
39              final String libName = System.getProperty(Crypto.CONF_PREFIX + OpenSslNativeJna.class.getSimpleName(), "crypto");
40              OpenSslJna.debug("Native.register('%s')", libName);
41              Native.register(libName);
42              ok = true;
43          } catch (final Exception | UnsatisfiedLinkError e) {
44              thrown = e;
45          } finally {
46              INIT_OK = ok;
47              INIT_ERROR = thrown;
48          }
49      }
50  
51      // Try to keep methods aligned across versions
52  
53      /**
54       * Gets engine by id
55       *
56       * @param id
57       *            engine id
58       * @return engine instance
59       */
60      public static native PointerByReference ENGINE_by_id(String id);
61  
62      /**
63       * Releases all functional references.
64       *
65       * @param e
66       *            engine reference.
67       * @return 0 on success, 1 otherwise.
68       */
69      public static native int ENGINE_finish(PointerByReference e);
70  
71      /**
72       * Frees the structural reference
73       *
74       * @param e
75       *            engine reference.
76       * @return 0 on success, 1 otherwise.
77       */
78      public static native int ENGINE_free(PointerByReference e);
79  
80      /**
81       * Obtains a functional reference from an existing structural reference.
82       *
83       * @param e
84       *            engine reference
85       * @return zero if the ENGINE was not already operational and couldn't be successfully
86       *         initialized
87       */
88      public static native int ENGINE_init(PointerByReference e);
89  
90      /**
91       * Sets the engine as the default for random number generation.
92       *
93       * @param e
94       *            engine reference
95       * @param flags
96       *            ENGINE_METHOD_RAND
97       * @return zero if failed.
98       */
99      public static native int ENGINE_set_default(PointerByReference e, int flags);
100 
101     /**
102      * Generates a human-readable string representing the error code e.
103      *
104      * @see <a href="https://www.openssl.org/docs/man1.1.0/man3/ERR_error_string.html">ERR_error_string</a>
105      *
106      * @param err
107      *            the error code
108      * @param null_
109      *            buf is NULL, the error string is placed in a static buffer
110      * @return the human-readable error messages.
111      */
112     public static native String ERR_error_string(NativeLong err, char[] null_);
113 
114     /**
115      * @return the earliest error code from the thread's error queue without modifying it.
116      */
117     public static native NativeLong ERR_peek_error();
118 
119     /**
120      * @return an OpenSSL AES EVP cipher instance with a 128-bit key CBC mode
121      */
122     public static native PointerByReference EVP_aes_128_cbc();
123 
124     /**
125      * @return an OpenSSL AES EVP cipher instance with a 128-bit key CTR mode
126      */
127     public static native PointerByReference EVP_aes_128_ctr();
128 
129     /**
130      * @return an OpenSSL AES EVP cipher instance with a 192-bit key CBC mode
131      */
132     public static native PointerByReference EVP_aes_192_cbc();
133 
134     /**
135      * @return an OpenSSL AES EVP cipher instance with a 192-bit key CTR mode
136      */
137     public static native PointerByReference EVP_aes_192_ctr();
138 
139     /**
140      * @return an OpenSSL AES EVP cipher instance with a 256-bit key CBC mode
141      */
142     public static native PointerByReference EVP_aes_256_cbc();
143 
144     /**
145      * @return an OpenSSL AES EVP cipher instance with a 256-bit key CTR mode
146      */
147     public static native PointerByReference EVP_aes_256_ctr();
148 
149     /**
150      * Clears all information from a cipher context and free up any allocated memory associate with
151      * it, including ctx itself.
152      *
153      * @param c
154      *            openssl evp cipher
155      */
156     public static native void EVP_CIPHER_CTX_free(PointerByReference c);
157 
158     /**
159      * Creates a cipher context.
160      *
161      * @return a pointer to a newly created EVP_CIPHER_CTX for success and NULL for failure.
162      */
163     public static native PointerByReference EVP_CIPHER_CTX_new();
164 
165     /**
166      * Clears all information from a cipher context and free up any allocated * memory associate
167      * with it.
168      *
169      * @param c
170      *            openssl evp cipher
171      */
172 
173     /**
174      * Enables or disables padding
175      *
176      * @param c
177      *            cipher context
178      * @param pad
179      *            If the pad parameter is zero then no padding is performed
180      * @return always returns 1
181      */
182     public static native int EVP_CIPHER_CTX_set_padding(PointerByReference c, int pad);
183 
184     /**
185      * Finishes a multiple-part operation.
186      *
187      * @param ctx
188      *            cipher context
189      * @param bout
190      *            output byte buffer
191      * @param outl
192      *            output length
193      * @return 1 for success and 0 for failure.
194      */
195     public static native int EVP_CipherFinal_ex(PointerByReference ctx, ByteBuffer bout,
196             int[] outl);
197 
198     // ENGINE API: https://www.openssl.org/docs/man1.1.1/man3/ENGINE_add.html
199     // (The above page includes all the ENGINE functions used below)
200 
201     /**
202      * Init a cipher.
203      *
204      * @param ctx
205      *            cipher context
206      * @param cipher
207      *            evp cipher instance
208      * @param impl
209      *            engine
210      * @param key
211      *            key
212      * @param iv
213      *            iv
214      * @param enc
215      *            1 for encryption, 0 for decryption
216      * @return 1 for success and 0 for failure.
217      */
218     public static native int EVP_CipherInit_ex(PointerByReference ctx, PointerByReference cipher,
219             PointerByReference impl, byte[] key, byte[] iv, int enc);
220 
221     /**
222      * Continues a multiple-part encryption/decryption operation.
223      *
224      * @param ctx
225      *            cipher context
226      * @param bout
227      *            output byte buffer
228      * @param outl
229      *            output length
230      * @param in
231      *            input byte buffer
232      * @param inl
233      *            input length
234      * @return 1 for success and 0 for failure.
235      */
236     public static native int EVP_CipherUpdate(PointerByReference ctx, ByteBuffer bout, int[] outl,
237             ByteBuffer in, int inl);
238 
239     /**
240      * Retrieves version/build information about OpenSSL library.
241      *
242      * @see <a href="https://www.openssl.org/docs/man1.1.1/man3/OpenSSL_version.html">OpenSSL_version</a>
243      * @param type
244      *            type can be OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON...
245      * @return A pointer to a constant string describing the version of the OpenSSL library or
246      *         giving information about the library build.
247      */
248     public static native String OpenSSL_version(int type);
249 
250     /**
251      * Generates random data
252      *
253      * @param buf
254      *            the bytes for generated random.
255      * @param num
256      *            buffer length
257      * @return 1 on success, 0 otherwise.
258      */
259     public static native int RAND_bytes(ByteBuffer buf, int num);
260 
261     // Random generator
262     /**
263      * OpenSSL uses for random number generation
264      *
265      * @return pointers to the respective methods
266      */
267     public static native PointerByReference RAND_get_rand_method();
268 
269     // ================== instance interface methods ==================
270 
271     @Override
272     public PointerByReference _ENGINE_by_id(final String string) {
273         return ENGINE_by_id(string);
274     }
275 
276     @Override
277     public int _ENGINE_cleanup() {
278         return 0; // Not available
279     }
280 
281     @Override
282     public int _ENGINE_finish(final PointerByReference rdrandEngine) {
283         return ENGINE_finish(rdrandEngine);
284     }
285 
286     @Override
287     public int _ENGINE_free(final PointerByReference rdrandEngine) {
288         return ENGINE_free(rdrandEngine);
289     }
290 
291     @Override
292     public int _ENGINE_init(final PointerByReference rdrandEngine) {
293         return ENGINE_init(rdrandEngine);
294     }
295 
296     @Override
297     public void _ENGINE_load_rdrand() {
298         // Not available
299     }
300 
301     @Override
302     public int _ENGINE_set_default(final PointerByReference rdrandEngine, final int flags) {
303         return ENGINE_set_default(rdrandEngine, flags);
304     }
305 
306     @Override
307     public String _ERR_error_string(final NativeLong err, final char[] buff) {
308         return ERR_error_string(err, buff);
309     }
310 
311     @Override
312     public NativeLong _ERR_peek_error() {
313         return ERR_peek_error();
314     }
315 
316     @Override
317     public PointerByReference _EVP_aes_128_cbc() {
318         return EVP_aes_128_cbc();
319     }
320 
321     @Override
322     public PointerByReference _EVP_aes_128_ctr() {
323         return EVP_aes_128_ctr();
324     }
325 
326     @Override
327     public PointerByReference _EVP_aes_192_cbc() {
328         return EVP_aes_192_cbc();
329     }
330 
331     @Override
332     public PointerByReference _EVP_aes_192_ctr() {
333         return EVP_aes_192_ctr();
334     }
335 
336     @Override
337     public PointerByReference _EVP_aes_256_cbc() {
338         return EVP_aes_256_cbc();
339     }
340 
341     @Override
342     public PointerByReference _EVP_aes_256_ctr() {
343         return EVP_aes_256_ctr();
344     }
345 
346     @Override
347     public void _EVP_CIPHER_CTX_cleanup(final PointerByReference context) {
348         // Not available
349     }
350 
351     @Override
352     public void _EVP_CIPHER_CTX_free(final PointerByReference context) {
353         EVP_CIPHER_CTX_free(context);
354     }
355 
356     @Override
357     public PointerByReference _EVP_CIPHER_CTX_new() {
358         return EVP_CIPHER_CTX_new();
359     }
360 
361     @Override
362     public int _EVP_CIPHER_CTX_set_padding(final PointerByReference context, final int padding) {
363         return EVP_CIPHER_CTX_set_padding(context, padding);
364     }
365 
366     @Override
367     public int _EVP_CipherFinal_ex(final PointerByReference context, final ByteBuffer outBuffer, final int[] outlen) {
368         return EVP_CipherFinal_ex(context, outBuffer, outlen);
369     }
370 
371     @Override
372     public int _EVP_CipherInit_ex(final PointerByReference context, final PointerByReference algo, final PointerByReference impl, final byte[] encoded,
373             final byte[] iv, final int cipherMode) {
374         return EVP_CipherInit_ex(context, algo, impl, encoded, iv, cipherMode);
375     }
376 
377     @Override
378     public int _EVP_CipherUpdate(final PointerByReference context, final ByteBuffer outBuffer, final int[] outlen, final ByteBuffer inBuffer,
379             final int remaining) {
380         return EVP_CipherUpdate(context, outBuffer, outlen, inBuffer, remaining);
381     }
382 
383     @Override
384     public Throwable _INIT_ERROR() {
385         return INIT_ERROR;
386     }
387 
388     @Override
389     public boolean _INIT_OK() {
390         return INIT_OK;
391     }
392 
393     @Override
394     public String _OpenSSL_version(final int i) {
395         return OpenSSL_version(i);
396     }
397 
398     @Override
399     public int _RAND_bytes(final ByteBuffer buf, final int length) {
400         return RAND_bytes(buf, length) ;
401     }
402 
403     @Override
404     public PointerByReference _RAND_get_rand_method() {
405         return RAND_get_rand_method();
406     }
407 
408     @Override
409     public PointerByReference _RAND_SSLeay() {
410         return null; // Not available
411     }
412 
413 }